From 81e27b972ca20db09a92e9b6a53e50d22ed1bfd6 Mon Sep 17 00:00:00 2001 From: Guochun Huang Date: Fri, 27 May 2022 08:29:53 +0000 Subject: [PATCH] mfd: MAX96745: disable remote control-channel link on this link there can be multiple SerDes applications on the same I2C BUS. the serializer can attach multiple deiserializers which have the same I2C slave device address, to avoid I2C communication conflicts, driver should disable remote control-channel link after accessing. Change-Id: I099caf597835cc34f34231231fbaddf2c5d03288 Signed-off-by: Guochun Huang --- drivers/mfd/max96745.c | 43 ++++++++++++++++++++++++------------ include/linux/mfd/max96745.h | 3 +++ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/mfd/max96745.c b/drivers/mfd/max96745.c index 41a31c18dc2a..07cc1b654779 100644 --- a/drivers/mfd/max96745.c +++ b/drivers/mfd/max96745.c @@ -43,18 +43,26 @@ static int max96745_select(struct i2c_mux_core *muxc, u32 chan) { struct max96745 *max96745 = dev_get_drvdata(muxc->dev); - if (chan == 0) { - regmap_update_bits(max96745->regmap, 0x0028, LINK_EN, - FIELD_PREP(LINK_EN, 1)); - } else if (chan == 1) { - regmap_update_bits(max96745->regmap, 0x0032, LINK_EN, - FIELD_PREP(LINK_EN, 1)); - } else { - regmap_update_bits(max96745->regmap, 0x0028, LINK_EN, - FIELD_PREP(LINK_EN, 1)); - regmap_update_bits(max96745->regmap, 0x0032, LINK_EN, - FIELD_PREP(LINK_EN, 1)); - } + if (chan == 1) + regmap_update_bits(max96745->regmap, 0x0086, DIS_REM_CC, + FIELD_PREP(DIS_REM_CC, 0)); + else + regmap_update_bits(max96745->regmap, 0x0076, DIS_REM_CC, + FIELD_PREP(DIS_REM_CC, 0)); + + return 0; +} + +static int max96745_deselect(struct i2c_mux_core *muxc, u32 chan) +{ + struct max96745 *max96745 = dev_get_drvdata(muxc->dev); + + if (chan == 1) + regmap_update_bits(max96745->regmap, 0x0086, DIS_REM_CC, + FIELD_PREP(DIS_REM_CC, 1)); + else + regmap_update_bits(max96745->regmap, 0x0076, DIS_REM_CC, + FIELD_PREP(DIS_REM_CC, 1)); return 0; } @@ -88,6 +96,12 @@ static int max96745_power_on(struct max96745 *max96745) msleep(100); + regmap_update_bits(max96745->regmap, 0x0076, DIS_REM_CC, + FIELD_PREP(DIS_REM_CC, 1)); + regmap_update_bits(max96745->regmap, 0x0086, DIS_REM_CC, + FIELD_PREP(DIS_REM_CC, 1)); + + return 0; } @@ -110,8 +124,9 @@ static int max96745_i2c_probe(struct i2c_client *client) if (!max96745) return -ENOMEM; - max96745->muxc = i2c_mux_alloc(client->adapter, dev, nr, 0, - I2C_MUX_LOCKED, max96745_select, NULL); + max96745->muxc = i2c_mux_alloc(client->adapter, dev, nr, + 0, I2C_MUX_LOCKED, + max96745_select, max96745_deselect); if (!max96745->muxc) return -ENOMEM; diff --git a/include/linux/mfd/max96745.h b/include/linux/mfd/max96745.h index acbe64b945e3..ce1d320eedb6 100644 --- a/include/linux/mfd/max96745.h +++ b/include/linux/mfd/max96745.h @@ -33,6 +33,9 @@ /* 002Ah, 0034h */ #define LINK_LOCKED BIT(0) +/* 0076h, 0086h */ +#define DIS_REM_CC BIT(7) + /* 0100h */ #define VID_LINK_SEL GENMASK(2, 1) #define VID_TX_EN BIT(0)