* Re: [PATCH] dt-bindings: pinctrl: mediatek: mt7622: add "gpio-ranges" property
From: Krzysztof Kozlowski @ 2024-04-08 11:25 UTC (permalink / raw)
To: Rafał Miłecki, Sean Wang, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: Matthias Brugger, AngeloGioacchino Del Regno, Hsin-Yi Wang,
linux-mediatek, linux-gpio, devicetree, linux-arm-kernel,
Rafał Miłecki
In-Reply-To: <20240408105128.30586-1-zajec5@gmail.com>
On 08/04/2024 12:51, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
>
> Allow specifying pin to GPIO mapping. It can be find in in-Linux DTS
> file for MT7622.
>
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH] arm64: dts: imx8mp-msc-sm2s: Add i2c{1,6} sda-/scl-gpios
From: Fabio Estevam @ 2024-04-08 11:31 UTC (permalink / raw)
To: Ian Ray
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, devicetree, imx,
linux-arm-kernel, linux-kernel
In-Reply-To: <20240408092449.6-1-ian.ray@gehealthcare.com>
Hi Ian,
> + pinctrl_i2c1_gpio: i2c1gpiogrp {
> + fsl,pins =
> + <MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x400001c3>,
The Sion bit is unnecessary in the GPIO mode so you could pass 0x1c3 instead.
^ permalink raw reply
* Re: [PATCH] arm64: dts: imx8mp-msc-sm2s: Add i2c{1,6} sda-/scl-gpios
From: Ian Ray @ 2024-04-08 11:44 UTC (permalink / raw)
To: Fabio Estevam
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, devicetree, imx,
linux-arm-kernel, linux-kernel
In-Reply-To: <CAOMZO5B-vTRSfi=tNc_iZxnxYstL8JJOd_1rMf4ps9WHyfx0GQ@mail.gmail.com>
On Mon, Apr 08, 2024 at 08:31:53AM -0300, Fabio Estevam wrote:
>
> Hi Ian,
>
> > + pinctrl_i2c1_gpio: i2c1gpiogrp {
> > + fsl,pins =
> > + <MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x400001c3>,
>
> The Sion bit is unnecessary in the GPIO mode so you could pass 0x1c3 instead.
Thank you -- I will submit a V2.
Would 0x1c2 be more correct? From the IMX8MPRM.pdf, it seems that the
lowest bit is reserved. Example: 8.2.4.158 SW_PAD_CTL_PAD_GPIO1_IO05
SW PAD Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO05).
^ permalink raw reply
* Re: [PATCH] arm64: dts: imx8mp-msc-sm2s: Add i2c{1,6} sda-/scl-gpios
From: Fabio Estevam @ 2024-04-08 11:48 UTC (permalink / raw)
To: Ian Ray
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, devicetree, imx,
linux-arm-kernel, linux-kernel
In-Reply-To: <ZhPYkGLM_b5IEKs2@de2cfed78370>
On Mon, Apr 8, 2024 at 8:44 AM Ian Ray <ian.ray@gehealthcare.com> wrote:
> Thank you -- I will submit a V2.
>
> Would 0x1c2 be more correct? From the IMX8MPRM.pdf, it seems that the
> lowest bit is reserved. Example: 8.2.4.158 SW_PAD_CTL_PAD_GPIO1_IO05
> SW PAD Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO05).
Yes, good catch. It is better not to write to the reserved bit 0, so
0x1c2 is preferred.
^ permalink raw reply
* Re: [PATCH v3 2/2] media: i2c: Add GC05A2 image sensor driver
From: Zhi Mao (毛智) @ 2024-04-08 11:50 UTC (permalink / raw)
To: mchehab@kernel.org, sakari.ailus@linux.intel.com,
robh+dt@kernel.org, kieran.bingham@ideasonboard.com,
krzysztof.kozlowski+dt@linaro.org
Cc: heiko@sntech.de, gerald.loacker@wolfvision.net,
linux-kernel@vger.kernel.org, yunkec@chromium.org,
linux-mediatek@lists.infradead.org, dan.scally@ideasonboard.com,
linux-media@vger.kernel.org,
Shengnan Wang (王圣男), hdegoede@redhat.com,
linus.walleij@linaro.org, andy.shevchenko@gmail.com,
Yaya Chang (張雅清), bingbu.cao@intel.com,
jacopo.mondi@ideasonboard.com, jernej.skrabec@gmail.com,
devicetree@vger.kernel.org, conor+dt@kernel.org,
Project_Global_Chrome_Upstream_Group, 10572168@qq.com,
hverkuil-cisco@xs4all.nl, tomi.valkeinen@ideasonboard.com,
linux-arm-kernel@lists.infradead.org, matthias.bgg@gmail.com,
laurent.pinchart@ideasonboard.com,
angelogioacchino.delregno@collabora.com, macromorgan@hotmail.com
In-Reply-To: <171248091995.2374960.12981271990757968652@ping.linuxembedded.co.uk>
Hi Kieran,
Thanks for your review this patch.
It seems that there are some difficult for us(Mediatek) to explain
these register setting comments.
As these settings are released by GC sensor vendor, and we have not
detailed datasheet described them.
And even if send the letter to ask sensor vendor, I am afraid there may
be not a clear response.
Can we just focus on the driver code function and control flow part?
On Sun, 2024-04-07 at 10:08 +0100, Kieran Bingham wrote:
>
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
> Hello,
>
> Thanks for helping extending the kernels sensor driver support.
>
> My comments below can likely be taken with a pinch of salt, as they
> are
> mostly around the tabled register values ... but we have many drivers
> which are binary blobs of sensor register values and I think it would
> be
> far more beneficial to clean these up where possible...
>
> So the first question is ... Can we ?
>
>
>
> Quoting Zhi Mao (2024-04-03 04:38:25)
> > Add a V4L2 sub-device driver for Galaxycore GC05A2 image sensor.
> >
> > Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
> > ---
> > drivers/media/i2c/Kconfig | 10 +
> > drivers/media/i2c/Makefile | 1 +
> > drivers/media/i2c/gc05a2.c | 1383
> ++++++++++++++++++++++++++++++++++++
> > 3 files changed, 1394 insertions(+)
> > create mode 100644 drivers/media/i2c/gc05a2.c
> >
> > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > index 56f276b920ab..97993bf160f9 100644
> > --- a/drivers/media/i2c/Kconfig
> > +++ b/drivers/media/i2c/Kconfig
> > @@ -70,6 +70,16 @@ config VIDEO_GC0308
> > To compile this driver as a module, choose M here: the
> > module will be called gc0308.
> >
> > +config VIDEO_GC05A2
> > + tristate "GalaxyCore gc05a2 sensor support"
> > + select V4L2_CCI_I2C
> > + help
> > + This is a Video4Linux2 sensor driver for the GalaxyCore
> gc05a2
> > + camera.
> > +
> > + To compile this driver as a module, choose M here: the
> > + module will be called gc05a2.
> > +
> > config VIDEO_GC2145
> > select V4L2_CCI_I2C
> > tristate "GalaxyCore GC2145 sensor support"
> > diff --git a/drivers/media/i2c/Makefile
> b/drivers/media/i2c/Makefile
> > index dfbe6448b549..8ed6faf0f854 100644
> > --- a/drivers/media/i2c/Makefile
> > +++ b/drivers/media/i2c/Makefile
> > @@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
> > obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
> > obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
> > obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
> > +obj-$(CONFIG_VIDEO_GC05A2) += gc05a2.o
> > obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
> > obj-$(CONFIG_VIDEO_HI556) += hi556.o
> > obj-$(CONFIG_VIDEO_HI846) += hi846.o
> > diff --git a/drivers/media/i2c/gc05a2.c
> b/drivers/media/i2c/gc05a2.c
> > new file mode 100644
> > index 000000000000..461d33055a3b
> > --- /dev/null
> > +++ b/drivers/media/i2c/gc05a2.c
> > @@ -0,0 +1,1383 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Driver for GalaxyCore gc05a2 image sensor
> > + *
> > + * Copyright 2024 MediaTek
> > + *
> > + * Zhi Mao <zhi.mao@mediatek.com>
> > + */
> > +#include <linux/array_size.h>
> > +#include <linux/bits.h>
> > +#include <linux/clk.h>
> > +#include <linux/container_of.h>
> > +#include <linux/delay.h>
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/gpio/consumer.h>
> > +#include <linux/math64.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/property.h>
> > +#include <linux/regulator/consumer.h>
> > +#include <linux/types.h>
> > +#include <linux/units.h>
> > +
> > +#include <media/v4l2-cci.h>
> > +#include <media/v4l2-ctrls.h>
> > +#include <media/v4l2-event.h>
> > +#include <media/v4l2-fwnode.h>
> > +#include <media/v4l2-subdev.h>
> > +
> > +#define GC05A2_REG_TEST_PATTERN_EN CCI_REG8(0x008c)
> > +#define GC05A2_REG_TEST_PATTERN_IDX CCI_REG8(0x008d)
> > +#define GC05A2_TEST_PATTERN_EN 0x01
> > +
> > +#define GC05A2_STREAMING_REG CCI_REG8(0x0100)
> > +
> > +#define GC05A2_FLIP_REG CCI_REG8(0x0101)
> > +#define GC05A2_FLIP_H_MASK BIT(0)
> > +#define GC05A2_FLIP_V_MASK BIT(1)
> > +
> > +#define GC05A2_EXP_REG CCI_REG16(0x0202)
> > +#define GC05A2_EXP_MARGIN 16
> > +#define GC05A2_EXP_MIN 4
> > +#define GC05A2_EXP_STEP 1
> > +
> > +#define GC05A2_AGAIN_REG CCI_REG16(0x0204)
> > +#define GC05A2_AGAIN_MIN 1024
> > +#define GC05A2_AGAIN_MAX (1024 * 16)
> > +#define GC05A2_AGAIN_STEP 1
> > +
> > +#define GC05A2_FRAME_LENGTH_REG CCI_REG16(0x0340)
> > +#define GC05A2_VTS_MAX 0xffff
> > +
> > +#define GC05A2_REG_CHIP_ID CCI_REG16(0x03f0)
> > +#define GC05A2_CHIP_ID 0x05a2
> > +
> > +#define GC05A2_NATIVE_WIDTH 2592
> > +#define GC05A2_NATIVE_HEIGHT 1944
> > +
> > +#define GC05A2_DEFAULT_CLK_FREQ (24 * HZ_PER_MHZ)
> > +#define GC05A2_MBUS_CODE MEDIA_BUS_FMT_SGRBG10_1X10
> > +#define GC05A2_DATA_LANES 2
> > +#define GC05A2_RGB_DEPTH 10
> > +#define GC05A2_SLEEP_US (2 * USEC_PER_MSEC)
> > +
> > +static const char *const gc05a2_test_pattern_menu[] = {
> > + "No Pattern", "Fade_to_gray_Color Bar", "Color Bar",
> > + "PN9", "Horizental_gradient", "Checkboard
> Pattern",
> > + "Slant", "Resolution", "Solid Black",
> > + "Solid White",
> > +};
> > +
> > +static const s64 gc05a2_link_freq_menu_items[] = {
> > + (448 * HZ_PER_MHZ),
> > + (224 * HZ_PER_MHZ),
> > +};
> > +
> > +static const char *const gc05a2_supply_name[] = {
> > + "avdd",
> > + "dvdd",
> > + "dovdd",
> > +};
> > +
> > +struct gc05a2 {
> > + struct device *dev;
> > + struct v4l2_subdev sd;
> > + struct media_pad pad;
> > +
> > + struct clk *xclk;
> > + struct regulator_bulk_data
> supplies[ARRAY_SIZE(gc05a2_supply_name)];
> > + struct gpio_desc *reset_gpio;
> > +
> > + struct v4l2_ctrl_handler ctrls;
> > + struct v4l2_ctrl *pixel_rate;
> > + struct v4l2_ctrl *link_freq;
> > + struct v4l2_ctrl *exposure;
> > + struct v4l2_ctrl *vblank;
> > + struct v4l2_ctrl *hblank;
> > + struct v4l2_ctrl *hflip;
> > + struct v4l2_ctrl *vflip;
> > +
> > + struct regmap *regmap;
> > + unsigned long link_freq_bitmap;
> > +
> > + /* True if the device has been identified */
> > + bool identified;
> > + const struct gc05a2_mode *cur_mode;
> > +};
> > +
> > +struct gc05a2_reg_list {
> > + u32 num_of_regs;
> > + const struct cci_reg_sequence *regs;
> > +};
> > +
> > +static const struct cci_reg_sequence mode_2592x1944[] = {
> > + /* system */
> > + { CCI_REG8(0x0135), 0x01 },
> > +
> > + /* pre_setting */
> > + { CCI_REG8(0x0084), 0x21 },
> > + { CCI_REG8(0x0d05), 0xcc },
> > + { CCI_REG8(0x0218), 0x00 },
> > + { CCI_REG8(0x005e), 0x48 },
> > + { CCI_REG8(0x0d06), 0x01 },
> > + { CCI_REG8(0x0007), 0x16 },
> > + { CCI_REG8(0x0101), 0x00 },
> > +
> > + /* analog */
> > + { CCI_REG8(0x0342), 0x07 },
> > + { CCI_REG8(0x0343), 0x28 },
> > + { CCI_REG8(0x0220), 0x07 },
> > + { CCI_REG8(0x0221), 0xd0 },
> > + { CCI_REG8(0x0202), 0x07 },
> > + { CCI_REG8(0x0203), 0x32 },
> > + { CCI_REG8(0x0340), 0x07 },
> > + { CCI_REG8(0x0341), 0xf0 },
> > + { CCI_REG8(0x0219), 0x00 },
> > + { CCI_REG8(0x0346), 0x00 },
> > + { CCI_REG8(0x0347), 0x04 },
> > + { CCI_REG8(0x0d14), 0x00 },
> > + { CCI_REG8(0x0d13), 0x05 },
> > + { CCI_REG8(0x0d16), 0x05 },
> > + { CCI_REG8(0x0d15), 0x1d },
> > + { CCI_REG8(0x00c0), 0x0a },
> > + { CCI_REG8(0x00c1), 0x30 },
> > + { CCI_REG8(0x034a), 0x07 },
> > + { CCI_REG8(0x034b), 0xa8 },
> > + { CCI_REG8(0x0e0a), 0x00 },
> > + { CCI_REG8(0x0e0b), 0x00 },
> > + { CCI_REG8(0x0e0e), 0x03 },
> > + { CCI_REG8(0x0e0f), 0x00 },
> > + { CCI_REG8(0x0e06), 0x0a },
> > + { CCI_REG8(0x0e23), 0x15 },
> > + { CCI_REG8(0x0e24), 0x15 },
> > + { CCI_REG8(0x0e2a), 0x10 },
> > + { CCI_REG8(0x0e2b), 0x10 },
> > + { CCI_REG8(0x0e17), 0x49 },
> > + { CCI_REG8(0x0e1b), 0x1c },
> > + { CCI_REG8(0x0e3a), 0x36 },
> > + { CCI_REG8(0x0d11), 0x84 },
> > + { CCI_REG8(0x0e52), 0x14 },
> > + { CCI_REG8(0x000b), 0x10 },
> > + { CCI_REG8(0x0008), 0x08 },
> > + { CCI_REG8(0x0223), 0x17 },
> > + { CCI_REG8(0x0d27), 0x39 },
> > + { CCI_REG8(0x0d22), 0x00 },
> > + { CCI_REG8(0x03f6), 0x0d },
> > + { CCI_REG8(0x0d04), 0x07 },
> > + { CCI_REG8(0x03f3), 0x72 },
> > + { CCI_REG8(0x03f4), 0xb8 },
> > + { CCI_REG8(0x03f5), 0xbc },
> > + { CCI_REG8(0x0d02), 0x73 },
> > +
> > + /* auto load start */
> > + { CCI_REG8(0x00cb), 0x00 },
> > +
> > + /* OUT 2592*1944 */
> > + { CCI_REG8(0x0350), 0x01 },
> > + { CCI_REG8(0x0353), 0x00 },
> > + { CCI_REG8(0x0354), 0x08 },
>
> > + { CCI_REG8(0x034c), 0x0a },
> > + { CCI_REG8(0x034d), 0x20 },
>
> Should/Could this be
> { CCI_REG16(0x034c), 2592 }, /* Width */
>
>
> > + { CCI_REG8(0x021f), 0x14 },
> > +
> > + /* MIPI */
> > + { CCI_REG8(0x0107), 0x05 },
> > + { CCI_REG8(0x0117), 0x01 },
> > + { CCI_REG8(0x0d81), 0x00 },
> > + { CCI_REG8(0x0d84), 0x0c },
> > + { CCI_REG8(0x0d85), 0xa8 },
> > + { CCI_REG8(0x0d86), 0x06 },
> > + { CCI_REG8(0x0d87), 0x55 },
> > + { CCI_REG8(0x0db3), 0x06 },
> > + { CCI_REG8(0x0db4), 0x08 },
> > + { CCI_REG8(0x0db5), 0x1e },
> > + { CCI_REG8(0x0db6), 0x02 },
> > + { CCI_REG8(0x0db8), 0x12 },
> > + { CCI_REG8(0x0db9), 0x0a },
> > + { CCI_REG8(0x0d93), 0x06 },
> > + { CCI_REG8(0x0d94), 0x09 },
> > + { CCI_REG8(0x0d95), 0x0d },
> > + { CCI_REG8(0x0d99), 0x0b },
> > + { CCI_REG8(0x0084), 0x01 },
> > +
> > + /* OUT */
> > + { CCI_REG8(0x0110), 0x01 },
> > +};
> > +
> > +static const struct cci_reg_sequence mode_1280x720[] = {
> > + /* system */
> > + { CCI_REG8(0x0135), 0x05 },
>
> In 2592x1944 this is 0x01. Do you have a datasheet? Can you explain
> why
> they are different? Can you add register definitions that have names
> to
> make this more maintainable or extendable in the future?
>
> There's discussion in the recent series improving the IMX258 which
> makes
> me wonder if we should try harder to have sensor drivers with clearer
> definitions.
>
>
> > +
> > + /*pre_setting*/
>
> /* pre_setting */ ?
>
> > + { CCI_REG8(0x0084), 0x21 },
> > + { CCI_REG8(0x0d05), 0xcc },
> > + { CCI_REG8(0x0218), 0x80 },
> > + { CCI_REG8(0x005e), 0x49 },
> > + { CCI_REG8(0x0d06), 0x81 },
> > + { CCI_REG8(0x0007), 0x16 },
> > + { CCI_REG8(0x0101), 0x00 },
>
> In 2592x1944, only register 0x0218 differs. Why? What is that? Can it
> be
> broken out to a function that applies the correct configuration at
> startuup based on a parameter instead of duplicating this table set?
>
> > +
> > + /* analog */
> > + { CCI_REG8(0x0342), 0x07 },
> > + { CCI_REG8(0x0343), 0x10 },
> > + { CCI_REG8(0x0220), 0x07 },
> > + { CCI_REG8(0x0221), 0xd0 },
> > + { CCI_REG8(0x0202), 0x03 },
> > + { CCI_REG8(0x0203), 0x32 },
> > + { CCI_REG8(0x0340), 0x04 },
> > + { CCI_REG8(0x0341), 0x08 },
> > + { CCI_REG8(0x0219), 0x00 },
> > + { CCI_REG8(0x0346), 0x01 },
> > + { CCI_REG8(0x0347), 0x00 },
> > + { CCI_REG8(0x0d14), 0x00 },
> > + { CCI_REG8(0x0d13), 0x05 },
> > + { CCI_REG8(0x0d16), 0x05 },
> > + { CCI_REG8(0x0d15), 0x1d },
> > + { CCI_REG8(0x00c0), 0x0a },
> > + { CCI_REG8(0x00c1), 0x30 },
> > + { CCI_REG8(0x034a), 0x05 },
> > + { CCI_REG8(0x034b), 0xb0 },
> > + { CCI_REG8(0x0e0a), 0x00 },
> > + { CCI_REG8(0x0e0b), 0x00 },
> > + { CCI_REG8(0x0e0e), 0x03 },
> > + { CCI_REG8(0x0e0f), 0x00 },
> > + { CCI_REG8(0x0e06), 0x0a },
> > + { CCI_REG8(0x0e23), 0x15 },
> > + { CCI_REG8(0x0e24), 0x15 },
> > + { CCI_REG8(0x0e2a), 0x10 },
> > + { CCI_REG8(0x0e2b), 0x10 },
> > + { CCI_REG8(0x0e17), 0x49 },
> > + { CCI_REG8(0x0e1b), 0x1c },
> > + { CCI_REG8(0x0e3a), 0x36 },
> > + { CCI_REG8(0x0d11), 0x84 },
> > + { CCI_REG8(0x0e52), 0x14 },
> > + { CCI_REG8(0x000b), 0x0e },
> > + { CCI_REG8(0x0008), 0x03 },
> > + { CCI_REG8(0x0223), 0x16 },
> > + { CCI_REG8(0x0d27), 0x39 },
> > + { CCI_REG8(0x0d22), 0x00 },
> > + { CCI_REG8(0x03f6), 0x0d },
> > + { CCI_REG8(0x0d04), 0x07 },
> > + { CCI_REG8(0x03f3), 0x72 },
> > + { CCI_REG8(0x03f4), 0xb8 },
> > + { CCI_REG8(0x03f5), 0xbc },
> > + { CCI_REG8(0x0d02), 0x73 },
> > +
>
> Are any of those able to be broken out to named register to be more
> clear in their intent?
>
> > + /* auto load start */
> > + { CCI_REG8(0x00cb), 0xfc },
> > +
>
> Why is this auto load start so different to the other modes 'auto
> load
> start'? What do the bits refer to ?
>
> > + /* OUT 1280x720 */
> > + { CCI_REG8(0x0350), 0x01 },
> > + { CCI_REG8(0x0353), 0x00 },
> > + { CCI_REG8(0x0354), 0x0c },
>
> > + { CCI_REG8(0x034c), 0x05 },
> > + { CCI_REG8(0x034d), 0x00 },
>
> Should/Could this be
> { CCI_REG16(0x034c), 1280 },
>
> Are there any other register settings that would make more sense to
> be
> in decimal units that match their actual context?
>
>
> > + { CCI_REG8(0x021f), 0x14 },
>
> I don't see a setting for 720/0x2d0. Do these registers only set the
> width?
>
> > +
> > + /* MIPI */
> > + { CCI_REG8(0x0107), 0x05 },
> > + { CCI_REG8(0x0117), 0x01 },
> > + { CCI_REG8(0x0d81), 0x00 },
> > + { CCI_REG8(0x0d84), 0x06 },
> > + { CCI_REG8(0x0d85), 0x40 },
> > + { CCI_REG8(0x0d86), 0x03 },
> > + { CCI_REG8(0x0d87), 0x21 },
> > + { CCI_REG8(0x0db3), 0x03 },
> > + { CCI_REG8(0x0db4), 0x04 },
> > + { CCI_REG8(0x0db5), 0x0d },
> > + { CCI_REG8(0x0db6), 0x01 },
> > + { CCI_REG8(0x0db8), 0x04 },
> > + { CCI_REG8(0x0db9), 0x06 },
> > + { CCI_REG8(0x0d93), 0x03 },
> > + { CCI_REG8(0x0d94), 0x04 },
> > + { CCI_REG8(0x0d95), 0x05 },
> > + { CCI_REG8(0x0d99), 0x06 },
> > + { CCI_REG8(0x0084), 0x01 },
> > +
> > + /* OUT */
>
> Out where? What is out?
>
> > + { CCI_REG8(0x0110), 0x01 },
> > +};
> > +
> > +static const struct cci_reg_sequence mode_table_common[] = {
> > + { GC05A2_STREAMING_REG, 0x00 },
> > + /* system */
> > + { CCI_REG8(0x0315), 0xd4 },
> > + { CCI_REG8(0x0d06), 0x01 },
> > + { CCI_REG8(0x0a70), 0x80 },
> > + { CCI_REG8(0x031a), 0x00 },
> > + { CCI_REG8(0x0314), 0x00 },
> > + { CCI_REG8(0x0130), 0x08 },
> > + { CCI_REG8(0x0132), 0x01 },
> > + { CCI_REG8(0x0136), 0x38 },
> > + { CCI_REG8(0x0137), 0x03 },
> > + { CCI_REG8(0x0134), 0x5b },
> > + { CCI_REG8(0x031c), 0xe0 },
> > + { CCI_REG8(0x0d82), 0x14 },
> > + { CCI_REG8(0x0dd1), 0x56 },
> > +
> > + /* gate_mode */
> > + { CCI_REG8(0x0af4), 0x01 },
> > + { CCI_REG8(0x0002), 0x10 },
> > + { CCI_REG8(0x00c3), 0x34 },
> > +
> > + /* auto load start */
>
> The previous 'auto load start' referenced 0x00cb ?
>
> > + { CCI_REG8(0x00c4), 0x00 },
> > + { CCI_REG8(0x00c5), 0x01 },
> > + { CCI_REG8(0x0af6), 0x00 },
> > + { CCI_REG8(0x0ba0), 0x17 },
> > + { CCI_REG8(0x0ba1), 0x00 },
> > + { CCI_REG8(0x0ba2), 0x00 },
> > + { CCI_REG8(0x0ba3), 0x00 },
> > + { CCI_REG8(0x0ba4), 0x03 },
> > + { CCI_REG8(0x0ba5), 0x00 },
> > + { CCI_REG8(0x0ba6), 0x00 },
> > + { CCI_REG8(0x0ba7), 0x00 },
> > + { CCI_REG8(0x0ba8), 0x40 },
> > + { CCI_REG8(0x0ba9), 0x00 },
> > + { CCI_REG8(0x0baa), 0x00 },
> > + { CCI_REG8(0x0bab), 0x00 },
> > + { CCI_REG8(0x0bac), 0x40 },
> > + { CCI_REG8(0x0bad), 0x00 },
> > + { CCI_REG8(0x0bae), 0x00 },
> > + { CCI_REG8(0x0baf), 0x00 },
> > + { CCI_REG8(0x0bb0), 0x02 },
> > + { CCI_REG8(0x0bb1), 0x00 },
> > + { CCI_REG8(0x0bb2), 0x00 },
> > + { CCI_REG8(0x0bb3), 0x00 },
> > + { CCI_REG8(0x0bb8), 0x02 },
> > + { CCI_REG8(0x0bb9), 0x00 },
> > + { CCI_REG8(0x0bba), 0x00 },
> > + { CCI_REG8(0x0bbb), 0x00 },
> > + { CCI_REG8(0x0a70), 0x80 },
> > + { CCI_REG8(0x0a71), 0x00 },
> > + { CCI_REG8(0x0a72), 0x00 },
> > + { CCI_REG8(0x0a66), 0x00 },
> > + { CCI_REG8(0x0a67), 0x80 },
> > + { CCI_REG8(0x0a4d), 0x4e },
> > + { CCI_REG8(0x0a50), 0x00 },
> > + { CCI_REG8(0x0a4f), 0x0c },
> > + { CCI_REG8(0x0a66), 0x00 },
> > + { CCI_REG8(0x00ca), 0x00 },
> > + { CCI_REG8(0x00cc), 0x00 },
> > + { CCI_REG8(0x00cd), 0x00 },
> > + { CCI_REG8(0x0aa1), 0x00 },
> > + { CCI_REG8(0x0aa2), 0xe0 },
> > + { CCI_REG8(0x0aa3), 0x00 },
> > + { CCI_REG8(0x0aa4), 0x40 },
> > + { CCI_REG8(0x0a90), 0x03 },
> > + { CCI_REG8(0x0a91), 0x0e },
> > + { CCI_REG8(0x0a94), 0x80 },
> > +
> > + /* standby */
> > + { CCI_REG8(0x0af6), 0x20 },
> > + { CCI_REG8(0x0b00), 0x91 },
> > + { CCI_REG8(0x0b01), 0x17 },
> > + { CCI_REG8(0x0b02), 0x01 },
> > + { CCI_REG8(0x0b03), 0x00 },
> > + { CCI_REG8(0x0b04), 0x01 },
> > + { CCI_REG8(0x0b05), 0x17 },
> > + { CCI_REG8(0x0b06), 0x01 },
> > + { CCI_REG8(0x0b07), 0x00 },
> > + { CCI_REG8(0x0ae9), 0x01 },
> > + { CCI_REG8(0x0aea), 0x02 },
> > + { CCI_REG8(0x0ae8), 0x53 },
> > + { CCI_REG8(0x0ae8), 0x43 },
> > +
> > + /* gain_partition */
> > + { CCI_REG8(0x0af6), 0x30 },
> > + { CCI_REG8(0x0b00), 0x08 },
> > + { CCI_REG8(0x0b01), 0x0f },
> > + { CCI_REG8(0x0b02), 0x00 },
> > + { CCI_REG8(0x0b04), 0x1c },
> > + { CCI_REG8(0x0b05), 0x24 },
> > + { CCI_REG8(0x0b06), 0x00 },
> > + { CCI_REG8(0x0b08), 0x30 },
> > + { CCI_REG8(0x0b09), 0x40 },
> > + { CCI_REG8(0x0b0a), 0x00 },
> > + { CCI_REG8(0x0b0c), 0x0e },
> > + { CCI_REG8(0x0b0d), 0x2a },
> > + { CCI_REG8(0x0b0e), 0x00 },
> > + { CCI_REG8(0x0b10), 0x0e },
> > + { CCI_REG8(0x0b11), 0x2b },
> > + { CCI_REG8(0x0b12), 0x00 },
> > + { CCI_REG8(0x0b14), 0x0e },
> > + { CCI_REG8(0x0b15), 0x23 },
> > + { CCI_REG8(0x0b16), 0x00 },
> > + { CCI_REG8(0x0b18), 0x0e },
> > + { CCI_REG8(0x0b19), 0x24 },
> > + { CCI_REG8(0x0b1a), 0x00 },
> > + { CCI_REG8(0x0b1c), 0x0c },
> > + { CCI_REG8(0x0b1d), 0x0c },
> > + { CCI_REG8(0x0b1e), 0x00 },
> > + { CCI_REG8(0x0b20), 0x03 },
> > + { CCI_REG8(0x0b21), 0x03 },
> > + { CCI_REG8(0x0b22), 0x00 },
> > + { CCI_REG8(0x0b24), 0x0e },
> > + { CCI_REG8(0x0b25), 0x0e },
> > + { CCI_REG8(0x0b26), 0x00 },
> > + { CCI_REG8(0x0b28), 0x03 },
> > + { CCI_REG8(0x0b29), 0x03 },
> > + { CCI_REG8(0x0b2a), 0x00 },
> > + { CCI_REG8(0x0b2c), 0x12 },
> > + { CCI_REG8(0x0b2d), 0x12 },
> > + { CCI_REG8(0x0b2e), 0x00 },
> > + { CCI_REG8(0x0b30), 0x08 },
> > + { CCI_REG8(0x0b31), 0x08 },
> > + { CCI_REG8(0x0b32), 0x00 },
> > + { CCI_REG8(0x0b34), 0x14 },
> > + { CCI_REG8(0x0b35), 0x14 },
> > + { CCI_REG8(0x0b36), 0x00 },
> > + { CCI_REG8(0x0b38), 0x10 },
> > + { CCI_REG8(0x0b39), 0x10 },
> > + { CCI_REG8(0x0b3a), 0x00 },
> > + { CCI_REG8(0x0b3c), 0x16 },
> > + { CCI_REG8(0x0b3d), 0x16 },
> > + { CCI_REG8(0x0b3e), 0x00 },
> > + { CCI_REG8(0x0b40), 0x10 },
> > + { CCI_REG8(0x0b41), 0x10 },
> > + { CCI_REG8(0x0b42), 0x00 },
> > + { CCI_REG8(0x0b44), 0x19 },
> > + { CCI_REG8(0x0b45), 0x19 },
> > + { CCI_REG8(0x0b46), 0x00 },
> > + { CCI_REG8(0x0b48), 0x16 },
> > + { CCI_REG8(0x0b49), 0x16 },
> > + { CCI_REG8(0x0b4a), 0x00 },
> > + { CCI_REG8(0x0b4c), 0x19 },
> > + { CCI_REG8(0x0b4d), 0x19 },
> > + { CCI_REG8(0x0b4e), 0x00 },
> > + { CCI_REG8(0x0b50), 0x16 },
> > + { CCI_REG8(0x0b51), 0x16 },
> > + { CCI_REG8(0x0b52), 0x00 },
> > + { CCI_REG8(0x0b80), 0x01 },
> > + { CCI_REG8(0x0b81), 0x00 },
> > + { CCI_REG8(0x0b82), 0x00 },
> > + { CCI_REG8(0x0b84), 0x00 },
> > + { CCI_REG8(0x0b85), 0x00 },
> > + { CCI_REG8(0x0b86), 0x00 },
> > + { CCI_REG8(0x0b88), 0x01 },
> > + { CCI_REG8(0x0b89), 0x6a },
> > + { CCI_REG8(0x0b8a), 0x00 },
> > + { CCI_REG8(0x0b8c), 0x00 },
> > + { CCI_REG8(0x0b8d), 0x01 },
> > + { CCI_REG8(0x0b8e), 0x00 },
> > + { CCI_REG8(0x0b90), 0x01 },
> > + { CCI_REG8(0x0b91), 0xf6 },
> > + { CCI_REG8(0x0b92), 0x00 },
> > + { CCI_REG8(0x0b94), 0x00 },
> > + { CCI_REG8(0x0b95), 0x02 },
> > + { CCI_REG8(0x0b96), 0x00 },
> > + { CCI_REG8(0x0b98), 0x02 },
> > + { CCI_REG8(0x0b99), 0xc4 },
> > + { CCI_REG8(0x0b9a), 0x00 },
> > + { CCI_REG8(0x0b9c), 0x00 },
> > + { CCI_REG8(0x0b9d), 0x03 },
> > + { CCI_REG8(0x0b9e), 0x00 },
> > + { CCI_REG8(0x0ba0), 0x03 },
> > + { CCI_REG8(0x0ba1), 0xd8 },
> > + { CCI_REG8(0x0ba2), 0x00 },
> > + { CCI_REG8(0x0ba4), 0x00 },
> > + { CCI_REG8(0x0ba5), 0x04 },
> > + { CCI_REG8(0x0ba6), 0x00 },
> > + { CCI_REG8(0x0ba8), 0x05 },
> > + { CCI_REG8(0x0ba9), 0x4d },
> > + { CCI_REG8(0x0baa), 0x00 },
> > + { CCI_REG8(0x0bac), 0x00 },
> > + { CCI_REG8(0x0bad), 0x05 },
> > + { CCI_REG8(0x0bae), 0x00 },
> > + { CCI_REG8(0x0bb0), 0x07 },
> > + { CCI_REG8(0x0bb1), 0x3e },
> > + { CCI_REG8(0x0bb2), 0x00 },
> > + { CCI_REG8(0x0bb4), 0x00 },
> > + { CCI_REG8(0x0bb5), 0x06 },
> > + { CCI_REG8(0x0bb6), 0x00 },
> > + { CCI_REG8(0x0bb8), 0x0a },
> > + { CCI_REG8(0x0bb9), 0x1a },
> > + { CCI_REG8(0x0bba), 0x00 },
> > + { CCI_REG8(0x0bbc), 0x09 },
> > + { CCI_REG8(0x0bbd), 0x36 },
> > + { CCI_REG8(0x0bbe), 0x00 },
> > + { CCI_REG8(0x0bc0), 0x0e },
> > + { CCI_REG8(0x0bc1), 0x66 },
> > + { CCI_REG8(0x0bc2), 0x00 },
> > + { CCI_REG8(0x0bc4), 0x10 },
> > + { CCI_REG8(0x0bc5), 0x06 },
> > + { CCI_REG8(0x0bc6), 0x00 },
> > + { CCI_REG8(0x02c1), 0xe0 },
> > + { CCI_REG8(0x0207), 0x04 },
> > + { CCI_REG8(0x02c2), 0x10 },
> > + { CCI_REG8(0x02c3), 0x74 },
> > + { CCI_REG8(0x02c5), 0x09 },
> > + { CCI_REG8(0x02c1), 0xe0 },
> > + { CCI_REG8(0x0207), 0x04 },
> > + { CCI_REG8(0x02c2), 0x10 },
> > + { CCI_REG8(0x02c5), 0x09 },
> > + { CCI_REG8(0x02c1), 0xe0 },
> > + { CCI_REG8(0x0207), 0x04 },
> > + { CCI_REG8(0x02c2), 0x10 },
> > + { CCI_REG8(0x02c5), 0x09 },
> > +
> > + /* auto load CH_GAIN */
> > + { CCI_REG8(0x0aa1), 0x15 },
> > + { CCI_REG8(0x0aa2), 0x50 },
> > + { CCI_REG8(0x0aa3), 0x00 },
> > + { CCI_REG8(0x0aa4), 0x09 },
> > + { CCI_REG8(0x0a90), 0x25 },
> > + { CCI_REG8(0x0a91), 0x0e },
> > + { CCI_REG8(0x0a94), 0x80 },
> > +
> > + /* ISP */
> > + { CCI_REG8(0x0050), 0x00 },
> > + { CCI_REG8(0x0089), 0x83 },
> > + { CCI_REG8(0x005a), 0x40 },
> > + { CCI_REG8(0x00c3), 0x35 },
> > + { CCI_REG8(0x00c4), 0x80 },
> > + { CCI_REG8(0x0080), 0x10 },
> > + { CCI_REG8(0x0040), 0x12 },
> > + { CCI_REG8(0x0053), 0x0a },
> > + { CCI_REG8(0x0054), 0x44 },
> > + { CCI_REG8(0x0055), 0x32 },
> > + { CCI_REG8(0x0058), 0x89 },
> > + { CCI_REG8(0x004a), 0x03 },
> > + { CCI_REG8(0x0048), 0xf0 },
> > + { CCI_REG8(0x0049), 0x0f },
> > + { CCI_REG8(0x0041), 0x20 },
> > + { CCI_REG8(0x0043), 0x0a },
> > + { CCI_REG8(0x009d), 0x08 },
> > + { CCI_REG8(0x0236), 0x40 },
> > +
> > + /* gain */
>
> Is the gain configurable? Is this analogue gain? digital gain? or
> colour
> balanace gains ?
>
>
> > + { CCI_REG8(0x0204), 0x04 },
> > + { CCI_REG8(0x0205), 0x00 },
> > + { CCI_REG8(0x02b3), 0x00 },
> > + { CCI_REG8(0x02b4), 0x00 },
> > + { CCI_REG8(0x009e), 0x01 },
> > + { CCI_REG8(0x009f), 0x94 },
> > +
> > + /* auto load REG */
> > + { CCI_REG8(0x0aa1), 0x10 },
> > + { CCI_REG8(0x0aa2), 0xf8 },
> > + { CCI_REG8(0x0aa3), 0x00 },
> > + { CCI_REG8(0x0aa4), 0x1f },
> > + { CCI_REG8(0x0a90), 0x11 },
> > + { CCI_REG8(0x0a91), 0x0e },
> > + { CCI_REG8(0x0a94), 0x80 },
> > + { CCI_REG8(0x03fe), 0x00 },
> > + { CCI_REG8(0x0a90), 0x00 },
> > + { CCI_REG8(0x0a70), 0x00 },
> > + { CCI_REG8(0x0a67), 0x00 },
> > + { CCI_REG8(0x0af4), 0x29 },
> > +
> > + /* DPHY */
> > + { CCI_REG8(0x0d80), 0x07 },
> > + { CCI_REG8(0x0dd3), 0x18 },
> > +
> > + /* CISCTL_Reset */
> > + { CCI_REG8(0x031c), 0x80 },
> > + { CCI_REG8(0x03fe), 0x30 },
> > + { CCI_REG8(0x0d17), 0x06 },
> > + { CCI_REG8(0x03fe), 0x00 },
> > + { CCI_REG8(0x0d17), 0x00 },
> > + { CCI_REG8(0x031c), 0x93 },
> > + { CCI_REG8(0x03fe), 0x00 },
> > + { CCI_REG8(0x031c), 0x80 },
> > + { CCI_REG8(0x03fe), 0x30 },
> > + { CCI_REG8(0x0d17), 0x06 },
> > + { CCI_REG8(0x03fe), 0x00 },
> > + { CCI_REG8(0x0d17), 0x00 },
> > + { CCI_REG8(0x031c), 0x93 },
> > +};
> > +
> > +struct gc05a2_mode {
> > + u32 width;
> > + u32 height;
> > + const struct gc05a2_reg_list reg_list;
> > +
> > + u32 hts; /* Horizontal timining size */
> > + u32 vts_def; /* Default vertical timining size */
> > + u32 vts_min; /* Min vertical timining size */
> > +};
> > +
> > +/* Declare modes in order, from biggest to smallest height. */
> > +static const struct gc05a2_mode gc05a2_modes[] = {
> > + {
> > + /* 2592*1944@30fps */
> > + .width = GC05A2_NATIVE_WIDTH,
> > + .height = GC05A2_NATIVE_HEIGHT,
> > + .reg_list = {
> > + .num_of_regs = ARRAY_SIZE(mode_2592x1944),
> > + .regs = mode_2592x1944,
> > + },
> > + .hts = 3664,
> > + .vts_def = 2032,
> > + .vts_min = 2032,
> > + },
> > + {
> > + /* 1280*720@60fps */
> > + .width = 1280,
> > + .height = 720,
> > + .reg_list = {
> > + .num_of_regs = ARRAY_SIZE(mode_1280x720),
> > + .regs = mode_1280x720,
> > + },
> > + .hts = 3616,
> > + .vts_def = 1032,
> > + .vts_min = 1032,
> > + },
> > +};
> > +
> > +static inline struct gc05a2 *to_gc05a2(struct v4l2_subdev *sd)
> > +{
> > + return container_of(sd, struct gc05a2, sd);
> > +}
> > +
> > +static int gc05a2_power_on(struct device *dev)
> > +{
> > + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > + struct gc05a2 *gc05a2 = to_gc05a2(sd);
> > + int ret;
> > +
> > + ret = regulator_bulk_enable(ARRAY_SIZE(gc05a2_supply_name),
> > + gc05a2->supplies);
> > + if (ret < 0) {
> > + dev_err(gc05a2->dev, "failed to enable regulators:
> %d\n", ret);
> > + return ret;
> > + }
> > +
> > + ret = clk_prepare_enable(gc05a2->xclk);
> > + if (ret < 0) {
> >
> + regulator_bulk_disable(ARRAY_SIZE(gc05a2_supply_name)
> ,
> > + gc05a2->supplies);
> > + dev_err(gc05a2->dev, "clk prepare enable
> failed\n");
> > + return ret;
> > + }
> > +
> > + fsleep(GC05A2_SLEEP_US);
> > +
> > + gpiod_set_value_cansleep(gc05a2->reset_gpio, 0);
> > + fsleep(GC05A2_SLEEP_US);
> > +
> > + return 0;
> > +}
> > +
> > +static int gc05a2_power_off(struct device *dev)
> > +{
> > + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> > + struct gc05a2 *gc05a2 = to_gc05a2(sd);
> > +
> > + clk_disable_unprepare(gc05a2->xclk);
> > + gpiod_set_value_cansleep(gc05a2->reset_gpio, 1);
> > + regulator_bulk_disable(ARRAY_SIZE(gc05a2_supply_name),
> > + gc05a2->supplies);
> > +
> > + return 0;
> > +}
> > +
> > +static int gc05a2_enum_mbus_code(struct v4l2_subdev *sd,
> > + struct v4l2_subdev_state
> *sd_state,
> > + struct v4l2_subdev_mbus_code_enum
> *code)
> > +{
> > + if (code->index > 0)
> > + return -EINVAL;
> > +
> > + code->code = GC05A2_MBUS_CODE;
> > +
> > + return 0;
> > +}
> > +
> > +static int gc05a2_enum_frame_size(struct v4l2_subdev *subdev,
> > + struct v4l2_subdev_state
> *sd_state,
> > + struct
> v4l2_subdev_frame_size_enum *fse)
> > +{
> > + if (fse->code != GC05A2_MBUS_CODE)
> > + return -EINVAL;
> > +
> > + if (fse->index >= ARRAY_SIZE(gc05a2_modes))
> > + return -EINVAL;
> > +
> > + fse->min_width = gc05a2_modes[fse->index].width;
> > + fse->max_width = gc05a2_modes[fse->index].width;
> > + fse->min_height = gc05a2_modes[fse->index].height;
> > + fse->max_height = gc05a2_modes[fse->index].height;
> > +
> > + return 0;
> > +}
> > +
> > +static int gc05a2_update_cur_mode_controls(struct gc05a2 *gc05a2,
> > + const struct gc05a2_mode
> *mode)
> > +{
> > + s64 exposure_max, h_blank;
> > + int ret;
> > +
> > + ret = __v4l2_ctrl_modify_range(gc05a2->vblank,
> > + mode->vts_min - mode-
> >height,
> > + GC05A2_VTS_MAX - mode-
> >height, 1,
> > + mode->vts_def - mode-
> >height);
> > + if (ret) {
> > + dev_err(gc05a2->dev, "VB ctrl range update
> failed\n");
> > + return ret;
> > + }
> > +
> > + h_blank = mode->hts - mode->width;
> > + ret = __v4l2_ctrl_modify_range(gc05a2->hblank, h_blank,
> h_blank, 1,
> > + h_blank);
> > + if (ret) {
> > + dev_err(gc05a2->dev, "HB ctrl range update
> failed\n");
> > + return ret;
> > + }
> > +
> > + exposure_max = mode->vts_def - GC05A2_EXP_MARGIN;
> > + ret = __v4l2_ctrl_modify_range(gc05a2->exposure,
> GC05A2_EXP_MIN,
> > + exposure_max,
> GC05A2_EXP_STEP,
> > + exposure_max);
> > + if (ret) {
> > + dev_err(gc05a2->dev, "exposure ctrl range update
> failed\n");
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static void gc05a2_update_pad_format(struct gc05a2 *gc08a3,
> > + const struct gc05a2_mode
> *mode,
> > + struct v4l2_mbus_framefmt
> *fmt)
> > +{
> > + fmt->width = mode->width;
> > + fmt->height = mode->height;
> > + fmt->code = GC05A2_MBUS_CODE;
> > + fmt->field = V4L2_FIELD_NONE;
> > + fmt->colorspace = V4L2_COLORSPACE_RAW;
> > + fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt-
> >colorspace);
> > + fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
> > + fmt->xfer_func = V4L2_XFER_FUNC_NONE;
> > +}
> > +
> > +static int gc05a2_set_format(struct v4l2_subdev *sd,
> > + struct v4l2_subdev_state *state,
> > + struct v4l2_subdev_format *fmt)
> > +{
> > + struct gc05a2 *gc05a2 = to_gc05a2(sd);
> > + struct v4l2_mbus_framefmt *mbus_fmt;
> > + struct v4l2_rect *crop;
> > + const struct gc05a2_mode *mode;
> > +
> > + mode = v4l2_find_nearest_size(gc05a2_modes,
> ARRAY_SIZE(gc05a2_modes),
> > + width, height, fmt-
> >format.width,
> > + fmt->format.height);
> > +
> > + /* update crop info to subdev state */
> > + crop = v4l2_subdev_state_get_crop(state, 0);
> > + crop->width = mode->width;
> > + crop->height = mode->height;
> > +
> > + /* update fmt info to subdev state */
> > + gc05a2_update_pad_format(gc05a2, mode, &fmt->format);
> > + mbus_fmt = v4l2_subdev_state_get_format(state, 0);
> > + *mbus_fmt = fmt->format;
> > +
> > + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
> > + return 0;
> > + gc05a2->cur_mode = mode;
> > + gc05a2_update_cur_mode_controls(gc05a2, mode);
> > +
> > + return 0;
> > +}
> > +
> > +static int gc05a2_get_selection(struct v4l2_subdev *sd,
> > + struct v4l2_subdev_state *state,
> > + struct v4l2_subdev_selection *sel)
> > +{
> > + switch (sel->target) {
> > + case V4L2_SEL_TGT_CROP_DEFAULT:
> > + case V4L2_SEL_TGT_CROP:
> > + sel->r = *v4l2_subdev_state_get_crop(state, 0);
> > + break;
> > + case V4L2_SEL_TGT_CROP_BOUNDS:
> > + sel->r.top = 0;
> > + sel->r.left = 0;
> > + sel->r.width = GC05A2_NATIVE_WIDTH;
> > + sel->r.height = GC05A2_NATIVE_HEIGHT;
> > + break;
> > + default:
> > + return -EINVAL;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int gc05a2_init_state(struct v4l2_subdev *sd,
> > + struct v4l2_subdev_state *state)
> > +{
> > + struct v4l2_subdev_format fmt = {
> > + .which = V4L2_SUBDEV_FORMAT_TRY,
> > + .pad = 0,
> > + .format = {
> > + .code = GC05A2_MBUS_CODE,
> > + .width = gc05a2_modes[0].width,
> > + .height = gc05a2_modes[0].height,
> > + },
> > + };
> > +
> > + gc05a2_set_format(sd, state, &fmt);
> > +
> > + return 0;
> > +}
> > +
> > +static int gc05a2_set_ctrl_hflip(struct gc05a2 *gc05a2, u32
> ctrl_val)
> > +{
> > + int ret;
> > + u64 val;
> > +
> > + ret = cci_read(gc05a2->regmap, GC05A2_FLIP_REG, &val,
> NULL);
> > + if (ret) {
> > + dev_err(gc05a2->dev, "read hflip register failed:
> %d\n", ret);
> > + return ret;
> > + }
> > +
> > + return cci_update_bits(gc05a2->regmap, GC05A2_FLIP_REG,
> > + GC05A2_FLIP_H_MASK,
> > + ctrl_val ? GC05A2_FLIP_H_MASK : 0,
> NULL);
> > +}
> > +
> > +static int gc05a2_set_ctrl_vflip(struct gc05a2 *gc05a2, u32
> ctrl_val)
> > +{
> > + int ret;
> > + u64 val;
> > +
> > + ret = cci_read(gc05a2->regmap, GC05A2_FLIP_REG, &val,
> NULL);
> > + if (ret) {
> > + dev_err(gc05a2->dev, "read vflip register failed:
> %d\n", ret);
> > + return ret;
> > + }
> > +
> > + return cci_update_bits(gc05a2->regmap, GC05A2_FLIP_REG,
> > + GC05A2_FLIP_V_MASK,
> > + ctrl_val ? GC05A2_FLIP_V_MASK : 0,
> NULL);
> > +}
> > +
> > +static int gc05a2_test_pattern(struct gc05a2 *gc05a2, u32
> pattern_menu)
> > +{
> > + u32 pattern;
> > + int ret;
> > +
> > + if (pattern_menu) {
> > + switch (pattern_menu) {
> > + case 1:
> > + case 2:
> > + case 3:
> > + case 4:
> > + case 5:
> > + case 6:
> > + case 7:
> > + pattern = pattern_menu << 4;
> > + break;
> > +
> > + case 8:
> > + pattern = 0;
> > + break;
> > +
> > + case 9:
> > + pattern = 4;
> > + break;
> > +
> > + default:
> > + pattern = 0x00;
> > + break;
> > + }
>
> This is fairly terse. Can we add comments, or definitions for the
> types
> or such so that the above is easier to interpret?
>
> > +
> > + ret = cci_write(gc05a2->regmap,
> GC05A2_REG_TEST_PATTERN_IDX,
> > + pattern, NULL);
> > + if (ret)
> > + return ret;
> > +
> > + return cci_write(gc05a2->regmap,
> GC05A2_REG_TEST_PATTERN_EN,
> > + GC05A2_TEST_PATTERN_EN, NULL);
> > + } else {
> > + return cci_write(gc05a2->regmap,
> GC05A2_REG_TEST_PATTERN_EN,
> > + 0x00, NULL);
> > + }
> > +}
> > +
> > +static int gc05a2_set_ctrl(struct v4l2_ctrl *ctrl)
> > +{
> > + struct gc05a2 *gc05a2 =
> > + container_of(ctrl->handler, struct gc05a2, ctrls);
> > + int ret = 0;
> > + s64 exposure_max;
> > + struct v4l2_subdev_state *state;
> > + const struct v4l2_mbus_framefmt *format;
> > +
> > + state = v4l2_subdev_get_locked_active_state(&gc05a2->sd);
> > + format = v4l2_subdev_state_get_format(state, 0);
> > +
> > + if (ctrl->id == V4L2_CID_VBLANK) {
> > + /* Update max exposure while meeting expected
> vblanking */
> > + exposure_max = format->height + ctrl->val -
> GC05A2_EXP_MARGIN;
> > + __v4l2_ctrl_modify_range(gc05a2->exposure,
> > + gc05a2->exposure->minimum,
> > + exposure_max, gc05a2-
> >exposure->step,
> > + exposure_max);
> > + }
> > +
> > + /*
> > + * Applying V4L2 control value only happens
> > + * when power is on for streaming.
> > + */
> > + if (!pm_runtime_get_if_active(gc05a2->dev))
> > + return 0;
> > +
> > + switch (ctrl->id) {
> > + case V4L2_CID_EXPOSURE:
> > + ret = cci_write(gc05a2->regmap, GC05A2_EXP_REG,
> > + ctrl->val, NULL);
> > + break;
> > +
> > + case V4L2_CID_ANALOGUE_GAIN:
> > + ret = cci_write(gc05a2->regmap, GC05A2_AGAIN_REG,
> > + ctrl->val, NULL);
> > + break;
> > +
> > + case V4L2_CID_VBLANK:
> > + ret = cci_write(gc05a2->regmap,
> GC05A2_FRAME_LENGTH_REG,
> > + gc05a2->cur_mode->height + ctrl-
> >val, NULL);
> > + break;
> > +
> > + case V4L2_CID_HFLIP:
> > + ret = gc05a2_set_ctrl_hflip(gc05a2, ctrl->val);
> > + break;
> > +
> > + case V4L2_CID_VFLIP:
> > + ret = gc05a2_set_ctrl_vflip(gc05a2, ctrl->val);
> > + break;
> > +
> > + case V4L2_CID_TEST_PATTERN:
> > + ret = gc05a2_test_pattern(gc05a2, ctrl->val);
> > + break;
> > +
> > + default:
> > + break;
> > + }
> > +
> > + pm_runtime_put(gc05a2->dev);
> > +
> > + return ret;
> > +}
> > +
> > +static const struct v4l2_ctrl_ops gc05a2_ctrl_ops = {
> > + .s_ctrl = gc05a2_set_ctrl,
> > +};
> > +
> > +static int gc05a2_identify_module(struct gc05a2 *gc05a2)
> > +{
> > + u64 val;
> > + int ret;
> > +
> > + if (gc05a2->identified)
> > + return 0;
> > +
> > + ret = cci_read(gc05a2->regmap, GC05A2_REG_CHIP_ID, &val,
> NULL);
> > + if (ret)
> > + return ret;
> > +
> > + if (val != GC05A2_CHIP_ID) {
> > + dev_err(gc05a2->dev, "chip id mismatch:
> 0x%x!=0x%llx",
> > + GC05A2_CHIP_ID, val);
> > + return -ENXIO;
> > + }
> > +
> > + gc05a2->identified = true;
> > +
> > + return 0;
> > +}
> > +
> > +static int gc05a2_start_streaming(struct gc05a2 *gc05a2)
> > +{
> > + const struct gc05a2_mode *mode;
> > + const struct gc05a2_reg_list *reg_list;
> > + int ret;
> > +
> > + ret = pm_runtime_resume_and_get(gc05a2->dev);
> > + if (ret < 0)
> > + return ret;
> > +
> > + ret = gc05a2_identify_module(gc05a2);
> > + if (ret)
> > + goto err_rpm_put;
> > +
> > + ret = cci_multi_reg_write(gc05a2->regmap,
> > + mode_table_common,
> > + ARRAY_SIZE(mode_table_common),
> NULL);
> > + if (ret)
> > + goto err_rpm_put;
> > +
> > + mode = gc05a2->cur_mode;
> > + reg_list = &mode->reg_list;
> > +
> > + ret = cci_multi_reg_write(gc05a2->regmap,
> > + reg_list->regs, reg_list-
> >num_of_regs, NULL);
> > + if (ret < 0)
> > + goto err_rpm_put;
> > +
> > + ret = __v4l2_ctrl_handler_setup(&gc05a2->ctrls);
> > + if (ret < 0) {
> > + dev_err(gc05a2->dev, "could not sync v4l2
> controls\n");
> > + goto err_rpm_put;
> > + }
> > +
> > + ret = cci_write(gc05a2->regmap, GC05A2_STREAMING_REG, 1,
> NULL);
> > + if (ret < 0) {
> > + dev_err(gc05a2->dev, "write STREAMING_REG failed:
> %d\n", ret);
> > + goto err_rpm_put;
> > + }
> > +
> > + return 0;
> > +
> > +err_rpm_put:
> > + pm_runtime_put(gc05a2->dev);
> > + return ret;
> > +}
> > +
> > +static int gc05a2_stop_streaming(struct gc05a2 *gc05a2)
> > +{
> > + int ret;
> > +
> > + ret = cci_write(gc05a2->regmap, GC05A2_STREAMING_REG, 0,
> NULL);
> > + if (ret < 0)
> > + dev_err(gc05a2->dev, "could not sent stop streaming
> %d\n", ret);
> > +
> > + pm_runtime_put(gc05a2->dev);
> > + return ret;
> > +}
> > +
> > +static int gc05a2_s_stream(struct v4l2_subdev *subdev, int enable)
> > +{
> > + struct gc05a2 *gc05a2 = to_gc05a2(subdev);
> > + struct v4l2_subdev_state *state;
> > + int ret;
> > +
> > + state = v4l2_subdev_lock_and_get_active_state(subdev);
> > +
> > + if (enable)
> > + ret = gc05a2_start_streaming(gc05a2);
> > + else
> > + ret = gc05a2_stop_streaming(gc05a2);
> > +
> > + v4l2_subdev_unlock_state(state);
> > +
> > + return ret;
> > +}
> > +
> > +static const struct v4l2_subdev_video_ops gc05a2_video_ops = {
> > + .s_stream = gc05a2_s_stream,
> > +};
> > +
> > +static const struct v4l2_subdev_pad_ops gc05a2_subdev_pad_ops = {
> > + .enum_mbus_code = gc05a2_enum_mbus_code,
> > + .enum_frame_size = gc05a2_enum_frame_size,
> > + .get_fmt = v4l2_subdev_get_fmt,
> > + .set_fmt = gc05a2_set_format,
> > + .get_selection = gc05a2_get_selection,
> > +};
> > +
> > +static const struct v4l2_subdev_core_ops gc05a2_core_ops = {
> > + .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> > + .unsubscribe_event = v4l2_event_subdev_unsubscribe,
> > +};
> > +
> > +static const struct v4l2_subdev_ops gc05a2_subdev_ops = {
> > + .core = &gc05a2_core_ops,
> > + .video = &gc05a2_video_ops,
> > + .pad = &gc05a2_subdev_pad_ops,
> > +};
> > +
> > +static const struct v4l2_subdev_internal_ops gc05a2_internal_ops =
> {
> > + .init_state = gc05a2_init_state,
> > +};
> > +
> > +static int gc05a2_get_regulators(struct device *dev, struct gc05a2
> *gc05a2)
> > +{
> > + unsigned int i;
> > +
> > + for (i = 0; i < ARRAY_SIZE(gc05a2_supply_name); i++)
> > + gc05a2->supplies[i].supply = gc05a2_supply_name[i];
> > +
> > + return devm_regulator_bulk_get(dev,
> ARRAY_SIZE(gc05a2_supply_name),
> > + gc05a2->supplies);
> > +}
> > +
> > +static int gc05a2_parse_fwnode(struct gc05a2 *gc05a2)
> > +{
> > + struct fwnode_handle *endpoint;
> > + struct v4l2_fwnode_endpoint bus_cfg = {
> > + .bus_type = V4L2_MBUS_CSI2_DPHY,
> > + };
> > + int ret;
> > + struct device *dev = gc05a2->dev;
> > +
> > + endpoint =
> > + fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0,
> 0,
> >
> + FWNODE_GRAPH_ENDPOINT
> _NEXT);
> > + if (!endpoint) {
> > + dev_err(dev, "endpoint node not found\n");
> > + return -EINVAL;
> > + }
> > +
> > + ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
> > + if (ret) {
> > + dev_err(dev, "parsing endpoint node failed\n");
> > + goto done;
> > + }
> > +
> > + ret = v4l2_link_freq_to_bitmap(dev,
> bus_cfg.link_frequencies,
> >
> + bus_cfg.nr_of_link_frequencies
> ,
> > + gc05a2_link_freq_menu_items,
> >
> + ARRAY_SIZE(gc05a2_link_freq_me
> nu_items),
> > + &gc05a2->link_freq_bitmap);
> > + if (ret)
> > + goto done;
> > +
> > +done:
> > + v4l2_fwnode_endpoint_free(&bus_cfg);
> > + fwnode_handle_put(endpoint);
> > + return ret;
> > +}
> > +
> > +static u64 gc05a2_to_pixel_rate(u32 f_index)
> > +{
> > + u64 pixel_rate =
> > + gc05a2_link_freq_menu_items[f_index] * 2 *
> GC05A2_DATA_LANES;
> > +
> > + return div_u64(pixel_rate, GC05A2_RGB_DEPTH);
> > +}
> > +
> > +static int gc05a2_init_controls(struct gc05a2 *gc05a2)
> > +{
> > + struct i2c_client *client = v4l2_get_subdevdata(&gc05a2-
> >sd);
> > + const struct gc05a2_mode *mode = &gc05a2_modes[0];
> > + const struct v4l2_ctrl_ops *ops = &gc05a2_ctrl_ops;
> > + struct v4l2_fwnode_device_properties props;
> > + struct v4l2_ctrl_handler *ctrl_hdlr;
> > + s64 exposure_max, h_blank;
> > + int ret;
> > +
> > + ctrl_hdlr = &gc05a2->ctrls;
> > + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9);
> > + if (ret)
> > + return ret;
> > +
> > + gc05a2->hflip = v4l2_ctrl_new_std(ctrl_hdlr,
> &gc05a2_ctrl_ops,
> > + V4L2_CID_HFLIP, 0, 1, 1,
> 0);
> > + gc05a2->vflip = v4l2_ctrl_new_std(ctrl_hdlr,
> &gc05a2_ctrl_ops,
> > + V4L2_CID_VFLIP, 0, 1, 1,
> 0);
> > + v4l2_ctrl_cluster(2, &gc05a2->hflip);
> > +
> > + gc05a2->link_freq =
> > + v4l2_ctrl_new_int_menu(ctrl_hdlr,
> > + &gc05a2_ctrl_ops,
> > + V4L2_CID_LINK_FREQ,
> >
> + ARRAY_SIZE(gc05a2_link_freq_menu_items
> ) - 1,
> > + 0,
> > + gc05a2_link_freq_menu_items);
> > + if (gc05a2->link_freq)
> > + gc05a2->link_freq->flags |=
> V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > + gc05a2->pixel_rate =
> > + v4l2_ctrl_new_std(ctrl_hdlr,
> > + &gc05a2_ctrl_ops,
> > + V4L2_CID_PIXEL_RATE, 0,
> > + gc05a2_to_pixel_rate(0),
> > + 1,
> > + gc05a2_to_pixel_rate(0));
> > +
> > + gc05a2->vblank =
> > + v4l2_ctrl_new_std(ctrl_hdlr,
> > + &gc05a2_ctrl_ops,
> V4L2_CID_VBLANK,
> > + mode->vts_min - mode->height,
> > + GC05A2_VTS_MAX - mode->height, 1,
> > + mode->vts_def - mode->height);
> > +
> > + h_blank = mode->hts - mode->width;
> > + gc05a2->hblank = v4l2_ctrl_new_std(ctrl_hdlr,
> &gc05a2_ctrl_ops,
> > + V4L2_CID_HBLANK,
> h_blank, h_blank, 1,
> > + h_blank);
> > + if (gc05a2->hblank)
> > + gc05a2->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > +
> > + v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
> > + V4L2_CID_ANALOGUE_GAIN, GC05A2_AGAIN_MIN,
> > + GC05A2_AGAIN_MAX, GC05A2_AGAIN_STEP,
> > + GC05A2_AGAIN_MIN);
> > +
> > + exposure_max = mode->vts_def - GC05A2_EXP_MARGIN;
> > + gc05a2->exposure = v4l2_ctrl_new_std(ctrl_hdlr,
> &gc05a2_ctrl_ops,
> > + V4L2_CID_EXPOSURE,
> GC05A2_EXP_MIN,
> > + exposure_max,
> GC05A2_EXP_STEP,
> > + exposure_max);
> > +
> > + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &gc05a2_ctrl_ops,
> > + V4L2_CID_TEST_PATTERN,
> >
> + ARRAY_SIZE(gc05a2_test_pattern_m
> enu) - 1,
> > + 0, 0,
> gc05a2_test_pattern_menu);
> > +
> > + /* register properties to fwnode (e.g. rotation,
> orientation) */
> > + ret = v4l2_fwnode_device_parse(&client->dev, &props);
> > + if (ret)
> > + goto error_ctrls;
> > +
> > + ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, ops,
> &props);
> > + if (ret)
> > + goto error_ctrls;
> > +
> > + if (ctrl_hdlr->error) {
> > + ret = ctrl_hdlr->error;
> > + goto error_ctrls;
> > + }
> > +
> > + gc05a2->sd.ctrl_handler = ctrl_hdlr;
> > +
> > + return 0;
> > +
> > +error_ctrls:
> > + v4l2_ctrl_handler_free(ctrl_hdlr);
> > +
> > + return ret;
> > +}
> > +
> > +static int gc05a2_probe(struct i2c_client *client)
> > +{
> > + struct device *dev = &client->dev;
> > + struct gc05a2 *gc05a2;
> > + int ret;
> > +
> > + gc05a2 = devm_kzalloc(dev, sizeof(*gc05a2), GFP_KERNEL);
> > + if (!gc05a2)
> > + return -ENOMEM;
> > +
> > + gc05a2->dev = dev;
> > +
> > + ret = gc05a2_parse_fwnode(gc05a2);
> > + if (ret)
> > + return ret;
> > +
> > + gc05a2->regmap = devm_cci_regmap_init_i2c(client, 16);
> > + if (IS_ERR(gc05a2->regmap))
> > + return dev_err_probe(dev, PTR_ERR(gc05a2->regmap),
> > + "failed to init CCI\n");
> > +
> > + gc05a2->xclk = devm_clk_get(dev, NULL);
> > + if (IS_ERR(gc05a2->xclk))
> > + return dev_err_probe(dev, PTR_ERR(gc05a2->xclk),
> > + "failed to get xclk\n");
> > +
> > + ret = clk_set_rate(gc05a2->xclk, GC05A2_DEFAULT_CLK_FREQ);
> > + if (ret)
> > + return dev_err_probe(dev, ret,
> > + "failed to set xclk
> frequency\n");
> > +
> > + ret = gc05a2_get_regulators(dev, gc05a2);
> > + if (ret < 0)
> > + return dev_err_probe(dev, ret,
> > + "failed to get regulators\n");
> > +
> > + gc05a2->reset_gpio = devm_gpiod_get(dev, "reset",
> GPIOD_OUT_LOW);
> > + if (IS_ERR(gc05a2->reset_gpio))
> > + return dev_err_probe(dev, PTR_ERR(gc05a2-
> >reset_gpio),
> > + "failed to get gpio\n");
> > +
> > + v4l2_i2c_subdev_init(&gc05a2->sd, client,
> &gc05a2_subdev_ops);
> > + gc05a2->sd.internal_ops = &gc05a2_internal_ops;
> > + gc05a2->cur_mode = &gc05a2_modes[0];
> > +
> > + ret = gc05a2_init_controls(gc05a2);
> > + if (ret)
> > + return dev_err_probe(dev, ret,
> > + "failed to init controls\n");
> > +
> > + gc05a2->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> > + V4L2_SUBDEV_FL_HAS_EVENTS;
> > + gc05a2->pad.flags = MEDIA_PAD_FL_SOURCE;
> > + gc05a2->sd.dev = &client->dev;
> > + gc05a2->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> > +
> > + ret = media_entity_pads_init(&gc05a2->sd.entity, 1,
> &gc05a2->pad);
> > + if (ret < 0) {
> > + dev_err(dev, "could not register media entity\n");
> > + goto err_v4l2_ctrl_handler_free;
> > + }
> > +
> > + gc05a2->sd.state_lock = gc05a2->ctrls.lock;
> > + ret = v4l2_subdev_init_finalize(&gc05a2->sd);
> > + if (ret < 0) {
> > + dev_err(dev, "v4l2 subdev init error: %d\n", ret);
> > + goto err_media_entity_cleanup;
> > + }
> > +
> > + pm_runtime_set_active(gc05a2->dev);
> > + pm_runtime_enable(gc05a2->dev);
> > + pm_runtime_set_autosuspend_delay(gc05a2->dev, 1000);
> > + pm_runtime_use_autosuspend(gc05a2->dev);
> > + pm_runtime_idle(gc05a2->dev);
> > +
> > + ret = v4l2_async_register_subdev_sensor(&gc05a2->sd);
> > + if (ret < 0) {
> > + dev_err(dev, "could not register v4l2 device\n");
> > + goto err_rpm;
> > + }
> > +
> > + return 0;
> > +
> > +err_rpm:
> > + pm_runtime_disable(gc05a2->dev);
> > + v4l2_subdev_cleanup(&gc05a2->sd);
> > +
> > +err_media_entity_cleanup:
> > + media_entity_cleanup(&gc05a2->sd.entity);
> > +
> > +err_v4l2_ctrl_handler_free:
> > + v4l2_ctrl_handler_free(&gc05a2->ctrls);
> > +
> > + return ret;
> > +}
> > +
> > +static void gc05a2_remove(struct i2c_client *client)
> > +{
> > + struct v4l2_subdev *sd = i2c_get_clientdata(client);
> > + struct gc05a2 *gc05a2 = to_gc05a2(sd);
> > +
> > + v4l2_async_unregister_subdev(&gc05a2->sd);
> > + v4l2_subdev_cleanup(sd);
> > + media_entity_cleanup(&gc05a2->sd.entity);
> > + v4l2_ctrl_handler_free(&gc05a2->ctrls);
> > +
> > + pm_runtime_disable(&client->dev);
> > + if (!pm_runtime_status_suspended(&client->dev))
> > + gc05a2_power_off(gc05a2->dev);
> > + pm_runtime_set_suspended(&client->dev);
> > +}
> > +
> > +static const struct of_device_id gc05a2_of_match[] = {
> > + { .compatible = "galaxycore,gc05a2" },
> > + {}
> > +};
> > +MODULE_DEVICE_TABLE(of, gc05a2_of_match);
> > +
> > +static DEFINE_RUNTIME_DEV_PM_OPS(gc05a2_pm_ops,
> > + gc05a2_power_off,
> > + gc05a2_power_on,
> > + NULL);
> > +
> > +static struct i2c_driver gc05a2_i2c_driver = {
> > + .driver = {
> > + .of_match_table = gc05a2_of_match,
> > + .pm = pm_ptr(&gc05a2_pm_ops),
> > + .name = "gc05a2",
> > + },
> > + .probe = gc05a2_probe,
> > + .remove = gc05a2_remove,
> > +};
> > +module_i2c_driver(gc05a2_i2c_driver);
> > +
> > +MODULE_DESCRIPTION("GalaxyCore gc05a2 Camera driver");
> > +MODULE_AUTHOR("Zhi Mao <zhi.mao@mediatek.com>");
> > +MODULE_LICENSE("GPL");
> > --
> > 2.25.1
> >
^ permalink raw reply
* Re: [PATCHv3 1/2] dt-bindings: usb: typec: anx7688: start a binding document
From: Ondřej Jirman @ 2024-04-08 11:51 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Pavel Machek, phone-devel, kernel list, fiona.klute, martijn,
samuel, heikki.krogerus, gregkh, linux-usb, robh+dt,
krzysztof.kozlowski+dt, devicetree
In-Reply-To: <ab9affc8-de68-4ec9-bdfc-02131191bc3a@linaro.org>
Hi Krzysztof,
On Mon, Apr 08, 2024 at 01:17:32PM GMT, Krzysztof Kozlowski wrote:
> On 08/04/2024 12:51, Pavel Machek wrote:
> > Add binding for anx7688 usb type-c bridge. I don't have a datasheet,
> > but I did best I could.
> >
> > Signed-off-by: Pavel Machek <pavel@ucw.cz>
>
> ...
>
> > + cabledet-gpios:
> > + maxItems: 1
> > + description: GPIO controlling CABLE_DET (C3) pin.
> > +
> > + avdd10-supply:
> > + description: 1.0V power supply going to AVDD10 (A4, ...) pins
> > +
> > + dvdd10-supply:
> > + description: 1.0V power supply going to DVDD10 (D6, ...) pins
> > +
> > + avdd18-supply:
> > + description: 1.8V power supply going to AVDD18 (E3, ...) pins
> > +
> > + dvdd18-supply:
> > + description: 1.8V power supply going to DVDD18 (G4, ...) pins
> > +
> > + avdd33-supply:
> > + description: 3.3V power supply going to AVDD33 (C4, ...) pins
> > +
> > + i2c-supply: true
> > + vconn-supply: true
>
> There are no such supplies like i2c and vconn on the schematics.
Which schematics?
ANX7688 has VCONN1/2_EN GPIOs that control a switching of VCONN power supply
to resective CCx pins. That's just a switch signal. Power for VCONN needs
to come from somewhere and the driver needs to enable the regulator at
the appropriate time only.
On Pinephone it can't be an always on power supply and needs to be enabled
only when used due to HW design of the circuit. (default without ANX driver
initialized would be to shove 5V to both CC pins, which breaks Type-C spec)
I2C supply is needed for I2C bus to work, apparently. There's nothing
that says that I2C pull-ups supply has to come from supplies powering the
chip. I2C I/O is open drain and the device needs to enable a bus supply
in order to communicate.
You can say that bus master should be managing the bus supply, but you'd still
have a problem that each device may be behind a voltage translator, and
logically, bus master driver should care only about its side of the bus then.
Both side of level shifter need the pull-up power enabled.
You can also make an argument that bus supply can be always on, but that
causes several other issues on Pinephone due to shared nature of most
resources like these. There are other devices on shared power rails, that
need to be turned off during sleep, etc.
Kind regards,
o.
> I think this represents some other part of component which was added
> here only for convenience.
>
>
>
> Best regards,
> Krzysztof
>
^ permalink raw reply
* Re: [PATCHv3 1/2] dt-bindings: usb: typec: anx7688: start a binding document
From: Ondřej Jirman @ 2024-04-08 11:52 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Pavel Machek, phone-devel, kernel list, fiona.klute, martijn,
samuel, heikki.krogerus, gregkh, linux-usb, robh+dt,
krzysztof.kozlowski+dt, devicetree
In-Reply-To: <e7841ad2-fa3d-442d-804d-51f12e05c234@linaro.org>
On Mon, Apr 08, 2024 at 01:24:03PM GMT, Krzysztof Kozlowski wrote:
> On 08/04/2024 13:21, Pavel Machek wrote:
> > Hi!
> >
> >>> Add binding for anx7688 usb type-c bridge. I don't have a datasheet,
> >>> but I did best I could.
> >>>
> >>> Signed-off-by: Pavel Machek <pavel@ucw.cz>
> >>
> >> ...
> >>
> >>> + cabledet-gpios:
> >>> + maxItems: 1
> >>> + description: GPIO controlling CABLE_DET (C3) pin.
> >>> +
> >>> + avdd10-supply:
> >>> + description: 1.0V power supply going to AVDD10 (A4, ...) pins
> >>> +
> >>> + dvdd10-supply:
> >>> + description: 1.0V power supply going to DVDD10 (D6, ...) pins
> >>> +
> >>> + avdd18-supply:
> >>> + description: 1.8V power supply going to AVDD18 (E3, ...) pins
> >>> +
> >>> + dvdd18-supply:
> >>> + description: 1.8V power supply going to DVDD18 (G4, ...) pins
> >>> +
> >>> + avdd33-supply:
> >>> + description: 3.3V power supply going to AVDD33 (C4, ...) pins
> >>> +
> >>> + i2c-supply: true
> >>> + vconn-supply: true
> >>
> >> There are no such supplies like i2c and vconn on the schematics.
> >>
> >> I think this represents some other part of component which was added
> >> here only for convenience.
> >
> > Can you give me pointer to documentation you are looking at?
>
> The schematics you linked in the document at the beginning. Page 13. Do
> you see these pins there? I saw only VCONN1_EN, but that's not a supply.
The supply is U1308.
regards,
o.
> Best regards,
> Krzysztof
>
^ permalink raw reply
* Re: [PATCH] dt-bindings: extcon: ptn5150: Document the 'port' node
From: Fabio Estevam @ 2024-04-08 11:58 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: cw00.choi, myungjoo.ham, robh, conor+dt, devicetree, marex,
Fabio Estevam
In-Reply-To: <c6edf937-dd58-44f7-b620-09dd452f6921@kernel.org>
On Sat, Apr 6, 2024 at 8:26 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
> > Would it be OK if I send a v2 without the USB C connector description
> > and address your other comments?
>
> No, because I think this should be the connector. Look at datasheet of
> ptn5150 and ptn5110. Aren't both describing similar hardware?
>
> Instead adding some sort of hacked-hardware-representation, please
> investigate why your previous commit broke things.
Yes, you are right.
I don't have access to any board with a PTN5150, so I can't debug it myself.
^ permalink raw reply
* Re: [PATCHv3 1/2] dt-bindings: usb: typec: anx7688: start a binding document
From: Krzysztof Kozlowski @ 2024-04-08 11:59 UTC (permalink / raw)
To: Ondřej Jirman, Pavel Machek, phone-devel, kernel list,
fiona.klute, martijn, samuel, heikki.krogerus, gregkh, linux-usb,
robh+dt, krzysztof.kozlowski+dt, devicetree
In-Reply-To: <e6vvuttix5k5fioy7q44ick5wj6u5gleh7mht36s4zjjcym7vy@bziejyohtc4b>
On 08/04/2024 13:52, Ondřej Jirman wrote:
> On Mon, Apr 08, 2024 at 01:24:03PM GMT, Krzysztof Kozlowski wrote:
>> On 08/04/2024 13:21, Pavel Machek wrote:
>>> Hi!
>>>
>>>>> Add binding for anx7688 usb type-c bridge. I don't have a datasheet,
>>>>> but I did best I could.
>>>>>
>>>>> Signed-off-by: Pavel Machek <pavel@ucw.cz>
>>>>
>>>> ...
>>>>
>>>>> + cabledet-gpios:
>>>>> + maxItems: 1
>>>>> + description: GPIO controlling CABLE_DET (C3) pin.
>>>>> +
>>>>> + avdd10-supply:
>>>>> + description: 1.0V power supply going to AVDD10 (A4, ...) pins
>>>>> +
>>>>> + dvdd10-supply:
>>>>> + description: 1.0V power supply going to DVDD10 (D6, ...) pins
>>>>> +
>>>>> + avdd18-supply:
>>>>> + description: 1.8V power supply going to AVDD18 (E3, ...) pins
>>>>> +
>>>>> + dvdd18-supply:
>>>>> + description: 1.8V power supply going to DVDD18 (G4, ...) pins
>>>>> +
>>>>> + avdd33-supply:
>>>>> + description: 3.3V power supply going to AVDD33 (C4, ...) pins
>>>>> +
>>>>> + i2c-supply: true
>>>>> + vconn-supply: true
>>>>
>>>> There are no such supplies like i2c and vconn on the schematics.
>>>>
>>>> I think this represents some other part of component which was added
>>>> here only for convenience.
>>>
>>> Can you give me pointer to documentation you are looking at?
>>
>> The schematics you linked in the document at the beginning. Page 13. Do
>> you see these pins there? I saw only VCONN1_EN, but that's not a supply.
>
> The supply is U1308.
That's not a supply to anx7688.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCHv3 1/2] dt-bindings: usb: typec: anx7688: start a binding document
From: Krzysztof Kozlowski @ 2024-04-08 12:01 UTC (permalink / raw)
To: Ondřej Jirman, Pavel Machek, phone-devel, kernel list,
fiona.klute, martijn, samuel, heikki.krogerus, gregkh, linux-usb,
robh+dt, krzysztof.kozlowski+dt, devicetree
In-Reply-To: <35tqaktf533qtpaquvzb7p5juupjyakktstlqgr2hqretnt7lv@chubnabkyqjz>
On 08/04/2024 13:51, Ondřej Jirman wrote:
> Hi Krzysztof,
>
> On Mon, Apr 08, 2024 at 01:17:32PM GMT, Krzysztof Kozlowski wrote:
>> On 08/04/2024 12:51, Pavel Machek wrote:
>>> Add binding for anx7688 usb type-c bridge. I don't have a datasheet,
>>> but I did best I could.
>>>
>>> Signed-off-by: Pavel Machek <pavel@ucw.cz>
>>
>> ...
>>
>>> + cabledet-gpios:
>>> + maxItems: 1
>>> + description: GPIO controlling CABLE_DET (C3) pin.
>>> +
>>> + avdd10-supply:
>>> + description: 1.0V power supply going to AVDD10 (A4, ...) pins
>>> +
>>> + dvdd10-supply:
>>> + description: 1.0V power supply going to DVDD10 (D6, ...) pins
>>> +
>>> + avdd18-supply:
>>> + description: 1.8V power supply going to AVDD18 (E3, ...) pins
>>> +
>>> + dvdd18-supply:
>>> + description: 1.8V power supply going to DVDD18 (G4, ...) pins
>>> +
>>> + avdd33-supply:
>>> + description: 3.3V power supply going to AVDD33 (C4, ...) pins
>>> +
>>> + i2c-supply: true
>>> + vconn-supply: true
>>
>> There are no such supplies like i2c and vconn on the schematics.
>
> Which schematics?
>
> ANX7688 has VCONN1/2_EN GPIOs that control a switching of VCONN power supply
> to resective CCx pins. That's just a switch signal. Power for VCONN needs
> to come from somewhere and the driver needs to enable the regulator at
> the appropriate time only.
>
> On Pinephone it can't be an always on power supply and needs to be enabled
> only when used due to HW design of the circuit. (default without ANX driver
> initialized would be to shove 5V to both CC pins, which breaks Type-C spec)
>
> I2C supply is needed for I2C bus to work, apparently. There's nothing
> that says that I2C pull-ups supply has to come from supplies powering the
> chip. I2C I/O is open drain and the device needs to enable a bus supply
> in order to communicate.
No, that's misunderstanding of DT. These are not supplies to anx7688.
Bus supply is not related to anx7688.
>
> You can say that bus master should be managing the bus supply, but you'd still
> have a problem that each device may be behind a voltage translator, and
> logically, bus master driver should care only about its side of the bus then.
> Both side of level shifter need the pull-up power enabled.
Again, that's nothing related to anx7688. If you want to add it here,
why not to every device everywhere?
>
> You can also make an argument that bus supply can be always on, but that
> causes several other issues on Pinephone due to shared nature of most
> resources like these. There are other devices on shared power rails, that
> need to be turned off during sleep, etc.
>
No, do not add non-existing properties on this device as workaround for
other issues.
Please drop these two supplies *and all other which do not exist* on
anx7688.
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v6 1/2] media: dt-bindings: nxp,imx8-jpeg: Add clocks entries
From: Mirela Rabulea @ 2024-04-08 12:06 UTC (permalink / raw)
To: shawnguo, robh+dt, krzysztof.kozlowski+dt, festevam, festevam,
alexander.stein, Frank.li, ming.qian
Cc: conor+dt, devicetree, linux-arm-kernel, s.hauer, kernel, mchehab,
hverkuil, linux-media, imx, linux-kernel
From: Fabio Estevam <festevam@denx.de>
The JPEG decoder/encoder present in iMX8QXP and iMX8QM SoCs need
the PER and IPG clocks to be functional, so add the clock entries.
This also fixes the following schema warning:
imx8qm-apalis-eval.dtb: jpegdec@58400000: 'assigned-clock-rates', 'assigned-clocks', 'clock-names', 'clocks' do not match any of the regexes: 'pinctrl-[0-9]+'
from schema $id: http://devicetree.org/schemas/media/nxp,imx8-jpeg.yaml#
Signed-off-by: Fabio Estevam <festevam@denx.de>
Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
---
Changes since v5:
- Remove one extra ":" from subject (thanks Fabio!)
- Use <festevam@denx.de> address for both Author and Signed-of (Fabio's feedback)
Changes since v4:
- Remove redundant description and update subject prefix (per Krzysztof's feddback)
Changes since v3:
- Add items for clocks (per Krzysztof's feddback)
- Add description for clocks (per Conor's feddback to the other similar patch from Alexander)
- Add "media:" to the subject
- Add Mirela's signed-off
- For the similar patches that were sent for this issue, should Co-developed-by/Signed-off-by be added? Alexander Stein? Frank Li?
Changes since v2:
- Remove clock-names. (Mirela)
.../devicetree/bindings/media/nxp,imx8-jpeg.yaml | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml b/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
index 3d9d1db37040..2be30c5fdc83 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
@@ -31,6 +31,11 @@ properties:
reg:
maxItems: 1
+ clocks:
+ items:
+ - description: AXI DMA engine clock for fetching JPEG bitstream from memory (per)
+ - description: IP bus clock for register access (ipg)
+
interrupts:
description: |
There are 4 slots available in the IP, which the driver may use
@@ -49,6 +54,7 @@ properties:
required:
- compatible
- reg
+ - clocks
- interrupts
- power-domains
@@ -56,12 +62,15 @@ additionalProperties: false
examples:
- |
+ #include <dt-bindings/clock/imx8-lpcg.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/firmware/imx/rsrc.h>
jpegdec: jpegdec@58400000 {
compatible = "nxp,imx8qxp-jpgdec";
reg = <0x58400000 0x00050000 >;
+ clocks = <&img_jpeg_dec_lpcg IMX_LPCG_CLK_0>,
+ <&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>;
interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>,
@@ -76,6 +85,8 @@ examples:
jpegenc: jpegenc@58450000 {
compatible = "nxp,imx8qm-jpgenc", "nxp,imx8qxp-jpgenc";
reg = <0x58450000 0x00050000 >;
+ clocks = <&img_jpeg_enc_lpcg IMX_LPCG_CLK_0>,
+ <&img_jpeg__lpcg IMX_LPCG_CLK_4>;
interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
--
2.25.1
^ permalink raw reply related
* [PATCH v6 2/2] arm64: dts: imx8-ss-img: Remove JPEG clock-names
From: Mirela Rabulea @ 2024-04-08 12:06 UTC (permalink / raw)
To: shawnguo, robh+dt, krzysztof.kozlowski+dt, festevam, festevam,
alexander.stein, Frank.li, ming.qian
Cc: conor+dt, devicetree, linux-arm-kernel, s.hauer, kernel, mchehab,
hverkuil, linux-media, imx, linux-kernel
In-Reply-To: <20240408120654.1196880-1-mirela.rabulea@nxp.com>
From: Fabio Estevam <festevam@denx.de>
Per nxp,imx8-jpeg.yaml, the clock-names entry is not valid.
Remove them.
Signed-off-by: Fabio Estevam <festevam@denx.de>
---
Changes since v5:
- Use <festevam@denx.de> address for both Author and Signed-of (Fabio's feedback)
Changes since v4:
- None
Changes since v3:
- Just added "imx8-ss-img:" in the subject
Changes since v2:
- Newly introduced.
arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
index e7783cc2d830..77d2928997b4 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
@@ -21,7 +21,6 @@ jpegdec: jpegdec@58400000 {
interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&img_jpeg_dec_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>;
- clock-names = "per", "ipg";
assigned-clocks = <&img_jpeg_dec_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>;
assigned-clock-rates = <200000000>, <200000000>;
@@ -35,7 +34,6 @@ jpegenc: jpegenc@58450000 {
interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&img_jpeg_enc_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_enc_lpcg IMX_LPCG_CLK_4>;
- clock-names = "per", "ipg";
assigned-clocks = <&img_jpeg_enc_lpcg IMX_LPCG_CLK_0>,
<&img_jpeg_enc_lpcg IMX_LPCG_CLK_4>;
assigned-clock-rates = <200000000>, <200000000>;
--
2.25.1
^ permalink raw reply related
* [PATCH V2 1/2] arm64: dts: imx8mp-msc-sm2s: do not write i2c pinctrl reserved bit
From: Ian Ray @ 2024-04-08 12:23 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Ian Ray, devicetree, imx, linux-arm-kernel, linux-kernel
Better not to write to the reserved bit.
Signed-off-by: Ian Ray <ian.ray@gehealthcare.com>
---
.../boot/dts/freescale/imx8mp-msc-sm2s.dtsi | 24 +++++++++----------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
index 61c2a63efc6d..940bdbe115a3 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
@@ -602,38 +602,38 @@ pinctrl_flexspi0: flexspi0grp {
pinctrl_i2c1: i2c1grp {
fsl,pins =
- <MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c3>,
- <MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c2>,
+ <MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c2>;
};
pinctrl_i2c2: i2c2grp {
fsl,pins =
- <MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c3>,
- <MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2>,
+ <MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c2>;
};
pinctrl_i2c3: i2c3grp {
fsl,pins =
- <MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c3>,
- <MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c2>,
+ <MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c2>;
};
pinctrl_i2c4: i2c4grp {
fsl,pins =
- <MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c3>,
- <MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c2>,
+ <MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c2>;
};
pinctrl_i2c5: i2c5grp {
fsl,pins =
- <MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x400001c3>,
- <MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x400001c2>,
+ <MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x400001c2>;
};
pinctrl_i2c6: i2c6grp {
fsl,pins =
- <MX8MP_IOMUXC_SAI5_RXFS__I2C6_SCL 0x400001c3>,
- <MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA 0x400001c3>;
+ <MX8MP_IOMUXC_SAI5_RXFS__I2C6_SCL 0x400001c2>,
+ <MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA 0x400001c2>;
};
pinctrl_lcd0_backlight: lcd0-backlightgrp {
--
2.39.2
^ permalink raw reply related
* [PATCH V2 2/2] arm64: dts: imx8mp-msc-sm2s: Add i2c{1,6} sda-/scl-gpios
From: Ian Ray @ 2024-04-08 12:23 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Ian Ray, devicetree, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <20240408122321.464-1-ian.ray@gehealthcare.com>
Add i2c{1,6} sda-/scl-gpios with the corresponding pinmux entries.
Signed-off-by: Ian Ray <ian.ray@gehealthcare.com>
---
.../boot/dts/freescale/imx8mp-msc-sm2s.dtsi | 22 +++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
index 940bdbe115a3..aeb557fe9dd6 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
@@ -200,8 +200,11 @@ ethphy1: ethernet-phy@1 {
};
&i2c1 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c1>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
clock-frequency = <400000>;
status = "okay";
@@ -241,8 +244,11 @@ &i2c5 {
};
&i2c6 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c6>;
+ pinctrl-1 = <&pinctrl_i2c6_gpio>;
+ scl-gpios = <&gpio3 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&gpio3 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
clock-frequency = <400000>;
status = "okay";
@@ -606,6 +612,12 @@ pinctrl_i2c1: i2c1grp {
<MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c2>;
};
+ pinctrl_i2c1_gpio: i2c1gpiogrp {
+ fsl,pins =
+ <MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14 0x1c2>,
+ <MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15 0x1c2>;
+ };
+
pinctrl_i2c2: i2c2grp {
fsl,pins =
<MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2>,
@@ -636,6 +648,12 @@ pinctrl_i2c6: i2c6grp {
<MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA 0x400001c2>;
};
+ pinctrl_i2c6_gpio: i2c6gpiogrp {
+ fsl,pins =
+ <MX8MP_IOMUXC_SAI5_RXFS__GPIO3_IO19 0x1c2>,
+ <MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20 0x1c2>;
+ };
+
pinctrl_lcd0_backlight: lcd0-backlightgrp {
fsl,pins =
<MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 0x41>;
--
2.39.2
^ permalink raw reply related
* Re: [PATCH v6 1/2] media: dt-bindings: nxp,imx8-jpeg: Add clocks entries
From: Krzysztof Kozlowski @ 2024-04-08 12:31 UTC (permalink / raw)
To: Mirela Rabulea, shawnguo, robh+dt, krzysztof.kozlowski+dt,
festevam, festevam, alexander.stein, Frank.li, ming.qian
Cc: conor+dt, devicetree, linux-arm-kernel, s.hauer, kernel, mchehab,
hverkuil, linux-media, imx, linux-kernel
In-Reply-To: <20240408120654.1196880-1-mirela.rabulea@nxp.com>
On 08/04/2024 14:06, Mirela Rabulea wrote:
> From: Fabio Estevam <festevam@denx.de>
>
> The JPEG decoder/encoder present in iMX8QXP and iMX8QM SoCs need
> the PER and IPG clocks to be functional, so add the clock entries.
>
> This also fixes the following schema warning:
>
> imx8qm-apalis-eval.dtb: jpegdec@58400000: 'assigned-clock-rates', 'assigned-clocks', 'clock-names', 'clocks' do not match any of the regexes: 'pinctrl-[0-9]+'
> from schema $id: http://devicetree.org/schemas/media/nxp,imx8-jpeg.yaml#
>
> Signed-off-by: Fabio Estevam <festevam@denx.de>
> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> ---
This is like third version today? Give people chance to review your code
and wait 24h before postings.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v6 1/2] media: dt-bindings: nxp,imx8-jpeg: Add clocks entries
From: Krzysztof Kozlowski @ 2024-04-08 12:32 UTC (permalink / raw)
To: Mirela Rabulea, shawnguo, robh+dt, krzysztof.kozlowski+dt,
festevam, festevam, alexander.stein, Frank.li, ming.qian
Cc: conor+dt, devicetree, linux-arm-kernel, s.hauer, kernel, mchehab,
hverkuil, linux-media, imx, linux-kernel
In-Reply-To: <20240408120654.1196880-1-mirela.rabulea@nxp.com>
On 08/04/2024 14:06, Mirela Rabulea wrote:
> From: Fabio Estevam <festevam@denx.de>
>
> The JPEG decoder/encoder present in iMX8QXP and iMX8QM SoCs need
> the PER and IPG clocks to be functional, so add the clock entries.
>
> This also fixes the following schema warning:
>
> imx8qm-apalis-eval.dtb: jpegdec@58400000: 'assigned-clock-rates', 'assigned-clocks', 'clock-names', 'clocks' do not match any of the regexes: 'pinctrl-[0-9]+'
> from schema $id: http://devicetree.org/schemas/media/nxp,imx8-jpeg.yaml#
>
> Signed-off-by: Fabio Estevam <festevam@denx.de>
> Signed-off-by: Mirela Rabulea <mirela.rabulea@nxp.com>
> ---
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
This is an automated instruction, just in case, because many review tags
are being ignored. If you know the process, you can skip it (please do
not feel offended by me posting it here - no bad intentions intended).
If you do not know the process, here is a short explanation:
Please add Acked-by/Reviewed-by/Tested-by tags when posting new
versions, under or above your Signed-off-by tag. Tag is "received", when
provided in a message replied to you on the mailing list. Tools like b4
can help here. However, there's no need to repost patches *only* to add
the tags. The upstream maintainer will do that for tags received on the
version they apply.
https://elixir.bootlin.com/linux/v6.5-rc3/source/Documentation/process/submitting-patches.rst#L577
Best regards,
Krzysztof
^ permalink raw reply
* [PATCH v6 04/11] dt-bindings: mfd: ti,tps6594: Add TI TPS65224 PMIC
From: Bhargav Raviprakash @ 2024-04-08 12:40 UTC (permalink / raw)
To: linux-kernel
Cc: m.nirmaladevi, lee, robh+dt, krzysztof.kozlowski+dt, conor+dt,
jpanis, devicetree, arnd, gregkh, lgirdwood, broonie,
linus.walleij, linux-gpio, linux-arm-kernel, nm, vigneshr, kristo,
eblanc, Bhargav Raviprakash, Conor Dooley
In-Reply-To: <20240408124047.191895-1-bhargav.r@ltts.com>
TPS65224 is a Power Management IC with 4 Buck regulators and 3 LDO
regulators, it includes additional features like GPIOs, watchdog, ESMs
(Error Signal Monitor), and PFSM (Pre-configurable Finite State Machine)
managing the state of the device.
In addition TPS65224 has support for 12-bit ADC and does not have RTC
unlike TPS6594.
Signed-off-by: Bhargav Raviprakash <bhargav.r@ltts.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
---
Documentation/devicetree/bindings/mfd/ti,tps6594.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
index 9d43376be..6341b6070 100644
--- a/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
+++ b/Documentation/devicetree/bindings/mfd/ti,tps6594.yaml
@@ -21,6 +21,7 @@ properties:
- ti,lp8764-q1
- ti,tps6593-q1
- ti,tps6594-q1
+ - ti,tps65224-q1
reg:
description: I2C slave address or SPI chip select number.
--
2.25.1
^ permalink raw reply related
* [PATCH v6 10/11] pinctrl: pinctrl-tps6594: Add TPS65224 PMIC pinctrl and GPIO
From: Bhargav Raviprakash @ 2024-04-08 12:40 UTC (permalink / raw)
To: linux-kernel
Cc: m.nirmaladevi, lee, robh+dt, krzysztof.kozlowski+dt, conor+dt,
jpanis, devicetree, arnd, gregkh, lgirdwood, broonie,
linus.walleij, linux-gpio, linux-arm-kernel, nm, vigneshr, kristo,
eblanc, Bhargav Raviprakash
In-Reply-To: <20240408124047.191895-1-bhargav.r@ltts.com>
From: Nirmala Devi Mal Nadar <m.nirmaladevi@ltts.com>
Add support for TPS65224 pinctrl and GPIOs to TPS6594 driver as they have
significant functional overlap.
TPS65224 PMIC has 6 GPIOS which can be configured as GPIO or other
dedicated device functions.
Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi@ltts.com>
Signed-off-by: Bhargav Raviprakash <bhargav.r@ltts.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/pinctrl-tps6594.c | 275 +++++++++++++++++++++++++-----
1 file changed, 228 insertions(+), 47 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-tps6594.c b/drivers/pinctrl/pinctrl-tps6594.c
index 66985e54b..f3d1c1518 100644
--- a/drivers/pinctrl/pinctrl-tps6594.c
+++ b/drivers/pinctrl/pinctrl-tps6594.c
@@ -14,8 +14,6 @@
#include <linux/mfd/tps6594.h>
-#define TPS6594_PINCTRL_PINS_NB 11
-
#define TPS6594_PINCTRL_GPIO_FUNCTION 0
#define TPS6594_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION 1
#define TPS6594_PINCTRL_TRIG_WDOG_FUNCTION 1
@@ -40,17 +38,40 @@
#define TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION_GPIO8 3
#define TPS6594_PINCTRL_CLK32KOUT_FUNCTION_GPIO9 3
+/* TPS65224 pin muxval */
+#define TPS65224_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION 1
+#define TPS65224_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION 1
+#define TPS65224_PINCTRL_VMON1_FUNCTION 1
+#define TPS65224_PINCTRL_VMON2_FUNCTION 1
+#define TPS65224_PINCTRL_WKUP_FUNCTION 1
+#define TPS65224_PINCTRL_NSLEEP2_FUNCTION 2
+#define TPS65224_PINCTRL_NSLEEP1_FUNCTION 2
+#define TPS65224_PINCTRL_SYNCCLKIN_FUNCTION 2
+#define TPS65224_PINCTRL_NERR_MCU_FUNCTION 2
+#define TPS65224_PINCTRL_NINT_FUNCTION 3
+#define TPS65224_PINCTRL_TRIG_WDOG_FUNCTION 3
+#define TPS65224_PINCTRL_PB_FUNCTION 3
+#define TPS65224_PINCTRL_ADC_IN_FUNCTION 3
+
+/* TPS65224 Special muxval for recalcitrant pins */
+#define TPS65224_PINCTRL_NSLEEP2_FUNCTION_GPIO5 1
+#define TPS65224_PINCTRL_WKUP_FUNCTION_GPIO5 4
+#define TPS65224_PINCTRL_SYNCCLKIN_FUNCTION_GPIO5 3
+
#define TPS6594_OFFSET_GPIO_SEL 5
-#define FUNCTION(fname, v) \
+#define TPS65224_NGPIO_PER_REG 6
+#define TPS6594_NGPIO_PER_REG 8
+
+#define FUNCTION(dev_name, fname, v) \
{ \
.pinfunction = PINCTRL_PINFUNCTION(#fname, \
- tps6594_##fname##_func_group_names, \
- ARRAY_SIZE(tps6594_##fname##_func_group_names)),\
+ dev_name##_##fname##_func_group_names, \
+ ARRAY_SIZE(dev_name##_##fname##_func_group_names)),\
.muxval = v, \
}
-static const struct pinctrl_pin_desc tps6594_pins[TPS6594_PINCTRL_PINS_NB] = {
+static const struct pinctrl_pin_desc tps6594_pins[] = {
PINCTRL_PIN(0, "GPIO0"), PINCTRL_PIN(1, "GPIO1"),
PINCTRL_PIN(2, "GPIO2"), PINCTRL_PIN(3, "GPIO3"),
PINCTRL_PIN(4, "GPIO4"), PINCTRL_PIN(5, "GPIO5"),
@@ -143,30 +164,127 @@ static const char *const tps6594_syncclkin_func_group_names[] = {
"GPIO9",
};
+static const struct pinctrl_pin_desc tps65224_pins[] = {
+ PINCTRL_PIN(0, "GPIO0"), PINCTRL_PIN(1, "GPIO1"),
+ PINCTRL_PIN(2, "GPIO2"), PINCTRL_PIN(3, "GPIO3"),
+ PINCTRL_PIN(4, "GPIO4"), PINCTRL_PIN(5, "GPIO5"),
+};
+
+static const char *const tps65224_gpio_func_group_names[] = {
+ "GPIO0", "GPIO1", "GPIO2", "GPIO3", "GPIO4", "GPIO5",
+};
+
+static const char *const tps65224_sda_i2c2_sdo_spi_func_group_names[] = {
+ "GPIO0",
+};
+
+static const char *const tps65224_nsleep2_func_group_names[] = {
+ "GPIO0", "GPIO5",
+};
+
+static const char *const tps65224_nint_func_group_names[] = {
+ "GPIO0",
+};
+
+static const char *const tps65224_scl_i2c2_cs_spi_func_group_names[] = {
+ "GPIO1",
+};
+
+static const char *const tps65224_nsleep1_func_group_names[] = {
+ "GPIO1", "GPIO2", "GPIO3",
+};
+
+static const char *const tps65224_trig_wdog_func_group_names[] = {
+ "GPIO1",
+};
+
+static const char *const tps65224_vmon1_func_group_names[] = {
+ "GPIO2",
+};
+
+static const char *const tps65224_pb_func_group_names[] = {
+ "GPIO2",
+};
+
+static const char *const tps65224_vmon2_func_group_names[] = {
+ "GPIO3",
+};
+
+static const char *const tps65224_adc_in_func_group_names[] = {
+ "GPIO3", "GPIO4",
+};
+
+static const char *const tps65224_wkup_func_group_names[] = {
+ "GPIO4", "GPIO5",
+};
+
+static const char *const tps65224_syncclkin_func_group_names[] = {
+ "GPIO4", "GPIO5",
+};
+
+static const char *const tps65224_nerr_mcu_func_group_names[] = {
+ "GPIO5",
+};
+
struct tps6594_pinctrl_function {
struct pinfunction pinfunction;
u8 muxval;
};
+struct muxval_remap {
+ unsigned int group;
+ u8 muxval;
+ u8 remap;
+};
+
+struct muxval_remap tps65224_muxval_remap[] = {
+ {5, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION, TPS65224_PINCTRL_WKUP_FUNCTION_GPIO5},
+ {5, TPS65224_PINCTRL_SYNCCLKIN_FUNCTION, TPS65224_PINCTRL_SYNCCLKIN_FUNCTION_GPIO5},
+ {5, TPS65224_PINCTRL_NSLEEP2_FUNCTION, TPS65224_PINCTRL_NSLEEP2_FUNCTION_GPIO5},
+};
+
+struct muxval_remap tps6594_muxval_remap[] = {
+ {8, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION_GPIO8},
+ {8, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION_GPIO8},
+ {9, TPS6594_PINCTRL_CLK32KOUT_FUNCTION, TPS6594_PINCTRL_CLK32KOUT_FUNCTION_GPIO9},
+};
+
static const struct tps6594_pinctrl_function pinctrl_functions[] = {
- FUNCTION(gpio, TPS6594_PINCTRL_GPIO_FUNCTION),
- FUNCTION(nsleep1, TPS6594_PINCTRL_NSLEEP1_FUNCTION),
- FUNCTION(nsleep2, TPS6594_PINCTRL_NSLEEP2_FUNCTION),
- FUNCTION(wkup1, TPS6594_PINCTRL_WKUP1_FUNCTION),
- FUNCTION(wkup2, TPS6594_PINCTRL_WKUP2_FUNCTION),
- FUNCTION(scl_i2c2_cs_spi, TPS6594_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION),
- FUNCTION(nrstout_soc, TPS6594_PINCTRL_NRSTOUT_SOC_FUNCTION),
- FUNCTION(trig_wdog, TPS6594_PINCTRL_TRIG_WDOG_FUNCTION),
- FUNCTION(sda_i2c2_sdo_spi, TPS6594_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION),
- FUNCTION(clk32kout, TPS6594_PINCTRL_CLK32KOUT_FUNCTION),
- FUNCTION(nerr_soc, TPS6594_PINCTRL_NERR_SOC_FUNCTION),
- FUNCTION(sclk_spmi, TPS6594_PINCTRL_SCLK_SPMI_FUNCTION),
- FUNCTION(sdata_spmi, TPS6594_PINCTRL_SDATA_SPMI_FUNCTION),
- FUNCTION(nerr_mcu, TPS6594_PINCTRL_NERR_MCU_FUNCTION),
- FUNCTION(syncclkout, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION),
- FUNCTION(disable_wdog, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION),
- FUNCTION(pdog, TPS6594_PINCTRL_PDOG_FUNCTION),
- FUNCTION(syncclkin, TPS6594_PINCTRL_SYNCCLKIN_FUNCTION),
+ FUNCTION(tps6594, gpio, TPS6594_PINCTRL_GPIO_FUNCTION),
+ FUNCTION(tps6594, nsleep1, TPS6594_PINCTRL_NSLEEP1_FUNCTION),
+ FUNCTION(tps6594, nsleep2, TPS6594_PINCTRL_NSLEEP2_FUNCTION),
+ FUNCTION(tps6594, wkup1, TPS6594_PINCTRL_WKUP1_FUNCTION),
+ FUNCTION(tps6594, wkup2, TPS6594_PINCTRL_WKUP2_FUNCTION),
+ FUNCTION(tps6594, scl_i2c2_cs_spi, TPS6594_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION),
+ FUNCTION(tps6594, nrstout_soc, TPS6594_PINCTRL_NRSTOUT_SOC_FUNCTION),
+ FUNCTION(tps6594, trig_wdog, TPS6594_PINCTRL_TRIG_WDOG_FUNCTION),
+ FUNCTION(tps6594, sda_i2c2_sdo_spi, TPS6594_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION),
+ FUNCTION(tps6594, clk32kout, TPS6594_PINCTRL_CLK32KOUT_FUNCTION),
+ FUNCTION(tps6594, nerr_soc, TPS6594_PINCTRL_NERR_SOC_FUNCTION),
+ FUNCTION(tps6594, sclk_spmi, TPS6594_PINCTRL_SCLK_SPMI_FUNCTION),
+ FUNCTION(tps6594, sdata_spmi, TPS6594_PINCTRL_SDATA_SPMI_FUNCTION),
+ FUNCTION(tps6594, nerr_mcu, TPS6594_PINCTRL_NERR_MCU_FUNCTION),
+ FUNCTION(tps6594, syncclkout, TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION),
+ FUNCTION(tps6594, disable_wdog, TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION),
+ FUNCTION(tps6594, pdog, TPS6594_PINCTRL_PDOG_FUNCTION),
+ FUNCTION(tps6594, syncclkin, TPS6594_PINCTRL_SYNCCLKIN_FUNCTION),
+};
+
+static const struct tps6594_pinctrl_function tps65224_pinctrl_functions[] = {
+ FUNCTION(tps65224, gpio, TPS6594_PINCTRL_GPIO_FUNCTION),
+ FUNCTION(tps65224, sda_i2c2_sdo_spi, TPS65224_PINCTRL_SDA_I2C2_SDO_SPI_FUNCTION),
+ FUNCTION(tps65224, nsleep2, TPS65224_PINCTRL_NSLEEP2_FUNCTION),
+ FUNCTION(tps65224, nint, TPS65224_PINCTRL_NINT_FUNCTION),
+ FUNCTION(tps65224, scl_i2c2_cs_spi, TPS65224_PINCTRL_SCL_I2C2_CS_SPI_FUNCTION),
+ FUNCTION(tps65224, nsleep1, TPS65224_PINCTRL_NSLEEP1_FUNCTION),
+ FUNCTION(tps65224, trig_wdog, TPS65224_PINCTRL_TRIG_WDOG_FUNCTION),
+ FUNCTION(tps65224, vmon1, TPS65224_PINCTRL_VMON1_FUNCTION),
+ FUNCTION(tps65224, pb, TPS65224_PINCTRL_PB_FUNCTION),
+ FUNCTION(tps65224, vmon2, TPS65224_PINCTRL_VMON2_FUNCTION),
+ FUNCTION(tps65224, adc_in, TPS65224_PINCTRL_ADC_IN_FUNCTION),
+ FUNCTION(tps65224, wkup, TPS65224_PINCTRL_WKUP_FUNCTION),
+ FUNCTION(tps65224, syncclkin, TPS65224_PINCTRL_SYNCCLKIN_FUNCTION),
+ FUNCTION(tps65224, nerr_mcu, TPS65224_PINCTRL_NERR_MCU_FUNCTION),
};
struct tps6594_pinctrl {
@@ -175,6 +293,31 @@ struct tps6594_pinctrl {
struct pinctrl_dev *pctl_dev;
const struct tps6594_pinctrl_function *funcs;
const struct pinctrl_pin_desc *pins;
+ int func_cnt;
+ int num_pins;
+ u8 mux_sel_mask;
+ unsigned int remap_cnt;
+ struct muxval_remap *remap;
+};
+
+static struct tps6594_pinctrl tps65224_template_pinctrl = {
+ .funcs = tps65224_pinctrl_functions,
+ .func_cnt = ARRAY_SIZE(tps65224_pinctrl_functions),
+ .pins = tps65224_pins,
+ .num_pins = ARRAY_SIZE(tps65224_pins),
+ .mux_sel_mask = TPS65224_MASK_GPIO_SEL,
+ .remap = tps65224_muxval_remap,
+ .remap_cnt = ARRAY_SIZE(tps65224_muxval_remap),
+};
+
+static struct tps6594_pinctrl tps6594_template_pinctrl = {
+ .funcs = pinctrl_functions,
+ .func_cnt = ARRAY_SIZE(pinctrl_functions),
+ .pins = tps6594_pins,
+ .num_pins = ARRAY_SIZE(tps6594_pins),
+ .mux_sel_mask = TPS6594_MASK_GPIO_SEL,
+ .remap = tps6594_muxval_remap,
+ .remap_cnt = ARRAY_SIZE(tps6594_muxval_remap),
};
static int tps6594_gpio_regmap_xlate(struct gpio_regmap *gpio,
@@ -201,7 +344,9 @@ static int tps6594_gpio_regmap_xlate(struct gpio_regmap *gpio,
static int tps6594_pmx_func_cnt(struct pinctrl_dev *pctldev)
{
- return ARRAY_SIZE(pinctrl_functions);
+ struct tps6594_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pinctrl->func_cnt;
}
static const char *tps6594_pmx_func_name(struct pinctrl_dev *pctldev,
@@ -229,10 +374,16 @@ static int tps6594_pmx_set(struct tps6594_pinctrl *pinctrl, unsigned int pin,
u8 muxval)
{
u8 mux_sel_val = muxval << TPS6594_OFFSET_GPIO_SEL;
+ u8 mux_sel_mask = pinctrl->mux_sel_mask;
+
+ if (pinctrl->tps->chip_id == TPS65224 && pin == 5) {
+ /* GPIO6 has a different mask in TPS65224*/
+ mux_sel_mask = TPS65224_MASK_GPIO_SEL_GPIO6;
+ }
return regmap_update_bits(pinctrl->tps->regmap,
TPS6594_REG_GPIOX_CONF(pin),
- TPS6594_MASK_GPIO_SEL, mux_sel_val);
+ mux_sel_mask, mux_sel_val);
}
static int tps6594_pmx_set_mux(struct pinctrl_dev *pctldev,
@@ -240,16 +391,14 @@ static int tps6594_pmx_set_mux(struct pinctrl_dev *pctldev,
{
struct tps6594_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
u8 muxval = pinctrl->funcs[function].muxval;
-
- /* Some pins don't have the same muxval for the same function... */
- if (group == 8) {
- if (muxval == TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION)
- muxval = TPS6594_PINCTRL_DISABLE_WDOG_FUNCTION_GPIO8;
- else if (muxval == TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION)
- muxval = TPS6594_PINCTRL_SYNCCLKOUT_FUNCTION_GPIO8;
- } else if (group == 9) {
- if (muxval == TPS6594_PINCTRL_CLK32KOUT_FUNCTION)
- muxval = TPS6594_PINCTRL_CLK32KOUT_FUNCTION_GPIO9;
+ unsigned int remap_cnt = pinctrl->remap_cnt;
+ struct muxval_remap *remap = pinctrl->remap;
+
+ for (unsigned int i = 0; i < remap_cnt; i++) {
+ if (group == remap[i].group && muxval == remap[i].muxval) {
+ muxval = remap[i].remap;
+ break;
+ }
}
return tps6594_pmx_set(pinctrl, group, muxval);
@@ -276,7 +425,9 @@ static const struct pinmux_ops tps6594_pmx_ops = {
static int tps6594_groups_cnt(struct pinctrl_dev *pctldev)
{
- return ARRAY_SIZE(tps6594_pins);
+ struct tps6594_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctldev);
+
+ return pinctrl->num_pins;
}
static int tps6594_group_pins(struct pinctrl_dev *pctldev,
@@ -318,19 +469,36 @@ static int tps6594_pinctrl_probe(struct platform_device *pdev)
pctrl_desc = devm_kzalloc(dev, sizeof(*pctrl_desc), GFP_KERNEL);
if (!pctrl_desc)
return -ENOMEM;
+
+ pinctrl = devm_kzalloc(dev, sizeof(*pinctrl), GFP_KERNEL);
+ if (!pinctrl)
+ return -ENOMEM;
+
pctrl_desc->name = dev_name(dev);
pctrl_desc->owner = THIS_MODULE;
- pctrl_desc->pins = tps6594_pins;
- pctrl_desc->npins = ARRAY_SIZE(tps6594_pins);
pctrl_desc->pctlops = &tps6594_pctrl_ops;
pctrl_desc->pmxops = &tps6594_pmx_ops;
- pinctrl = devm_kzalloc(dev, sizeof(*pinctrl), GFP_KERNEL);
- if (!pinctrl)
- return -ENOMEM;
- pinctrl->tps = dev_get_drvdata(dev->parent);
- pinctrl->funcs = pinctrl_functions;
- pinctrl->pins = tps6594_pins;
+ switch (tps->chip_id) {
+ case TPS65224:
+ pctrl_desc->pins = tps65224_pins;
+ pctrl_desc->npins = ARRAY_SIZE(tps65224_pins);
+
+ *pinctrl = tps65224_template_pinctrl;
+ break;
+ case TPS6593:
+ case TPS6594:
+ pctrl_desc->pins = tps6594_pins;
+ pctrl_desc->npins = ARRAY_SIZE(tps6594_pins);
+
+ *pinctrl = tps6594_template_pinctrl;
+ break;
+ default:
+ break;
+ }
+
+ pinctrl->tps = tps;
+
pinctrl->pctl_dev = devm_pinctrl_register(dev, pctrl_desc, pinctrl);
if (IS_ERR(pinctrl->pctl_dev))
return dev_err_probe(dev, PTR_ERR(pinctrl->pctl_dev),
@@ -338,8 +506,20 @@ static int tps6594_pinctrl_probe(struct platform_device *pdev)
config.parent = tps->dev;
config.regmap = tps->regmap;
- config.ngpio = TPS6594_PINCTRL_PINS_NB;
- config.ngpio_per_reg = 8;
+ switch (tps->chip_id) {
+ case TPS65224:
+ config.ngpio = ARRAY_SIZE(tps65224_gpio_func_group_names);
+ config.ngpio_per_reg = TPS65224_NGPIO_PER_REG;
+ break;
+ case TPS6593:
+ case TPS6594:
+ config.ngpio = ARRAY_SIZE(tps6594_gpio_func_group_names);
+ config.ngpio_per_reg = TPS6594_NGPIO_PER_REG;
+ break;
+ default:
+ break;
+ }
+
config.reg_dat_base = TPS6594_REG_GPIO_IN_1;
config.reg_set_base = TPS6594_REG_GPIO_OUT_1;
config.reg_dir_out_base = TPS6594_REG_GPIOX_CONF(0);
@@ -369,5 +549,6 @@ static struct platform_driver tps6594_pinctrl_driver = {
module_platform_driver(tps6594_pinctrl_driver);
MODULE_AUTHOR("Esteban Blanc <eblanc@baylibre.com>");
+MODULE_AUTHOR("Nirmala Devi Mal Nadar <m.nirmaladevi@ltts.com>");
MODULE_DESCRIPTION("TPS6594 pinctrl and GPIO driver");
MODULE_LICENSE("GPL");
--
2.25.1
^ permalink raw reply related
* [PATCH v6 11/11] arch: arm64: dts: ti: k3-am62p5-sk: Add TPS65224 PMIC support in AM62P dts
From: Bhargav Raviprakash @ 2024-04-08 12:40 UTC (permalink / raw)
To: linux-kernel
Cc: m.nirmaladevi, lee, robh+dt, krzysztof.kozlowski+dt, conor+dt,
jpanis, devicetree, arnd, gregkh, lgirdwood, broonie,
linus.walleij, linux-gpio, linux-arm-kernel, nm, vigneshr, kristo,
eblanc, Bhargav Raviprakash
In-Reply-To: <20240408124047.191895-1-bhargav.r@ltts.com>
Add support for TPS65224 PMIC in device tree of AM62P EVM. Adds regulator
configuration, pinmux configurations and pmic device nodes.
Signed-off-by: Bhargav Raviprakash <bhargav.r@ltts.com>
---
arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 95 +++++++++++++++++++++++++
1 file changed, 95 insertions(+)
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
index 1773c05f7..5d8e4321b 100644
--- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -112,6 +112,16 @@ vddshv_sdio: regulator-3 {
bootph-all;
};
+ vcc_3v3_main: regulator-4 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_main";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vmain_pd>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -580,6 +590,12 @@ &main_uart1 {
&mcu_pmx0 {
bootph-all;
+ pmic_irq_pins_default: pmic-irq-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_MCU_IOPAD(0x000, PIN_INPUT, 7) /* (B10) MCU_GPIO0_0 */
+ >;
+ };
+
wkup_uart0_pins_default: wkup-uart0-default-pins {
pinctrl-single,pins = <
AM62PX_MCU_IOPAD(0x02c, PIN_INPUT, 0) /* (C7) WKUP_UART0_CTSn */
@@ -589,6 +605,13 @@ AM62PX_MCU_IOPAD(0x028, PIN_OUTPUT, 0) /* (D7) WKUP_UART0_TXD */
>;
bootph-all;
};
+
+ wkup_i2c0_pins_default: wkup-i2c0-default-pins {
+ pinctrl-single,pins = <
+ AM62PX_MCU_IOPAD(0x04c, PIN_INPUT, 0) /* (A13) WKUP_I2C0_SCL */
+ AM62PX_MCU_IOPAD(0x050, PIN_INPUT, 0) /* (C11) WKUP_I2C0_SDA */
+ >;
+ };
};
&wkup_uart0 {
@@ -599,6 +622,78 @@ &wkup_uart0 {
bootph-all;
};
+&wkup_i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wkup_i2c0_pins_default>;
+ clock-frequency = <400000>;
+
+ tps65224: pmic@48 {
+ compatible = "ti,tps65224-q1";
+ reg = <0x48>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_irq_pins_default>;
+ interrupt-parent = <&mcu_gpio0>;
+ interrupts = <0 IRQ_TYPE_EDGE_FALLING>;
+ ti,primary-pmic;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ buck12-supply = <&vcc_3v3_main>;
+ buck3-supply = <&vcc_3v3_main>;
+ buck4-supply = <&vcc_3v3_main>;
+
+ ldo1-supply = <&vcc_3v3_main>;
+ ldo2-supply = <&vcc_3v3_main>;
+ ldo3-supply = <&vcc1v8_sys>;
+
+ regulators {
+ vcc_core: buck12 {
+ regulator-name = "vcc_core_buck12";
+ regulator-min-microvolt = <715000>;
+ regulator-max-microvolt = <895000>;
+ regulator-always-on;
+ };
+
+ vcc1v8_sys: buck3 {
+ regulator-name = "vcc1v8_sys_buck3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vcc1v1: buck4 {
+ regulator-name = "vcc1v1_buck4";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ regulator-always-on;
+ };
+
+ vdda1v8: ldo1 {
+ regulator-name = "vdda1v8_ldo1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ dvdd3v3: ldo2 {
+ regulator-name = "dvdd3v3_ldo2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ vcc_0v85: ldo3 {
+ regulator-name = "vcc_0v85_ldo3";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
/* mcu_gpio0 and mcu_gpio_intr are reserved for mcu firmware usage */
&mcu_gpio0 {
status = "reserved";
--
2.25.1
^ permalink raw reply related
* [PATCH v6 00/11] Add support for TI TPS65224 PMIC
From: Bhargav Raviprakash @ 2024-04-08 12:40 UTC (permalink / raw)
To: linux-kernel
Cc: m.nirmaladevi, lee, robh+dt, krzysztof.kozlowski+dt, conor+dt,
jpanis, devicetree, arnd, gregkh, lgirdwood, broonie,
linus.walleij, linux-gpio, linux-arm-kernel, nm, vigneshr, kristo,
eblanc, Bhargav Raviprakash
This series modifies the existing TPS6594 drivers to add support for the
TPS65224 PMIC device that is a derivative of TPS6594. TPS65224 has a
similar register map to TPS6594 with a few differences. SPI, I2C, ESM,
PFSM, Regulators and GPIO features overlap between the two devices.
TPS65224 is a Power Management IC (PMIC) which provides regulators and
other features like GPIOs, Watchdog, Error Signal Monitor (ESM) and
Pre-configurable Finite State Machine (PFSM). The SoC and the PMIC can
communicate through the I2C or SPI interfaces. The PMIC TPS65224
additionally has a 12-bit ADC.
Data Sheet for TPS65224: https://www.ti.com/product/TPS65224-Q1
Driver re-use is applied following the advice of the following series:
https://lore.kernel.org/lkml/2f467b0a-1d11-4ec7-8ca6-6c4ba66e5887@baylibre.com/
The features implemented in this series are:
- TPS65224 Register definitions
- Core (MFD I2C and SPI entry points)
- PFSM
- Regulators
- Pinctrl
TPS65224 Register definitions:
This patch adds macros for register field definitions of TPS65224
to the existing TPS6594 driver.
Core description:
I2C and SPI interface protocols are implemented, with and without
the bit-integrity error detection feature (CRC mode).
PFSM description:
Strictly speaking, PFSM is not hardware. It is a piece of code.
PMIC integrates a state machine which manages operational modes.
Depending on the current operational mode, some voltage domains
remain energized while others can be off.
PFSM driver can be used to trigger transitions between configured
states.
Regulators description:
4 BUCKs and 3 LDOs.
BUCK12 can be used in dual-phase mode.
Pinctrl description:
TPS65224 family has 6 GPIOs. Those GPIOs can also serve different
functions such as I2C or SPI interface or watchdog disable functions.
The driver provides both pinmuxing for the functions and GPIO capability.
This series was tested on linux-next tag: next-20240118
Test logs can be found here:
https://gist.github.com/LeonardMH/58ec135921fb1062ffd4a8b384831eb0
Changelog v5 -> v6:
- Refactoring regulator driver: pass both array and size
in tps6594_regulator_irq_handler function
Bhargav Raviprakash (8):
mfd: tps6594: use volatile_table instead of volatile_reg
mfd: tps6594: add regmap config in match data
dt-bindings: mfd: ti,tps6594: Add TI TPS65224 PMIC
mfd: tps6594-i2c: Add TI TPS65224 PMIC I2C
mfd: tps6594-spi: Add TI TPS65224 PMIC SPI
mfd: tps6594-core: Add TI TPS65224 PMIC core
misc: tps6594-pfsm: Add TI TPS65224 PMIC PFSM
arch: arm64: dts: ti: k3-am62p5-sk: Add TPS65224 PMIC support in AM62P
dts
Nirmala Devi Mal Nadar (3):
mfd: tps6594: Add register definitions for TI TPS65224 PMIC
regulator: tps6594-regulator: Add TI TPS65224 PMIC regulators
pinctrl: pinctrl-tps6594: Add TPS65224 PMIC pinctrl and GPIO
.../devicetree/bindings/mfd/ti,tps6594.yaml | 1 +
arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 95 +++++
drivers/mfd/tps6594-core.c | 253 ++++++++++--
drivers/mfd/tps6594-i2c.c | 41 +-
drivers/mfd/tps6594-spi.c | 43 ++-
drivers/misc/tps6594-pfsm.c | 48 ++-
drivers/pinctrl/pinctrl-tps6594.c | 275 ++++++++++---
drivers/regulator/Kconfig | 4 +-
drivers/regulator/tps6594-regulator.c | 243 ++++++++++--
include/linux/mfd/tps6594.h | 362 +++++++++++++++++-
10 files changed, 1221 insertions(+), 144 deletions(-)
base-commit: 2863b714f3ad0a9686f2de1b779228ad8c7a8052
--
2.25.1
^ permalink raw reply
* [PATCH v6 01/11] mfd: tps6594: Add register definitions for TI TPS65224 PMIC
From: Bhargav Raviprakash @ 2024-04-08 12:40 UTC (permalink / raw)
To: linux-kernel
Cc: m.nirmaladevi, lee, robh+dt, krzysztof.kozlowski+dt, conor+dt,
jpanis, devicetree, arnd, gregkh, lgirdwood, broonie,
linus.walleij, linux-gpio, linux-arm-kernel, nm, vigneshr, kristo,
eblanc, Bhargav Raviprakash
In-Reply-To: <20240408124047.191895-1-bhargav.r@ltts.com>
From: Nirmala Devi Mal Nadar <m.nirmaladevi@ltts.com>
Extend TPS6594 PMIC register and field definitions to support TPS65224
power management IC.
TPS65224 is software compatible to TPS6594 and can re-use many of the
same definitions, new definitions are added to support additional
controls available on TPS65224.
Signed-off-by: Nirmala Devi Mal Nadar <m.nirmaladevi@ltts.com>
Signed-off-by: Bhargav Raviprakash <bhargav.r@ltts.com>
---
include/linux/mfd/tps6594.h | 347 ++++++++++++++++++++++++++++++++++--
1 file changed, 335 insertions(+), 12 deletions(-)
diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h
index 3f7c5e23c..e754c01ac 100644
--- a/include/linux/mfd/tps6594.h
+++ b/include/linux/mfd/tps6594.h
@@ -18,12 +18,13 @@ enum pmic_id {
TPS6594,
TPS6593,
LP8764,
+ TPS65224,
};
/* Macro to get page index from register address */
#define TPS6594_REG_TO_PAGE(reg) ((reg) >> 8)
-/* Registers for page 0 of TPS6594 */
+/* Registers for page 0 */
#define TPS6594_REG_DEV_REV 0x01
#define TPS6594_REG_NVM_CODE_1 0x02
@@ -56,9 +57,6 @@ enum pmic_id {
#define TPS6594_REG_GPIOX_OUT(gpio_inst) (TPS6594_REG_GPIO_OUT_1 + (gpio_inst) / 8)
#define TPS6594_REG_GPIOX_IN(gpio_inst) (TPS6594_REG_GPIO_IN_1 + (gpio_inst) / 8)
-#define TPS6594_REG_GPIO_IN_1 0x3f
-#define TPS6594_REG_GPIO_IN_2 0x40
-
#define TPS6594_REG_RAIL_SEL_1 0x41
#define TPS6594_REG_RAIL_SEL_2 0x42
#define TPS6594_REG_RAIL_SEL_3 0x43
@@ -70,13 +68,15 @@ enum pmic_id {
#define TPS6594_REG_FSM_TRIG_MASK_3 0x48
#define TPS6594_REG_MASK_BUCK1_2 0x49
+#define TPS65224_REG_MASK_BUCKS 0x49
#define TPS6594_REG_MASK_BUCK3_4 0x4a
#define TPS6594_REG_MASK_BUCK5 0x4b
#define TPS6594_REG_MASK_LDO1_2 0x4c
+#define TPS65224_REG_MASK_LDOS 0x4c
#define TPS6594_REG_MASK_LDO3_4 0x4d
#define TPS6594_REG_MASK_VMON 0x4e
-#define TPS6594_REG_MASK_GPIO1_8_FALL 0x4f
-#define TPS6594_REG_MASK_GPIO1_8_RISE 0x50
+#define TPS6594_REG_MASK_GPIO_FALL 0x4f
+#define TPS6594_REG_MASK_GPIO_RISE 0x50
#define TPS6594_REG_MASK_GPIO9_11 0x51
#define TPS6594_REG_MASK_STARTUP 0x52
#define TPS6594_REG_MASK_MISC 0x53
@@ -174,6 +174,10 @@ enum pmic_id {
#define TPS6594_REG_REGISTER_LOCK 0xa1
+#define TPS65224_REG_SRAM_ACCESS_1 0xa2
+#define TPS65224_REG_SRAM_ACCESS_2 0xa3
+#define TPS65224_REG_SRAM_ADDR_CTRL 0xa4
+#define TPS65224_REG_RECOV_CNT_PFSM_INCR 0xa5
#define TPS6594_REG_MANUFACTURING_VER 0xa6
#define TPS6594_REG_CUSTOMER_NVM_ID_REG 0xa7
@@ -182,6 +186,9 @@ enum pmic_id {
#define TPS6594_REG_SOFT_REBOOT_REG 0xab
+#define TPS65224_REG_ADC_CTRL 0xac
+#define TPS65224_REG_ADC_RESULT_REG_1 0xad
+#define TPS65224_REG_ADC_RESULT_REG_2 0xae
#define TPS6594_REG_RTC_SECONDS 0xb5
#define TPS6594_REG_RTC_MINUTES 0xb6
#define TPS6594_REG_RTC_HOURS 0xb7
@@ -199,6 +206,7 @@ enum pmic_id {
#define TPS6594_REG_RTC_CTRL_1 0xc2
#define TPS6594_REG_RTC_CTRL_2 0xc3
+#define TPS65224_REG_STARTUP_CTRL 0xc3
#define TPS6594_REG_RTC_STATUS 0xc4
#define TPS6594_REG_RTC_INTERRUPTS 0xc5
#define TPS6594_REG_RTC_COMP_LSB 0xc6
@@ -214,13 +222,17 @@ enum pmic_id {
#define TPS6594_REG_PFSM_DELAY_REG_2 0xce
#define TPS6594_REG_PFSM_DELAY_REG_3 0xcf
#define TPS6594_REG_PFSM_DELAY_REG_4 0xd0
+#define TPS65224_REG_ADC_GAIN_COMP_REG 0xd0
+#define TPS65224_REG_CRC_CALC_CONTROL 0xef
+#define TPS65224_REG_REGMAP_USER_CRC_LOW 0xf0
+#define TPS65224_REG_REGMAP_USER_CRC_HIGH 0xf1
-/* Registers for page 1 of TPS6594 */
+/* Registers for page 1 */
#define TPS6594_REG_SERIAL_IF_CONFIG 0x11a
#define TPS6594_REG_I2C1_ID 0x122
#define TPS6594_REG_I2C2_ID 0x123
-/* Registers for page 4 of TPS6594 */
+/* Registers for page 4 */
#define TPS6594_REG_WD_ANSWER_REG 0x401
#define TPS6594_REG_WD_QUESTION_ANSW_CNT 0x402
#define TPS6594_REG_WD_WIN1_CFG 0x403
@@ -241,16 +253,26 @@ enum pmic_id {
#define TPS6594_BIT_BUCK_PLDN BIT(5)
#define TPS6594_BIT_BUCK_RV_SEL BIT(7)
-/* BUCKX_CONF register field definition */
+/* TPS6594 BUCKX_CONF register field definition */
#define TPS6594_MASK_BUCK_SLEW_RATE GENMASK(2, 0)
#define TPS6594_MASK_BUCK_ILIM GENMASK(5, 3)
-/* BUCKX_PG_WINDOW register field definition */
+/* TPS65224 BUCKX_CONF register field definition */
+#define TPS65224_MASK_BUCK_SLEW_RATE GENMASK(1, 0)
+
+/* TPS6594 BUCKX_PG_WINDOW register field definition */
#define TPS6594_MASK_BUCK_OV_THR GENMASK(2, 0)
#define TPS6594_MASK_BUCK_UV_THR GENMASK(5, 3)
-/* BUCKX VSET */
-#define TPS6594_MASK_BUCKS_VSET GENMASK(7, 0)
+/* TPS65224 BUCKX_PG_WINDOW register field definition */
+#define TPS65224_MASK_BUCK_VMON_THR GENMASK(1, 0)
+
+/* TPS6594 BUCKX_VOUT register field definition */
+#define TPS6594_MASK_BUCKS_VSET GENMASK(7, 0)
+
+/* TPS65224 BUCKX_VOUT register field definition */
+#define TPS65224_MASK_BUCK1_VSET GENMASK(7, 0)
+#define TPS65224_MASK_BUCKS_VSET GENMASK(6, 0)
/* LDOX_CTRL register field definition */
#define TPS6594_BIT_LDO_EN BIT(0)
@@ -258,6 +280,7 @@ enum pmic_id {
#define TPS6594_BIT_LDO_VMON_EN BIT(4)
#define TPS6594_MASK_LDO_PLDN GENMASK(6, 5)
#define TPS6594_BIT_LDO_RV_SEL BIT(7)
+#define TPS65224_BIT_LDO_DISCHARGE_EN BIT(5)
/* LDORTC_CTRL register field definition */
#define TPS6594_BIT_LDORTC_DIS BIT(0)
@@ -271,6 +294,9 @@ enum pmic_id {
#define TPS6594_MASK_LDO_OV_THR GENMASK(2, 0)
#define TPS6594_MASK_LDO_UV_THR GENMASK(5, 3)
+/* LDOX_PG_WINDOW register field definition */
+#define TPS65224_MASK_LDO_VMON_THR GENMASK(1, 0)
+
/* VCCA_VMON_CTRL register field definition */
#define TPS6594_BIT_VMON_EN BIT(0)
#define TPS6594_BIT_VMON1_EN BIT(1)
@@ -278,10 +304,12 @@ enum pmic_id {
#define TPS6594_BIT_VMON2_EN BIT(3)
#define TPS6594_BIT_VMON2_RV_SEL BIT(4)
#define TPS6594_BIT_VMON_DEGLITCH_SEL BIT(5)
+#define TPS65224_BIT_VMON_DEGLITCH_SEL GENMASK(7, 5)
/* VCCA_PG_WINDOW register field definition */
#define TPS6594_MASK_VCCA_OV_THR GENMASK(2, 0)
#define TPS6594_MASK_VCCA_UV_THR GENMASK(5, 3)
+#define TPS65224_MASK_VCCA_VMON_THR GENMASK(1, 0)
#define TPS6594_BIT_VCCA_PG_SET BIT(6)
/* VMONX_PG_WINDOW register field definition */
@@ -289,6 +317,9 @@ enum pmic_id {
#define TPS6594_MASK_VMONX_UV_THR GENMASK(5, 3)
#define TPS6594_BIT_VMONX_RANGE BIT(6)
+/* VMONX_PG_WINDOW register field definition */
+#define TPS65224_MASK_VMONX_THR GENMASK(1, 0)
+
/* GPIOX_CONF register field definition */
#define TPS6594_BIT_GPIO_DIR BIT(0)
#define TPS6594_BIT_GPIO_OD BIT(1)
@@ -296,6 +327,8 @@ enum pmic_id {
#define TPS6594_BIT_GPIO_PU_PD_EN BIT(3)
#define TPS6594_BIT_GPIO_DEGLITCH_EN BIT(4)
#define TPS6594_MASK_GPIO_SEL GENMASK(7, 5)
+#define TPS65224_MASK_GPIO_SEL GENMASK(6, 5)
+#define TPS65224_MASK_GPIO_SEL_GPIO6 GENMASK(7, 5)
/* NPWRON_CONF register field definition */
#define TPS6594_BIT_NRSTOUT_OD BIT(0)
@@ -305,6 +338,12 @@ enum pmic_id {
#define TPS6594_BIT_ENABLE_POL BIT(5)
#define TPS6594_MASK_NPWRON_SEL GENMASK(7, 6)
+/* POWER_ON_CONFIG register field definition */
+#define TPS65224_BIT_NINT_ENDRV_PU_SEL BIT(0)
+#define TPS65224_BIT_NINT_ENDRV_SEL BIT(1)
+#define TPS65224_BIT_EN_PB_DEGL BIT(5)
+#define TPS65224_MASK_EN_PB_VSENSE_CONFIG GENMASK(7, 6)
+
/* GPIO_OUT_X register field definition */
#define TPS6594_BIT_GPIOX_OUT(gpio_inst) BIT((gpio_inst) % 8)
@@ -312,6 +351,12 @@ enum pmic_id {
#define TPS6594_BIT_GPIOX_IN(gpio_inst) BIT((gpio_inst) % 8)
#define TPS6594_BIT_NPWRON_IN BIT(3)
+/* GPIO_OUT_X register field definition */
+#define TPS65224_BIT_GPIOX_OUT(gpio_inst) BIT((gpio_inst))
+
+/* GPIO_IN_X register field definition */
+#define TPS65224_BIT_GPIOX_IN(gpio_inst) BIT((gpio_inst))
+
/* RAIL_SEL_1 register field definition */
#define TPS6594_MASK_BUCK1_GRP_SEL GENMASK(1, 0)
#define TPS6594_MASK_BUCK2_GRP_SEL GENMASK(3, 2)
@@ -343,6 +388,9 @@ enum pmic_id {
#define TPS6594_BIT_GPIOX_FSM_MASK(gpio_inst) BIT(((gpio_inst) << 1) % 8)
#define TPS6594_BIT_GPIOX_FSM_MASK_POL(gpio_inst) BIT(((gpio_inst) << 1) % 8 + 1)
+#define TPS65224_BIT_GPIOX_FSM_MASK(gpio_inst) BIT(((gpio_inst) << 1) % 6)
+#define TPS65224_BIT_GPIOX_FSM_MASK_POL(gpio_inst) BIT(((gpio_inst) << 1) % 6 + 1)
+
/* MASK_BUCKX register field definition */
#define TPS6594_BIT_BUCKX_OV_MASK(buck_inst) BIT(((buck_inst) << 2) % 8)
#define TPS6594_BIT_BUCKX_UV_MASK(buck_inst) BIT(((buck_inst) << 2) % 8 + 1)
@@ -361,22 +409,46 @@ enum pmic_id {
#define TPS6594_BIT_VMON2_OV_MASK BIT(5)
#define TPS6594_BIT_VMON2_UV_MASK BIT(6)
+/* MASK_BUCK Register field definition */
+#define TPS65224_BIT_BUCK1_UVOV_MASK BIT(0)
+#define TPS65224_BIT_BUCK2_UVOV_MASK BIT(1)
+#define TPS65224_BIT_BUCK3_UVOV_MASK BIT(2)
+#define TPS65224_BIT_BUCK4_UVOV_MASK BIT(4)
+
+/* MASK_LDO_VMON register field definition */
+#define TPS65224_BIT_LDO1_UVOV_MASK BIT(0)
+#define TPS65224_BIT_LDO2_UVOV_MASK BIT(1)
+#define TPS65224_BIT_LDO3_UVOV_MASK BIT(2)
+#define TPS65224_BIT_VCCA_UVOV_MASK BIT(4)
+#define TPS65224_BIT_VMON1_UVOV_MASK BIT(5)
+#define TPS65224_BIT_VMON2_UVOV_MASK BIT(6)
+
/* MASK_GPIOX register field definition */
#define TPS6594_BIT_GPIOX_FALL_MASK(gpio_inst) BIT((gpio_inst) < 8 ? \
(gpio_inst) : (gpio_inst) % 8)
#define TPS6594_BIT_GPIOX_RISE_MASK(gpio_inst) BIT((gpio_inst) < 8 ? \
(gpio_inst) : (gpio_inst) % 8 + 3)
+/* MASK_GPIOX register field definition */
+#define TPS65224_BIT_GPIOX_FALL_MASK(gpio_inst) BIT((gpio_inst))
+#define TPS65224_BIT_GPIOX_RISE_MASK(gpio_inst) BIT((gpio_inst))
/* MASK_STARTUP register field definition */
#define TPS6594_BIT_NPWRON_START_MASK BIT(0)
#define TPS6594_BIT_ENABLE_MASK BIT(1)
#define TPS6594_BIT_FSD_MASK BIT(4)
#define TPS6594_BIT_SOFT_REBOOT_MASK BIT(5)
+#define TPS65224_BIT_VSENSE_MASK BIT(0)
+#define TPS65224_BIT_PB_SHORT_MASK BIT(2)
/* MASK_MISC register field definition */
#define TPS6594_BIT_BIST_PASS_MASK BIT(0)
#define TPS6594_BIT_EXT_CLK_MASK BIT(1)
+#define TPS65224_BIT_REG_UNLOCK_MASK BIT(2)
#define TPS6594_BIT_TWARN_MASK BIT(3)
+#define TPS65224_BIT_PB_LONG_MASK BIT(4)
+#define TPS65224_BIT_PB_FALL_MASK BIT(5)
+#define TPS65224_BIT_PB_RISE_MASK BIT(6)
+#define TPS65224_BIT_ADC_CONV_READY_MASK BIT(7)
/* MASK_MODERATE_ERR register field definition */
#define TPS6594_BIT_BIST_FAIL_MASK BIT(1)
@@ -391,6 +463,8 @@ enum pmic_id {
#define TPS6594_BIT_ORD_SHUTDOWN_MASK BIT(1)
#define TPS6594_BIT_MCU_PWR_ERR_MASK BIT(2)
#define TPS6594_BIT_SOC_PWR_ERR_MASK BIT(3)
+#define TPS65224_BIT_COMM_ERR_MASK BIT(4)
+#define TPS65224_BIT_I2C2_ERR_MASK BIT(5)
/* MASK_COMM_ERR register field definition */
#define TPS6594_BIT_COMM_FRM_ERR_MASK BIT(0)
@@ -426,6 +500,12 @@ enum pmic_id {
#define TPS6594_BIT_BUCK3_4_INT BIT(1)
#define TPS6594_BIT_BUCK5_INT BIT(2)
+/* INT_BUCK register field definition */
+#define TPS65224_BIT_BUCK1_UVOV_INT BIT(0)
+#define TPS65224_BIT_BUCK2_UVOV_INT BIT(1)
+#define TPS65224_BIT_BUCK3_UVOV_INT BIT(2)
+#define TPS65224_BIT_BUCK4_UVOV_INT BIT(3)
+
/* INT_BUCKX register field definition */
#define TPS6594_BIT_BUCKX_OV_INT(buck_inst) BIT(((buck_inst) << 2) % 8)
#define TPS6594_BIT_BUCKX_UV_INT(buck_inst) BIT(((buck_inst) << 2) % 8 + 1)
@@ -437,6 +517,14 @@ enum pmic_id {
#define TPS6594_BIT_LDO3_4_INT BIT(1)
#define TPS6594_BIT_VCCA_INT BIT(4)
+/* INT_LDO_VMON register field definition */
+#define TPS65224_BIT_LDO1_UVOV_INT BIT(0)
+#define TPS65224_BIT_LDO2_UVOV_INT BIT(1)
+#define TPS65224_BIT_LDO3_UVOV_INT BIT(2)
+#define TPS65224_BIT_VCCA_UVOV_INT BIT(4)
+#define TPS65224_BIT_VMON1_UVOV_INT BIT(5)
+#define TPS65224_BIT_VMON2_UVOV_INT BIT(6)
+
/* INT_LDOX register field definition */
#define TPS6594_BIT_LDOX_OV_INT(ldo_inst) BIT(((ldo_inst) << 2) % 8)
#define TPS6594_BIT_LDOX_UV_INT(ldo_inst) BIT(((ldo_inst) << 2) % 8 + 1)
@@ -462,17 +550,32 @@ enum pmic_id {
/* INT_GPIOX register field definition */
#define TPS6594_BIT_GPIOX_INT(gpio_inst) BIT(gpio_inst)
+/* INT_GPIO register field definition */
+#define TPS65224_BIT_GPIO1_INT BIT(0)
+#define TPS65224_BIT_GPIO2_INT BIT(1)
+#define TPS65224_BIT_GPIO3_INT BIT(2)
+#define TPS65224_BIT_GPIO4_INT BIT(3)
+#define TPS65224_BIT_GPIO5_INT BIT(4)
+#define TPS65224_BIT_GPIO6_INT BIT(5)
+
/* INT_STARTUP register field definition */
#define TPS6594_BIT_NPWRON_START_INT BIT(0)
+#define TPS65224_BIT_VSENSE_INT BIT(0)
#define TPS6594_BIT_ENABLE_INT BIT(1)
#define TPS6594_BIT_RTC_INT BIT(2)
+#define TPS65224_BIT_PB_SHORT_INT BIT(2)
#define TPS6594_BIT_FSD_INT BIT(4)
#define TPS6594_BIT_SOFT_REBOOT_INT BIT(5)
/* INT_MISC register field definition */
#define TPS6594_BIT_BIST_PASS_INT BIT(0)
#define TPS6594_BIT_EXT_CLK_INT BIT(1)
+#define TPS65224_BIT_REG_UNLOCK_INT BIT(2)
#define TPS6594_BIT_TWARN_INT BIT(3)
+#define TPS65224_BIT_PB_LONG_INT BIT(4)
+#define TPS65224_BIT_PB_FALL_INT BIT(5)
+#define TPS65224_BIT_PB_RISE_INT BIT(6)
+#define TPS65224_BIT_ADC_CONV_READY_INT BIT(7)
/* INT_MODERATE_ERR register field definition */
#define TPS6594_BIT_TSD_ORD_INT BIT(0)
@@ -488,6 +591,7 @@ enum pmic_id {
#define TPS6594_BIT_TSD_IMM_INT BIT(0)
#define TPS6594_BIT_VCCA_OVP_INT BIT(1)
#define TPS6594_BIT_PFSM_ERR_INT BIT(2)
+#define TPS65224_BIT_BG_XMON_INT BIT(3)
/* INT_FSM_ERR register field definition */
#define TPS6594_BIT_IMM_SHUTDOWN_INT BIT(0)
@@ -496,6 +600,7 @@ enum pmic_id {
#define TPS6594_BIT_SOC_PWR_ERR_INT BIT(3)
#define TPS6594_BIT_COMM_ERR_INT BIT(4)
#define TPS6594_BIT_READBACK_ERR_INT BIT(5)
+#define TPS65224_BIT_I2C2_ERR_INT BIT(5)
#define TPS6594_BIT_ESM_INT BIT(6)
#define TPS6594_BIT_WD_INT BIT(7)
@@ -536,8 +641,18 @@ enum pmic_id {
#define TPS6594_BIT_VMON2_OV_STAT BIT(5)
#define TPS6594_BIT_VMON2_UV_STAT BIT(6)
+/* STAT_LDO_VMON register field definition */
+#define TPS65224_BIT_LDO1_UVOV_STAT BIT(0)
+#define TPS65224_BIT_LDO2_UVOV_STAT BIT(1)
+#define TPS65224_BIT_LDO3_UVOV_STAT BIT(2)
+#define TPS65224_BIT_VCCA_UVOV_STAT BIT(4)
+#define TPS65224_BIT_VMON1_UVOV_STAT BIT(5)
+#define TPS65224_BIT_VMON2_UVOV_STAT BIT(6)
+
/* STAT_STARTUP register field definition */
+#define TPS65224_BIT_VSENSE_STAT BIT(0)
#define TPS6594_BIT_ENABLE_STAT BIT(1)
+#define TPS65224_BIT_PB_LEVEL_STAT BIT(2)
/* STAT_MISC register field definition */
#define TPS6594_BIT_EXT_CLK_STAT BIT(1)
@@ -549,6 +664,7 @@ enum pmic_id {
/* STAT_SEVERE_ERR register field definition */
#define TPS6594_BIT_TSD_IMM_STAT BIT(0)
#define TPS6594_BIT_VCCA_OVP_STAT BIT(1)
+#define TPS65224_BIT_BG_XMON_STAT BIT(3)
/* STAT_READBACK_ERR register field definition */
#define TPS6594_BIT_EN_DRV_READBACK_STAT BIT(0)
@@ -597,6 +713,8 @@ enum pmic_id {
#define TPS6594_BIT_BB_CHARGER_EN BIT(0)
#define TPS6594_BIT_BB_ICHR BIT(1)
#define TPS6594_MASK_BB_VEOC GENMASK(3, 2)
+#define TPS65224_BIT_I2C1_SPI_CRC_EN BIT(4)
+#define TPS65224_BIT_I2C2_CRC_EN BIT(5)
#define TPS6594_BB_EOC_RDY BIT(7)
/* ENABLE_DRV_REG register field definition */
@@ -617,6 +735,7 @@ enum pmic_id {
#define TPS6594_BIT_NRSTOUT_SOC_IN BIT(2)
#define TPS6594_BIT_FORCE_EN_DRV_LOW BIT(3)
#define TPS6594_BIT_SPMI_LPM_EN BIT(4)
+#define TPS65224_BIT_TSD_DISABLE BIT(5)
/* RECOV_CNT_REG_1 register field definition */
#define TPS6594_MASK_RECOV_CNT GENMASK(3, 0)
@@ -671,15 +790,27 @@ enum pmic_id {
/* ESM_SOC_START_REG register field definition */
#define TPS6594_BIT_ESM_SOC_START BIT(0)
+/* ESM_MCU_START_REG register field definition */
+#define TPS65224_BIT_ESM_MCU_START BIT(0)
+
/* ESM_SOC_MODE_CFG register field definition */
#define TPS6594_MASK_ESM_SOC_ERR_CNT_TH GENMASK(3, 0)
#define TPS6594_BIT_ESM_SOC_ENDRV BIT(5)
#define TPS6594_BIT_ESM_SOC_EN BIT(6)
#define TPS6594_BIT_ESM_SOC_MODE BIT(7)
+/* ESM_MCU_MODE_CFG register field definition */
+#define TPS65224_MASK_ESM_MCU_ERR_CNT_TH GENMASK(3, 0)
+#define TPS65224_BIT_ESM_MCU_ENDRV BIT(5)
+#define TPS65224_BIT_ESM_MCU_EN BIT(6)
+#define TPS65224_BIT_ESM_MCU_MODE BIT(7)
+
/* ESM_SOC_ERR_CNT_REG register field definition */
#define TPS6594_MASK_ESM_SOC_ERR_CNT GENMASK(4, 0)
+/* ESM_MCU_ERR_CNT_REG register field definition */
+#define TPS6594_MASK_ESM_MCU_ERR_CNT GENMASK(4, 0)
+
/* REGISTER_LOCK register field definition */
#define TPS6594_BIT_REGISTER_LOCK_STATUS BIT(0)
@@ -687,6 +818,29 @@ enum pmic_id {
#define TPS6594_MASK_VMON1_SLEW_RATE GENMASK(2, 0)
#define TPS6594_MASK_VMON2_SLEW_RATE GENMASK(5, 3)
+/* SRAM_ACCESS_1 Register field definition */
+#define TPS65224_MASk_SRAM_UNLOCK_SEQ GENMASK(7, 0)
+
+/* SRAM_ACCESS_2 Register field definition */
+#define TPS65224_BIT_SRAM_WRITE_MODE BIT(0)
+#define TPS65224_BIT_OTP_PROG_USER BIT(1)
+#define TPS65224_BIT_OTP_PROG_PFSM BIT(2)
+#define TPS65224_BIT_OTP_PROG_STATUS BIT(3)
+#define TPS65224_BIT_SRAM_UNLOCKED BIT(6)
+#define TPS65224_USER_PROG_ALLOWED BIT(7)
+
+/* SRAM_ADDR_CTRL Register field definition */
+#define TPS65224_MASk_SRAM_SEL GENMASK(1, 0)
+
+/* RECOV_CNT_PFSM_INCR Register field definition */
+#define TPS65224_BIT_INCREMENT_RECOV_CNT BIT(0)
+
+/* MANUFACTURING_VER Register field definition */
+#define TPS65224_MASK_SILICON_REV GENMASK(7, 0)
+
+/* CUSTOMER_NVM_ID_REG Register field definition */
+#define TPS65224_MASK_CUSTOMER_NVM_ID GENMASK(7, 0)
+
/* SOFT_REBOOT_REG register field definition */
#define TPS6594_BIT_SOFT_REBOOT BIT(0)
@@ -755,14 +909,83 @@ enum pmic_id {
#define TPS6594_BIT_I2C2_CRC_EN BIT(2)
#define TPS6594_MASK_T_CRC GENMASK(7, 3)
+/* ADC_CTRL Register field definition */
+#define TPS65224_BIT_ADC_START BIT(0)
+#define TPS65224_BIT_ADC_CONT_CONV BIT(1)
+#define TPS65224_BIT_ADC_THERMAL_SEL BIT(2)
+#define TPS65224_BIT_ADC_RDIV_EN BIT(3)
+#define TPS65224_BIT_ADC_STATUS BIT(7)
+
+/* ADC_RESULT_REG_1 Register field definition */
+#define TPS65224_MASK_ADC_RESULT_11_4 GENMASK(7, 0)
+
+/* ADC_RESULT_REG_2 Register field definition */
+#define TPS65224_MASK_ADC_RESULT_3_0 GENMASK(7, 4)
+
+/* STARTUP_CTRL Register field definition */
+#define TPS65224_MASK_STARTUP_DEST GENMASK(6, 5)
+#define TPS65224_BIT_FIRST_STARTUP_DONE BIT(7)
+
+/* SCRATCH_PAD_REG_1 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_1 GENMASK(7, 0)
+
+/* SCRATCH_PAD_REG_2 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_2 GENMASK(7, 0)
+
+/* SCRATCH_PAD_REG_3 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_3 GENMASK(7, 0)
+
+/* SCRATCH_PAD_REG_4 Register field definition */
+#define TPS6594_MASK_SCRATCH_PAD_4 GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_1 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY1 GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_2 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY2 GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_3 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY3 GENMASK(7, 0)
+
+/* PFSM_DELAY_REG_4 Register field definition */
+#define TPS6594_MASK_PFSM_DELAY4 GENMASK(7, 0)
+
+/* CRC_CALC_CONTROL Register field definition */
+#define TPS65224_BIT_RUN_CRC_BIST BIT(0)
+#define TPS65224_BIT_RUN_CRC_UPDATE BIT(1)
+
+/* ADC_GAIN_COMP_REG Register field definition */
+#define TPS65224_MASK_ADC_GAIN_COMP GENMASK(7, 0)
+
+/* REGMAP_USER_CRC_LOW Register field definition */
+#define TPS65224_MASK_REGMAP_USER_CRC16_LOW GENMASK(7, 0)
+
+/* REGMAP_USER_CRC_HIGH Register field definition */
+#define TPS65224_MASK_REGMAP_USER_CRC16_HIGH GENMASK(7, 0)
+
+/* WD_ANSWER_REG Register field definition */
+#define TPS6594_MASK_WD_ANSWER GENMASK(7, 0)
+
/* WD_QUESTION_ANSW_CNT register field definition */
#define TPS6594_MASK_WD_QUESTION GENMASK(3, 0)
#define TPS6594_MASK_WD_ANSW_CNT GENMASK(5, 4)
+#define TPS65224_BIT_INT_TOP_STATUS BIT(7)
+
+/* WD WIN1_CFG register field definition */
+#define TPS6594_MASK_WD_WIN1_CFG GENMASK(6, 0)
+
+/* WD WIN2_CFG register field definition */
+#define TPS6594_MASK_WD_WIN2_CFG GENMASK(6, 0)
+
+/* WD LongWin register field definition */
+#define TPS6594_MASK_WD_LONGWIN_CFG GENMASK(7, 0)
/* WD_MODE_REG register field definition */
#define TPS6594_BIT_WD_RETURN_LONGWIN BIT(0)
#define TPS6594_BIT_WD_MODE_SELECT BIT(1)
#define TPS6594_BIT_WD_PWRHOLD BIT(2)
+#define TPS65224_BIT_WD_ENDRV_SEL BIT(6)
+#define TPS65224_BIT_WD_CNT_SEL BIT(7)
/* WD_QA_CFG register field definition */
#define TPS6594_MASK_WD_QUESTION_SEED GENMASK(3, 0)
@@ -993,6 +1216,106 @@ enum tps6594_irqs {
#define TPS6594_IRQ_NAME_ALARM "alarm"
#define TPS6594_IRQ_NAME_POWERUP "powerup"
+/* IRQs */
+enum tps65224_irqs {
+ /* INT_BUCK register */
+ TPS65224_IRQ_BUCK1_UVOV,
+ TPS65224_IRQ_BUCK2_UVOV,
+ TPS65224_IRQ_BUCK3_UVOV,
+ TPS65224_IRQ_BUCK4_UVOV,
+ /* INT_LDO_VMON register */
+ TPS65224_IRQ_LDO1_UVOV,
+ TPS65224_IRQ_LDO2_UVOV,
+ TPS65224_IRQ_LDO3_UVOV,
+ TPS65224_IRQ_VCCA_UVOV,
+ TPS65224_IRQ_VMON1_UVOV,
+ TPS65224_IRQ_VMON2_UVOV,
+ /* INT_GPIO register */
+ TPS65224_IRQ_GPIO1,
+ TPS65224_IRQ_GPIO2,
+ TPS65224_IRQ_GPIO3,
+ TPS65224_IRQ_GPIO4,
+ TPS65224_IRQ_GPIO5,
+ TPS65224_IRQ_GPIO6,
+ /* INT_STARTUP register */
+ TPS65224_IRQ_VSENSE,
+ TPS65224_IRQ_ENABLE,
+ TPS65224_IRQ_PB_SHORT,
+ TPS65224_IRQ_FSD,
+ TPS65224_IRQ_SOFT_REBOOT,
+ /* INT_MISC register */
+ TPS65224_IRQ_BIST_PASS,
+ TPS65224_IRQ_EXT_CLK,
+ TPS65224_IRQ_REG_UNLOCK,
+ TPS65224_IRQ_TWARN,
+ TPS65224_IRQ_PB_LONG,
+ TPS65224_IRQ_PB_FALL,
+ TPS65224_IRQ_PB_RISE,
+ TPS65224_IRQ_ADC_CONV_READY,
+ /* INT_MODERATE_ERR register */
+ TPS65224_IRQ_TSD_ORD,
+ TPS65224_IRQ_BIST_FAIL,
+ TPS65224_IRQ_REG_CRC_ERR,
+ TPS65224_IRQ_RECOV_CNT,
+ /* INT_SEVERE_ERR register */
+ TPS65224_IRQ_TSD_IMM,
+ TPS65224_IRQ_VCCA_OVP,
+ TPS65224_IRQ_PFSM_ERR,
+ TPS65224_IRQ_BG_XMON,
+ /* INT_FSM_ERR register */
+ TPS65224_IRQ_IMM_SHUTDOWN,
+ TPS65224_IRQ_ORD_SHUTDOWN,
+ TPS65224_IRQ_MCU_PWR_ERR,
+ TPS65224_IRQ_SOC_PWR_ERR,
+ TPS65224_IRQ_COMM_ERR,
+ TPS65224_IRQ_I2C2_ERR,
+};
+
+#define TPS65224_IRQ_NAME_BUCK1_UVOV "buck1_uvov"
+#define TPS65224_IRQ_NAME_BUCK2_UVOV "buck2_uvov"
+#define TPS65224_IRQ_NAME_BUCK3_UVOV "buck3_uvov"
+#define TPS65224_IRQ_NAME_BUCK4_UVOV "buck4_uvov"
+#define TPS65224_IRQ_NAME_LDO1_UVOV "ldo1_uvov"
+#define TPS65224_IRQ_NAME_LDO2_UVOV "ldo2_uvov"
+#define TPS65224_IRQ_NAME_LDO3_UVOV "ldo3_uvov"
+#define TPS65224_IRQ_NAME_VCCA_UVOV "vcca_uvov"
+#define TPS65224_IRQ_NAME_VMON1_UVOV "vmon1_uvov"
+#define TPS65224_IRQ_NAME_VMON2_UVOV "vmon2_uvov"
+#define TPS65224_IRQ_NAME_GPIO1 "gpio1"
+#define TPS65224_IRQ_NAME_GPIO2 "gpio2"
+#define TPS65224_IRQ_NAME_GPIO3 "gpio3"
+#define TPS65224_IRQ_NAME_GPIO4 "gpio4"
+#define TPS65224_IRQ_NAME_GPIO5 "gpio5"
+#define TPS65224_IRQ_NAME_GPIO6 "gpio6"
+#define TPS65224_IRQ_NAME_VSENSE "vsense"
+#define TPS65224_IRQ_NAME_ENABLE "enable"
+#define TPS65224_IRQ_NAME_PB_SHORT "pb_short"
+#define TPS65224_IRQ_NAME_FSD "fsd"
+#define TPS65224_IRQ_NAME_SOFT_REBOOT "soft_reboot"
+#define TPS65224_IRQ_NAME_BIST_PASS "bist_pass"
+#define TPS65224_IRQ_NAME_EXT_CLK "ext_clk"
+#define TPS65224_IRQ_NAME_REG_UNLOCK "reg_unlock"
+#define TPS65224_IRQ_NAME_TWARN "twarn"
+#define TPS65224_IRQ_NAME_PB_LONG "pb_long"
+#define TPS65224_IRQ_NAME_PB_FALL "pb_fall"
+#define TPS65224_IRQ_NAME_PB_RISE "pb_rise"
+#define TPS65224_IRQ_NAME_ADC_CONV_READY "adc_conv_ready"
+#define TPS65224_IRQ_NAME_TSD_ORD "tsd_ord"
+#define TPS65224_IRQ_NAME_BIST_FAIL "bist_fail"
+#define TPS65224_IRQ_NAME_REG_CRC_ERR "reg_crc_err"
+#define TPS65224_IRQ_NAME_RECOV_CNT "recov_cnt"
+#define TPS65224_IRQ_NAME_TSD_IMM "tsd_imm"
+#define TPS65224_IRQ_NAME_VCCA_OVP "vcca_ovp"
+#define TPS65224_IRQ_NAME_PFSM_ERR "pfsm_err"
+#define TPS65224_IRQ_NAME_BG_XMON "bg_xmon"
+#define TPS65224_IRQ_NAME_IMM_SHUTDOWN "imm_shutdown"
+#define TPS65224_IRQ_NAME_ORD_SHUTDOWN "ord_shutdown"
+#define TPS65224_IRQ_NAME_MCU_PWR_ERR "mcu_pwr_err"
+#define TPS65224_IRQ_NAME_SOC_PWR_ERR "soc_pwr_err"
+#define TPS65224_IRQ_NAME_COMM_ERR "comm_err"
+#define TPS65224_IRQ_NAME_I2C2_ERR "i2c2_err"
+#define TPS65224_IRQ_NAME_POWERUP "powerup"
+
/**
* struct tps6594 - device private data structure
*
--
2.25.1
^ permalink raw reply related
* [PATCH v6 02/11] mfd: tps6594: use volatile_table instead of volatile_reg
From: Bhargav Raviprakash @ 2024-04-08 12:40 UTC (permalink / raw)
To: linux-kernel
Cc: m.nirmaladevi, lee, robh+dt, krzysztof.kozlowski+dt, conor+dt,
jpanis, devicetree, arnd, gregkh, lgirdwood, broonie,
linus.walleij, linux-gpio, linux-arm-kernel, nm, vigneshr, kristo,
eblanc, Bhargav Raviprakash
In-Reply-To: <20240408124047.191895-1-bhargav.r@ltts.com>
In regmap_config use volatile_table instead of volatile_reg. This change
makes it easier to add support for TPS65224 PMIC.
Signed-off-by: Bhargav Raviprakash <bhargav.r@ltts.com>
Acked-by: Julien Panis <jpanis@baylibre.com>
---
drivers/mfd/tps6594-core.c | 16 ++++++++++------
drivers/mfd/tps6594-i2c.c | 2 +-
drivers/mfd/tps6594-spi.c | 2 +-
include/linux/mfd/tps6594.h | 4 +++-
4 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/mfd/tps6594-core.c b/drivers/mfd/tps6594-core.c
index 783ee5990..089ab8cc8 100644
--- a/drivers/mfd/tps6594-core.c
+++ b/drivers/mfd/tps6594-core.c
@@ -319,12 +319,16 @@ static struct regmap_irq_chip tps6594_irq_chip = {
.handle_post_irq = tps6594_handle_post_irq,
};
-bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg)
-{
- return (reg >= TPS6594_REG_INT_TOP && reg <= TPS6594_REG_STAT_READBACK_ERR) ||
- reg == TPS6594_REG_RTC_STATUS;
-}
-EXPORT_SYMBOL_GPL(tps6594_is_volatile_reg);
+static const struct regmap_range tps6594_volatile_ranges[] = {
+ regmap_reg_range(TPS6594_REG_INT_TOP, TPS6594_REG_STAT_READBACK_ERR),
+ regmap_reg_range(TPS6594_REG_RTC_STATUS, TPS6594_REG_RTC_STATUS),
+};
+
+const struct regmap_access_table tps6594_volatile_table = {
+ .yes_ranges = tps6594_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(tps6594_volatile_ranges),
+};
+EXPORT_SYMBOL_GPL(tps6594_volatile_table);
static int tps6594_check_crc_mode(struct tps6594 *tps, bool primary_pmic)
{
diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c
index 899c88c0f..c125b474b 100644
--- a/drivers/mfd/tps6594-i2c.c
+++ b/drivers/mfd/tps6594-i2c.c
@@ -187,7 +187,7 @@ static const struct regmap_config tps6594_i2c_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
- .volatile_reg = tps6594_is_volatile_reg,
+ .volatile_table = &tps6594_volatile_table,
.read = tps6594_i2c_read,
.write = tps6594_i2c_write,
};
diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
index 24b72847e..5afb1736f 100644
--- a/drivers/mfd/tps6594-spi.c
+++ b/drivers/mfd/tps6594-spi.c
@@ -70,7 +70,7 @@ static const struct regmap_config tps6594_spi_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
- .volatile_reg = tps6594_is_volatile_reg,
+ .volatile_table = &tps6594_volatile_table,
.reg_read = tps6594_spi_reg_read,
.reg_write = tps6594_spi_reg_write,
.use_single_read = true,
diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h
index e754c01ac..16543fd4d 100644
--- a/include/linux/mfd/tps6594.h
+++ b/include/linux/mfd/tps6594.h
@@ -1337,7 +1337,9 @@ struct tps6594 {
struct regmap_irq_chip_data *irq_data;
};
-bool tps6594_is_volatile_reg(struct device *dev, unsigned int reg);
+extern const struct regmap_access_table tps6594_volatile_table;
+extern const struct regmap_access_table tps65224_volatile_table;
+
int tps6594_device_init(struct tps6594 *tps, bool enable_crc);
#endif /* __LINUX_MFD_TPS6594_H */
--
2.25.1
^ permalink raw reply related
* [PATCH v6 03/11] mfd: tps6594: add regmap config in match data
From: Bhargav Raviprakash @ 2024-04-08 12:40 UTC (permalink / raw)
To: linux-kernel
Cc: m.nirmaladevi, lee, robh+dt, krzysztof.kozlowski+dt, conor+dt,
jpanis, devicetree, arnd, gregkh, lgirdwood, broonie,
linus.walleij, linux-gpio, linux-arm-kernel, nm, vigneshr, kristo,
eblanc, Bhargav Raviprakash
In-Reply-To: <20240408124047.191895-1-bhargav.r@ltts.com>
Introduces a new struct tps6594_match_data. This struct holds fields for
chip id and regmap config. Using this struct in of_device_id data field.
This helps in adding support for TPS65224 PMIC.
Signed-off-by: Bhargav Raviprakash <bhargav.r@ltts.com>
Acked-by: Julien Panis <jpanis@baylibre.com>
---
drivers/mfd/tps6594-i2c.c | 24 ++++++++++++++++--------
drivers/mfd/tps6594-spi.c | 24 ++++++++++++++++--------
include/linux/mfd/tps6594.h | 11 +++++++++++
3 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c
index c125b474b..9e2ed48b7 100644
--- a/drivers/mfd/tps6594-i2c.c
+++ b/drivers/mfd/tps6594-i2c.c
@@ -192,10 +192,16 @@ static const struct regmap_config tps6594_i2c_regmap_config = {
.write = tps6594_i2c_write,
};
+static const struct tps6594_match_data match_data[] = {
+ [TPS6594] = {TPS6594, &tps6594_i2c_regmap_config},
+ [TPS6593] = {TPS6593, &tps6594_i2c_regmap_config},
+ [LP8764] = {LP8764, &tps6594_i2c_regmap_config},
+};
+
static const struct of_device_id tps6594_i2c_of_match_table[] = {
- { .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
- { .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
- { .compatible = "ti,lp8764-q1", .data = (void *)LP8764, },
+ { .compatible = "ti,tps6594-q1", .data = &match_data[TPS6594], },
+ { .compatible = "ti,tps6593-q1", .data = &match_data[TPS6593], },
+ { .compatible = "ti,lp8764-q1", .data = &match_data[LP8764], },
{}
};
MODULE_DEVICE_TABLE(of, tps6594_i2c_of_match_table);
@@ -205,6 +211,7 @@ static int tps6594_i2c_probe(struct i2c_client *client)
struct device *dev = &client->dev;
struct tps6594 *tps;
const struct of_device_id *match;
+ const struct tps6594_match_data *mdata;
tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
@@ -216,14 +223,15 @@ static int tps6594_i2c_probe(struct i2c_client *client)
tps->reg = client->addr;
tps->irq = client->irq;
- tps->regmap = devm_regmap_init(dev, NULL, client, &tps6594_i2c_regmap_config);
- if (IS_ERR(tps->regmap))
- return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
-
match = of_match_device(tps6594_i2c_of_match_table, dev);
if (!match)
return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
- tps->chip_id = (unsigned long)match->data;
+ mdata = (struct tps6594_match_data *)match->data;
+ tps->chip_id = mdata->chip_id;
+
+ tps->regmap = devm_regmap_init(dev, NULL, client, mdata->config);
+ if (IS_ERR(tps->regmap))
+ return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
crc8_populate_msb(tps6594_i2c_crc_table, TPS6594_CRC8_POLYNOMIAL);
diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
index 5afb1736f..82a1c02e3 100644
--- a/drivers/mfd/tps6594-spi.c
+++ b/drivers/mfd/tps6594-spi.c
@@ -77,10 +77,16 @@ static const struct regmap_config tps6594_spi_regmap_config = {
.use_single_write = true,
};
+static const struct tps6594_match_data match_data[] = {
+ [TPS6594] = {TPS6594, &tps6594_spi_regmap_config},
+ [TPS6593] = {TPS6593, &tps6594_spi_regmap_config},
+ [LP8764] = {LP8764, &tps6594_spi_regmap_config},
+};
+
static const struct of_device_id tps6594_spi_of_match_table[] = {
- { .compatible = "ti,tps6594-q1", .data = (void *)TPS6594, },
- { .compatible = "ti,tps6593-q1", .data = (void *)TPS6593, },
- { .compatible = "ti,lp8764-q1", .data = (void *)LP8764, },
+ { .compatible = "ti,tps6594-q1", .data = &match_data[TPS6594], },
+ { .compatible = "ti,tps6593-q1", .data = &match_data[TPS6593], },
+ { .compatible = "ti,lp8764-q1", .data = &match_data[LP8764], },
{}
};
MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);
@@ -90,6 +96,7 @@ static int tps6594_spi_probe(struct spi_device *spi)
struct device *dev = &spi->dev;
struct tps6594 *tps;
const struct of_device_id *match;
+ const struct tps6594_match_data *mdata;
tps = devm_kzalloc(dev, sizeof(*tps), GFP_KERNEL);
if (!tps)
@@ -101,14 +108,15 @@ static int tps6594_spi_probe(struct spi_device *spi)
tps->reg = spi_get_chipselect(spi, 0);
tps->irq = spi->irq;
- tps->regmap = devm_regmap_init(dev, NULL, spi, &tps6594_spi_regmap_config);
- if (IS_ERR(tps->regmap))
- return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
-
match = of_match_device(tps6594_spi_of_match_table, dev);
if (!match)
return dev_err_probe(dev, -EINVAL, "Failed to find matching chip ID\n");
- tps->chip_id = (unsigned long)match->data;
+ mdata = (struct tps6594_match_data *)match->data;
+ tps->chip_id = mdata->chip_id;
+
+ tps->regmap = devm_regmap_init(dev, NULL, spi, mdata->config);
+ if (IS_ERR(tps->regmap))
+ return dev_err_probe(dev, PTR_ERR(tps->regmap), "Failed to init regmap\n");
crc8_populate_msb(tps6594_spi_crc_table, TPS6594_CRC8_POLYNOMIAL);
diff --git a/include/linux/mfd/tps6594.h b/include/linux/mfd/tps6594.h
index 16543fd4d..d781e0fe3 100644
--- a/include/linux/mfd/tps6594.h
+++ b/include/linux/mfd/tps6594.h
@@ -1337,6 +1337,17 @@ struct tps6594 {
struct regmap_irq_chip_data *irq_data;
};
+/**
+ * struct tps6594_match_data - of match data of PMIC
+ *
+ * @chip_id: chip ID of PMIC
+ * @config: regmap config of PMIC
+ */
+struct tps6594_match_data {
+ unsigned long chip_id;
+ const struct regmap_config *config;
+};
+
extern const struct regmap_access_table tps6594_volatile_table;
extern const struct regmap_access_table tps65224_volatile_table;
--
2.25.1
^ permalink raw reply related
* [PATCH v6 05/11] mfd: tps6594-i2c: Add TI TPS65224 PMIC I2C
From: Bhargav Raviprakash @ 2024-04-08 12:40 UTC (permalink / raw)
To: linux-kernel
Cc: m.nirmaladevi, lee, robh+dt, krzysztof.kozlowski+dt, conor+dt,
jpanis, devicetree, arnd, gregkh, lgirdwood, broonie,
linus.walleij, linux-gpio, linux-arm-kernel, nm, vigneshr, kristo,
eblanc, Bhargav Raviprakash
In-Reply-To: <20240408124047.191895-1-bhargav.r@ltts.com>
Add support for TPS65224 PMIC in TPS6594's I2C driver which has
significant functional overlap.
Signed-off-by: Bhargav Raviprakash <bhargav.r@ltts.com>
Acked-by: Julien Panis <jpanis@baylibre.com>
---
drivers/mfd/tps6594-i2c.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/mfd/tps6594-i2c.c b/drivers/mfd/tps6594-i2c.c
index 9e2ed48b7..0d741da74 100644
--- a/drivers/mfd/tps6594-i2c.c
+++ b/drivers/mfd/tps6594-i2c.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * I2C access driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * I2C access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
*
* Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
*/
@@ -192,16 +192,27 @@ static const struct regmap_config tps6594_i2c_regmap_config = {
.write = tps6594_i2c_write,
};
+static const struct regmap_config tps65224_i2c_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
+ .volatile_table = &tps65224_volatile_table,
+ .read = tps6594_i2c_read,
+ .write = tps6594_i2c_write,
+};
+
static const struct tps6594_match_data match_data[] = {
[TPS6594] = {TPS6594, &tps6594_i2c_regmap_config},
[TPS6593] = {TPS6593, &tps6594_i2c_regmap_config},
[LP8764] = {LP8764, &tps6594_i2c_regmap_config},
+ [TPS65224] = {TPS65224, &tps65224_i2c_regmap_config},
};
static const struct of_device_id tps6594_i2c_of_match_table[] = {
{ .compatible = "ti,tps6594-q1", .data = &match_data[TPS6594], },
{ .compatible = "ti,tps6593-q1", .data = &match_data[TPS6593], },
{ .compatible = "ti,lp8764-q1", .data = &match_data[LP8764], },
+ { .compatible = "ti,tps65224-q1", .data = &match_data[TPS65224], },
{}
};
MODULE_DEVICE_TABLE(of, tps6594_i2c_of_match_table);
@@ -248,5 +259,5 @@ static struct i2c_driver tps6594_i2c_driver = {
module_i2c_driver(tps6594_i2c_driver);
MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
-MODULE_DESCRIPTION("TPS6594 I2C Interface Driver");
+MODULE_DESCRIPTION("I2C Interface Driver for TPS65224, TPS6594/3, and LP8764");
MODULE_LICENSE("GPL");
--
2.25.1
^ permalink raw reply related
* [PATCH v6 06/11] mfd: tps6594-spi: Add TI TPS65224 PMIC SPI
From: Bhargav Raviprakash @ 2024-04-08 12:40 UTC (permalink / raw)
To: linux-kernel
Cc: m.nirmaladevi, lee, robh+dt, krzysztof.kozlowski+dt, conor+dt,
jpanis, devicetree, arnd, gregkh, lgirdwood, broonie,
linus.walleij, linux-gpio, linux-arm-kernel, nm, vigneshr, kristo,
eblanc, Bhargav Raviprakash
In-Reply-To: <20240408124047.191895-1-bhargav.r@ltts.com>
Add support for TPS65224 PMIC in TPS6594's SPI driver which has
significant functional overlap.
Signed-off-by: Bhargav Raviprakash <bhargav.r@ltts.com>
Acked-by: Julien Panis <jpanis@baylibre.com>
---
drivers/mfd/tps6594-spi.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/mfd/tps6594-spi.c b/drivers/mfd/tps6594-spi.c
index 82a1c02e3..a9cdc524f 100644
--- a/drivers/mfd/tps6594-spi.c
+++ b/drivers/mfd/tps6594-spi.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * SPI access driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * SPI access driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
*
* Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
*/
@@ -77,16 +77,29 @@ static const struct regmap_config tps6594_spi_regmap_config = {
.use_single_write = true,
};
+static const struct regmap_config tps65224_spi_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = TPS6594_REG_DWD_FAIL_CNT_REG,
+ .volatile_table = &tps65224_volatile_table,
+ .reg_read = tps6594_spi_reg_read,
+ .reg_write = tps6594_spi_reg_write,
+ .use_single_read = true,
+ .use_single_write = true,
+};
+
static const struct tps6594_match_data match_data[] = {
[TPS6594] = {TPS6594, &tps6594_spi_regmap_config},
[TPS6593] = {TPS6593, &tps6594_spi_regmap_config},
[LP8764] = {LP8764, &tps6594_spi_regmap_config},
+ [TPS65224] = {TPS65224, &tps65224_spi_regmap_config},
};
static const struct of_device_id tps6594_spi_of_match_table[] = {
{ .compatible = "ti,tps6594-q1", .data = &match_data[TPS6594], },
{ .compatible = "ti,tps6593-q1", .data = &match_data[TPS6593], },
{ .compatible = "ti,lp8764-q1", .data = &match_data[LP8764], },
+ { .compatible = "ti,tps65224-q1", .data = &match_data[TPS65224],},
{}
};
MODULE_DEVICE_TABLE(of, tps6594_spi_of_match_table);
@@ -133,5 +146,5 @@ static struct spi_driver tps6594_spi_driver = {
module_spi_driver(tps6594_spi_driver);
MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>");
-MODULE_DESCRIPTION("TPS6594 SPI Interface Driver");
+MODULE_DESCRIPTION("SPI Interface Driver for TPS65224, TPS6594/3, and LP8764");
MODULE_LICENSE("GPL");
--
2.25.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox