Re: [PATCH v3 05/11] drm/bridge: Add Analogix anx6345 support

2019-02-25 Thread Andrzej Hajda
On 15.02.2019 20:36, Vasily Khoruzhick wrote:
> On Fri, Feb 15, 2019 at 1:13 AM Andrzej Hajda  wrote:
>
> Hi Andrzej,
>
> Thanks for review!
>
>>> +#include 
>> Do you need this header?
> I'll drop it.
>
>>> +#include 
>> drmP.h is/should be deprecated.
> Same here
>
>>> +struct anx6345_platform_data {
>>> + struct regulator *dvdd12;
>>> + struct regulator *dvdd25;
>>> + struct gpio_desc *gpiod_reset;
>>> +};
>> Why do you need this struct, why just do not embed it's fields directly
>> into struct anx6345 ?
> OK, I'll embed it into struct anx6345
>
>>> + if (WARN_ON(anx6345->powered))
>>> + return;
>> It should not happen, you can remove this warn.
> OK
>
>>> + if (pdata->dvdd12) {
>> If regulators are required this will be never null.
> Right, and regulator subsystem will return dummy regulator if it's
> missing in dts.
> I'll remove redundant checks.
>
>>> +
>>> + if (pdata->dvdd25) {
>> ditto
> OK
>
>>> +
>>> + if (anx6345->panel)
>>> + drm_panel_prepare(anx6345->panel);
>> again, here and below: panel is never null, check can be removed.
> That's not true, panel is optional. It can be DP connector, not a panel.
>
>>> +
>>> + gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
>>> + usleep_range(1000, 2000);
>>> +
>>> + gpiod_set_value_cansleep(pdata->gpiod_reset, 1);
>>
>> Start/stop sequence seems odd regarding reset gpio:
>>
>> 1. In probe reset is set to low, in poweroff to high - incosistent.
>>
>> 2. If in case of disabled device reset should be 0, there is no point to
>> set it again to 0 three lines above.
>>
>> 3. I suspect in dts reset gpio should be declared as active_low, and the
>> logic in the driver should be reverted, in power off it should be set to
>> high, in power on it should be lowered (logically).
> OK, I'll look into it.
>
>>> +err_poweroff:
>>> + DRM_ERROR("Failed DisplayPort transmitter initialization: %d\n", err);
>> redundant message
> OK, will drop.
>
>>> + DRM_ERROR("Get sink count failed %d\n", err);
>> The rule of thumb I heard is that if you start message capitalized you
>> should end with dot. Since I do not know if it is enforced in kernel I
>> leave the decision up to you.
> I grepped DRM_ERROR in driver/gpu/drm and they do exactly the same as here.
> So I'll just keep it as is for consistency.
>
>>> +static bool anx6345_bridge_mode_fixup(struct drm_bridge *bridge,
>>> +   const struct drm_display_mode *mode,
>>> +   struct drm_display_mode *adjusted_mode)
>>> +{
>>> + if (mode->flags & DRM_MODE_FLAG_INTERLACE)
>>> + return false;
>>> +
>>> + /* Max 1200p at 5.4 Ghz, one lane */
>>> + if (mode->clock > 154000)
>>> + return false;
>> These checks should be in mode_valid callback.
> OK
>
>>> + /* Map slave addresses of ANX6345 */
>>> + for (i = 0; i < I2C_NUM_ADDRESSES; i++) {
>>> + if (anx6345_i2c_addresses[i] >> 1 != client->addr)
>>> + anx6345->i2c_clients[i] = 
>>> i2c_new_dummy(client->adapter,
>>> + anx6345_i2c_addresses[i] >> 
>>> 1);
>>> + else
>>> + anx6345->i2c_clients[i] = client;
>>
>> I see this contredanse is copy/pasted from anx78*, but it looks quite
>> complicated. As I understand there are two i2c addresses, why we cannot
>> assume one address is for control interfaces and another  is dummy? It would
>> simplify the code here and in other places.
> Sorry, I don't get you, could you elaborate? Note that anx6345 uses
> both addresses,
> i2c_new_dummy() just registers new i2c device bound to a dummy driver and it's
> supposed to be used for devices that consume more than one i2c address.


My idea was to assume that ANALOGIX_I2C_DPTX is the main address, ie.
address which should be set in dts in device node reg property.

Other addresses should be registered as dummy devices during probe -
simple loop without conditionals, without redundant fields in anx6345
context - i2c_clients, client.

I do not insist on this change but I suggest as it should simplify the code.

And moreover, you can consider removing direction bit from i2c
addresses, it could be also confusing and against i2c kernel api.

>
>>> + if (!found) {
>>> + DRM_ERROR("ANX%x (ver. %d) not supported by this driver\n",
>>> +   anx6345->chipid, version);
>>> + err = -ENODEV;
>>> + goto err_poweroff;
>>> + }
>>
>> As I see chip becomes powered forever, is it OK? Usually it should be
>> powered only when pipeline starts, and powered-off after pipeline stops.
> I'll look into how hard it would be to implement but personally I
> think it's OK for now.
> We can add more sophisticated power management once this driver is merged.


But the rule is every resource allocated/set during lifetime of the
driver should be dropped on driver removal, so please 

Re: [linux-sunxi] [PATCH v3 05/11] drm/bridge: Add Analogix anx6345 support

2019-02-18 Thread Priit Laes
On Thu, Feb 14, 2019 at 09:09:51PM -0800, Vasily Khoruzhick wrote:
> From: Icenowy Zheng 
> 
> The ANX6345 is an ultra-low power DisplayPower/eDP transmitter designed
> for portable devices. This driver adds initial support for RGB to eDP
> mode, without HPD and interrupts.
> 
> This is a configuration usually seen in eDP applications.
> 
> Signed-off-by: Icenowy Zheng 
> Signed-off-by: Vasily Khoruzhick 
> ---
>  drivers/gpu/drm/bridge/analogix/Kconfig   |  11 +
>  drivers/gpu/drm/bridge/analogix/Makefile  |   1 +
>  .../drm/bridge/analogix/analogix-anx6345.c| 845 ++
>  .../drm/bridge/analogix/analogix-i2c-dptx.c   |   2 +-
>  .../drm/bridge/analogix/analogix-i2c-dptx.h   |   8 +
>  .../bridge/analogix/analogix-i2c-txcommon.h   |   3 +
>  6 files changed, 869 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> 

[ ... ]

> +
> +static int anx6345_start(struct anx6345 *anx6345)
> +{
> + int err;
> +
> + if (!anx6345->powered)
> + anx6345_poweron(anx6345);
> +
> + /* Power on needed modules */
> + err = anx6345_clear_bits(anx6345->map[I2C_IDX_TXCOM],
> +  SP_POWERDOWN_CTRL_REG,
> +  SP_VIDEO_PD | SP_LINK_PD);
> +
> + err = anx6345_tx_initialization(anx6345);
> + if (err) {
> + DRM_ERROR("Failed transmitter initialization: %d\n", err);
> + goto err_poweroff;

You can move the whole err_poweroff section from below here and drop the goto.

> + }
> +
> + /*
> +  * This delay seems to help keep the hardware in a good state. Without
> +  * it, there are times where it fails silently.
> +  */
> + usleep_range(1, 15000);
> +
> + return 0;
> +
> +err_poweroff:
> + DRM_ERROR("Failed DisplayPort transmitter initialization: %d\n", err);
> + anx6345_poweroff(anx6345);
> +
> + return err;
> +}
> +

[ ... ]
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [linux-sunxi] [PATCH v3 05/11] drm/bridge: Add Analogix anx6345 support

2019-02-16 Thread Vasily Khoruzhick via dri-devel
On Fri, Feb 15, 2019 at 12:23 AM Priit Laes  wrote:

> > + err = anx6345_tx_initialization(anx6345);
> > + if (err) {
> > + DRM_ERROR("Failed transmitter initialization: %d\n", err);
> > + goto err_poweroff;
>
> You can move the whole err_poweroff section from below here and drop the goto.

Thanks, will do.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v3 05/11] drm/bridge: Add Analogix anx6345 support

2019-02-16 Thread Vasily Khoruzhick via dri-devel
On Fri, Feb 15, 2019 at 1:13 AM Andrzej Hajda  wrote:

Hi Andrzej,

Thanks for review!

> > +#include 
> Do you need this header?

I'll drop it.

> > +#include 
>
> drmP.h is/should be deprecated.

Same here

> > +struct anx6345_platform_data {
> > + struct regulator *dvdd12;
> > + struct regulator *dvdd25;
> > + struct gpio_desc *gpiod_reset;
> > +};
>
> Why do you need this struct, why just do not embed it's fields directly
> into struct anx6345 ?

OK, I'll embed it into struct anx6345

> > + if (WARN_ON(anx6345->powered))
> > + return;
>
> It should not happen, you can remove this warn.

OK

> > + if (pdata->dvdd12) {
>
> If regulators are required this will be never null.

Right, and regulator subsystem will return dummy regulator if it's
missing in dts.
I'll remove redundant checks.

> > +
> > + if (pdata->dvdd25) {
>
> ditto

OK

> > +
> > + if (anx6345->panel)
> > + drm_panel_prepare(anx6345->panel);
>
> again, here and below: panel is never null, check can be removed.

That's not true, panel is optional. It can be DP connector, not a panel.

> > +
> > + gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
> > + usleep_range(1000, 2000);
> > +
> > + gpiod_set_value_cansleep(pdata->gpiod_reset, 1);
>
>
> Start/stop sequence seems odd regarding reset gpio:
>
> 1. In probe reset is set to low, in poweroff to high - incosistent.
>
> 2. If in case of disabled device reset should be 0, there is no point to
> set it again to 0 three lines above.
>
> 3. I suspect in dts reset gpio should be declared as active_low, and the
> logic in the driver should be reverted, in power off it should be set to
> high, in power on it should be lowered (logically).

OK, I'll look into it.

> > +err_poweroff:
> > + DRM_ERROR("Failed DisplayPort transmitter initialization: %d\n", err);
>
> redundant message

OK, will drop.

> > + DRM_ERROR("Get sink count failed %d\n", err);
>
> The rule of thumb I heard is that if you start message capitalized you
> should end with dot. Since I do not know if it is enforced in kernel I
> leave the decision up to you.

I grepped DRM_ERROR in driver/gpu/drm and they do exactly the same as here.
So I'll just keep it as is for consistency.

> > +static bool anx6345_bridge_mode_fixup(struct drm_bridge *bridge,
> > +   const struct drm_display_mode *mode,
> > +   struct drm_display_mode *adjusted_mode)
> > +{
> > + if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> > + return false;
> > +
> > + /* Max 1200p at 5.4 Ghz, one lane */
> > + if (mode->clock > 154000)
> > + return false;
>
> These checks should be in mode_valid callback.

OK

> > + /* Map slave addresses of ANX6345 */
> > + for (i = 0; i < I2C_NUM_ADDRESSES; i++) {
> > + if (anx6345_i2c_addresses[i] >> 1 != client->addr)
> > + anx6345->i2c_clients[i] = 
> > i2c_new_dummy(client->adapter,
> > + anx6345_i2c_addresses[i] >> 
> > 1);
> > + else
> > + anx6345->i2c_clients[i] = client;
>
>
> I see this contredanse is copy/pasted from anx78*, but it looks quite
> complicated. As I understand there are two i2c addresses, why we cannot
> assume one address is for control interfaces and another  is dummy? It would
> simplify the code here and in other places.

Sorry, I don't get you, could you elaborate? Note that anx6345 uses
both addresses,
i2c_new_dummy() just registers new i2c device bound to a dummy driver and it's
supposed to be used for devices that consume more than one i2c address.

> > + if (!found) {
> > + DRM_ERROR("ANX%x (ver. %d) not supported by this driver\n",
> > +   anx6345->chipid, version);
> > + err = -ENODEV;
> > + goto err_poweroff;
> > + }
>
>
> As I see chip becomes powered forever, is it OK? Usually it should be
> powered only when pipeline starts, and powered-off after pipeline stops.

I'll look into how hard it would be to implement but personally I
think it's OK for now.
We can add more sophisticated power management once this driver is merged.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v3 05/11] drm/bridge: Add Analogix anx6345 support

2019-02-16 Thread Vasily Khoruzhick via dri-devel
From: Icenowy Zheng 

The ANX6345 is an ultra-low power DisplayPower/eDP transmitter designed
for portable devices. This driver adds initial support for RGB to eDP
mode, without HPD and interrupts.

This is a configuration usually seen in eDP applications.

Signed-off-by: Icenowy Zheng 
Signed-off-by: Vasily Khoruzhick 
---
 drivers/gpu/drm/bridge/analogix/Kconfig   |  11 +
 drivers/gpu/drm/bridge/analogix/Makefile  |   1 +
 .../drm/bridge/analogix/analogix-anx6345.c| 845 ++
 .../drm/bridge/analogix/analogix-i2c-dptx.c   |   2 +-
 .../drm/bridge/analogix/analogix-i2c-dptx.h   |   8 +
 .../bridge/analogix/analogix-i2c-txcommon.h   |   3 +
 6 files changed, 869 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/bridge/analogix/analogix-anx6345.c

diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig 
b/drivers/gpu/drm/bridge/analogix/Kconfig
index ed2d05c12546..3c6ec535d361 100644
--- a/drivers/gpu/drm/bridge/analogix/Kconfig
+++ b/drivers/gpu/drm/bridge/analogix/Kconfig
@@ -1,3 +1,14 @@
+config DRM_ANALOGIX_ANX6345
+   tristate "Analogix ANX6345 bridge"
+   select DRM_ANALOGIX_DP_I2C
+   select DRM_KMS_HELPER
+   select REGMAP_I2C
+   help
+ ANX6345 is an ultra-low Full-HD DisplayPort/eDP
+ transmitter designed for portable devices. The
+ ANX6345 transforms the LVTTL RGB output of an
+ application processor to eDP or DisplayPort.
+
 config DRM_ANALOGIX_ANX78XX
tristate "Analogix ANX78XX bridge"
select DRM_ANALOGIX_DP_I2C
diff --git a/drivers/gpu/drm/bridge/analogix/Makefile 
b/drivers/gpu/drm/bridge/analogix/Makefile
index 2d523b67487d..12fed7b04e1e 100644
--- a/drivers/gpu/drm/bridge/analogix/Makefile
+++ b/drivers/gpu/drm/bridge/analogix/Makefile
@@ -1,5 +1,6 @@
 analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o
 analogix_dp_i2c-objs := analogix-i2c-dptx.o
+obj-$(CONFIG_DRM_ANALOGIX_ANX6345) += analogix-anx6345.o
 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
 obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o
 obj-$(CONFIG_DRM_ANALOGIX_DP_I2C) += analogix_dp_i2c.o
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c 
b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
new file mode 100644
index ..6098e245e074
--- /dev/null
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
@@ -0,0 +1,845 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(c) Icenowy Zheng 
+ * Based on analogix-anx6345.c, which is:
+ *   Copyright(c) 2016, Analogix Semiconductor.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "analogix-i2c-dptx.h"
+#include "analogix-i2c-txcommon.h"
+
+#define I2C_NUM_ADDRESSES  2
+#define I2C_IDX_DPTX   0
+#define I2C_IDX_TXCOM  1
+
+#define XTAL_CLK   270 /* 27M */
+
+#define POLL_DELAY 5 /* us */
+#define POLL_TIMEOUT   500 /* us */
+
+static const u8 anx6345_i2c_addresses[] = {
+   [I2C_IDX_DPTX]  = ANALOGIX_I2C_DPTX,
+   [I2C_IDX_TXCOM] = ANALOGIX_I2C_TXCOMMON,
+};
+
+struct anx6345_platform_data {
+   struct regulator *dvdd12;
+   struct regulator *dvdd25;
+   struct gpio_desc *gpiod_reset;
+};
+
+struct anx6345 {
+   struct drm_dp_aux aux;
+   struct drm_bridge bridge;
+   struct i2c_client *client;
+   struct edid *edid;
+   struct drm_connector connector;
+   struct drm_dp_link link;
+   struct drm_panel *panel;
+   struct anx6345_platform_data pdata;
+   struct mutex lock;
+
+   /*
+* I2C Slave addresses of ANX6345 are mapped as DPTX and SYS
+*/
+   struct i2c_client *i2c_clients[I2C_NUM_ADDRESSES];
+   struct regmap *map[I2C_NUM_ADDRESSES];
+
+   u16 chipid;
+   u8 dpcd[DP_RECEIVER_CAP_SIZE];
+
+   bool powered;
+};
+
+static inline struct anx6345 *connector_to_anx6345(struct drm_connector *c)
+{
+   return container_of(c, struct anx6345, connector);
+}
+
+static inline struct anx6345 *bridge_to_anx6345(struct drm_bridge *bridge)
+{
+   return container_of(bridge, struct anx6345, bridge);
+}
+
+static int anx6345_set_bits(struct regmap *map, u8 reg, u8 mask)
+{
+   return regmap_update_bits(map, reg, mask, mask);
+}
+
+static int anx6345_clear_bits(struct regmap *map, u8 reg, u8 mask)
+{
+   return regmap_update_bits(map, reg, mask, 0);
+}
+
+static ssize_t anx6345_aux_transfer(struct drm_dp_aux *aux,
+   struct drm_dp_aux_msg *msg)
+{
+   struct anx6345 *anx6345 = container_of(aux, struct anx6345, aux);
+
+   return anx_aux_transfer(anx6345->map[I2C_IDX_DPTX], msg);
+}
+
+static int anx6345_dp_link_training(struct anx6345 *anx6345)
+{
+   unsigned int value;
+   u8 dp_bw;
+   int err;
+
+   err = 

Re: [PATCH v3 05/11] drm/bridge: Add Analogix anx6345 support

2019-02-15 Thread Andrzej Hajda via dri-devel
On 15.02.2019 06:09, Vasily Khoruzhick wrote:
> From: Icenowy Zheng 
>
> The ANX6345 is an ultra-low power DisplayPower/eDP transmitter designed
> for portable devices. This driver adds initial support for RGB to eDP
> mode, without HPD and interrupts.
>
> This is a configuration usually seen in eDP applications.
>
> Signed-off-by: Icenowy Zheng 
> Signed-off-by: Vasily Khoruzhick 
> ---
>  drivers/gpu/drm/bridge/analogix/Kconfig   |  11 +
>  drivers/gpu/drm/bridge/analogix/Makefile  |   1 +
>  .../drm/bridge/analogix/analogix-anx6345.c| 845 ++
>  .../drm/bridge/analogix/analogix-i2c-dptx.c   |   2 +-
>  .../drm/bridge/analogix/analogix-i2c-dptx.h   |   8 +
>  .../bridge/analogix/analogix-i2c-txcommon.h   |   3 +
>  6 files changed, 869 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
>
> diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig 
> b/drivers/gpu/drm/bridge/analogix/Kconfig
> index ed2d05c12546..3c6ec535d361 100644
> --- a/drivers/gpu/drm/bridge/analogix/Kconfig
> +++ b/drivers/gpu/drm/bridge/analogix/Kconfig
> @@ -1,3 +1,14 @@
> +config DRM_ANALOGIX_ANX6345
> + tristate "Analogix ANX6345 bridge"
> + select DRM_ANALOGIX_DP_I2C
> + select DRM_KMS_HELPER
> + select REGMAP_I2C
> + help
> +   ANX6345 is an ultra-low Full-HD DisplayPort/eDP
> +   transmitter designed for portable devices. The
> +   ANX6345 transforms the LVTTL RGB output of an
> +   application processor to eDP or DisplayPort.
> +
>  config DRM_ANALOGIX_ANX78XX
>   tristate "Analogix ANX78XX bridge"
>   select DRM_ANALOGIX_DP_I2C
> diff --git a/drivers/gpu/drm/bridge/analogix/Makefile 
> b/drivers/gpu/drm/bridge/analogix/Makefile
> index 2d523b67487d..12fed7b04e1e 100644
> --- a/drivers/gpu/drm/bridge/analogix/Makefile
> +++ b/drivers/gpu/drm/bridge/analogix/Makefile
> @@ -1,5 +1,6 @@
>  analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o
>  analogix_dp_i2c-objs := analogix-i2c-dptx.o
> +obj-$(CONFIG_DRM_ANALOGIX_ANX6345) += analogix-anx6345.o
>  obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
>  obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o
>  obj-$(CONFIG_DRM_ANALOGIX_DP_I2C) += analogix_dp_i2c.o
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c 
> b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> new file mode 100644
> index ..6098e245e074
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
> @@ -0,0 +1,845 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(c) Icenowy Zheng 
> + * Based on analogix-anx6345.c, which is:
> + *   Copyright(c) 2016, Analogix Semiconductor.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
Do you need this header?
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 


drmP.h is/should be deprecated.


> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "analogix-i2c-dptx.h"
> +#include "analogix-i2c-txcommon.h"
> +
> +#define I2C_NUM_ADDRESSES2
> +#define I2C_IDX_DPTX 0
> +#define I2C_IDX_TXCOM1
> +
> +#define XTAL_CLK 270 /* 27M */
> +
> +#define POLL_DELAY   5 /* us */
> +#define POLL_TIMEOUT 500 /* us */
> +
> +static const u8 anx6345_i2c_addresses[] = {
> + [I2C_IDX_DPTX]  = ANALOGIX_I2C_DPTX,
> + [I2C_IDX_TXCOM] = ANALOGIX_I2C_TXCOMMON,
> +};
> +
> +struct anx6345_platform_data {
> + struct regulator *dvdd12;
> + struct regulator *dvdd25;
> + struct gpio_desc *gpiod_reset;
> +};


Why do you need this struct, why just do not embed it's fields directly
into struct anx6345 ?


> +
> +struct anx6345 {
> + struct drm_dp_aux aux;
> + struct drm_bridge bridge;
> + struct i2c_client *client;
> + struct edid *edid;
> + struct drm_connector connector;
> + struct drm_dp_link link;
> + struct drm_panel *panel;
> + struct anx6345_platform_data pdata;
> + struct mutex lock;
> +
> + /*
> +  * I2C Slave addresses of ANX6345 are mapped as DPTX and SYS
> +  */
> + struct i2c_client *i2c_clients[I2C_NUM_ADDRESSES];
> + struct regmap *map[I2C_NUM_ADDRESSES];
> +
> + u16 chipid;
> + u8 dpcd[DP_RECEIVER_CAP_SIZE];
> +
> + bool powered;
> +};
> +
> +static inline struct anx6345 *connector_to_anx6345(struct drm_connector *c)
> +{
> + return container_of(c, struct anx6345, connector);
> +}
> +
> +static inline struct anx6345 *bridge_to_anx6345(struct drm_bridge *bridge)
> +{
> + return container_of(bridge, struct anx6345, bridge);
> +}
> +
> +static int anx6345_set_bits(struct regmap *map, u8 reg, u8 mask)
> +{
> + return regmap_update_bits(map, reg, mask, mask);
> +}
> +
> +static int anx6345_clear_bits(struct regmap *map, u8 reg, u8 mask)
> +{
> + return regmap_update_bits(map, reg, mask, 0);
> +}
> +
> +static ssize_t