Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: rsmu: support I2C SMBus access

8a3400x device implements its own reg_read and reg_write,
which only supports I2C bus access. This patch adds support
for SMBus access.

Signed-off-by: Min Li <min.li.xe@renesas.com>
Link: https://lore.kernel.org/r/LV3P220MB12021342F302AADEB6C1601CA0192@LV3P220MB1202.NAMP220.PROD.OUTLOOK.COM
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Min Li and committed by
Lee Jones
53d3ff7b ecbc0f27

+97 -18
+93 -14
drivers/mfd/rsmu_i2c.c
··· 32 32 #define RSMU_SABRE_PAGE_ADDR 0x7F 33 33 #define RSMU_SABRE_PAGE_WINDOW 128 34 34 35 + typedef int (*rsmu_rw_device)(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes); 36 + 35 37 static const struct regmap_range_cfg rsmu_sabre_range_cfg[] = { 36 38 { 37 39 .range_min = 0, ··· 56 54 } 57 55 } 58 56 59 - static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes) 57 + static int rsmu_smbus_i2c_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes) 58 + { 59 + struct i2c_client *client = to_i2c_client(rsmu->dev); 60 + 61 + return i2c_smbus_write_i2c_block_data(client, reg, bytes, buf); 62 + } 63 + 64 + static int rsmu_smbus_i2c_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes) 65 + { 66 + struct i2c_client *client = to_i2c_client(rsmu->dev); 67 + int ret; 68 + 69 + ret = i2c_smbus_read_i2c_block_data(client, reg, bytes, buf); 70 + if (ret == bytes) 71 + return 0; 72 + else if (ret < 0) 73 + return ret; 74 + else 75 + return -EIO; 76 + } 77 + 78 + static int rsmu_i2c_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes) 60 79 { 61 80 struct i2c_client *client = to_i2c_client(rsmu->dev); 62 81 struct i2c_msg msg[2]; ··· 107 84 return 0; 108 85 } 109 86 110 - static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes) 87 + static int rsmu_i2c_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u8 bytes) 111 88 { 112 89 struct i2c_client *client = to_i2c_client(rsmu->dev); 113 - u8 msg[RSMU_MAX_WRITE_COUNT + 1]; /* 1 Byte added for the device register */ 90 + /* we add 1 byte for device register */ 91 + u8 msg[RSMU_MAX_WRITE_COUNT + 1]; 114 92 int cnt; 115 93 116 94 if (bytes > RSMU_MAX_WRITE_COUNT) ··· 131 107 return 0; 132 108 } 133 109 134 - static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg) 110 + static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg, 111 + rsmu_rw_device rsmu_write_device) 135 112 { 136 113 u32 page = reg & RSMU_CM_PAGE_MASK; 137 114 u8 buf[4]; ··· 161 136 return err; 162 137 } 163 138 164 - static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val) 139 + static int rsmu_i2c_reg_read(void *context, unsigned int reg, unsigned int *val) 165 140 { 166 141 struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context); 167 142 u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK); 168 143 int err; 169 144 170 - err = rsmu_write_page_register(rsmu, reg); 145 + err = rsmu_write_page_register(rsmu, reg, rsmu_i2c_write_device); 171 146 if (err) 172 147 return err; 173 148 174 - err = rsmu_read_device(rsmu, addr, (u8 *)val, 1); 149 + err = rsmu_i2c_read_device(rsmu, addr, (u8 *)val, 1); 175 150 if (err) 176 151 dev_err(rsmu->dev, "Failed to read offset address 0x%x\n", addr); 177 152 178 153 return err; 179 154 } 180 155 181 - static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val) 156 + static int rsmu_i2c_reg_write(void *context, unsigned int reg, unsigned int val) 182 157 { 183 158 struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context); 184 159 u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK); 185 160 u8 data = (u8)val; 186 161 int err; 187 162 188 - err = rsmu_write_page_register(rsmu, reg); 163 + err = rsmu_write_page_register(rsmu, reg, rsmu_i2c_write_device); 189 164 if (err) 190 165 return err; 191 166 192 - err = rsmu_write_device(rsmu, addr, &data, 1); 167 + err = rsmu_i2c_write_device(rsmu, addr, &data, 1); 193 168 if (err) 194 169 dev_err(rsmu->dev, 195 170 "Failed to write offset address 0x%x\n", addr); ··· 197 172 return err; 198 173 } 199 174 200 - static const struct regmap_config rsmu_cm_regmap_config = { 175 + static int rsmu_smbus_i2c_reg_read(void *context, unsigned int reg, unsigned int *val) 176 + { 177 + struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context); 178 + u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK); 179 + int err; 180 + 181 + err = rsmu_write_page_register(rsmu, reg, rsmu_smbus_i2c_write_device); 182 + if (err) 183 + return err; 184 + 185 + err = rsmu_smbus_i2c_read_device(rsmu, addr, (u8 *)val, 1); 186 + if (err) 187 + dev_err(rsmu->dev, "Failed to read offset address 0x%x\n", addr); 188 + 189 + return err; 190 + } 191 + 192 + static int rsmu_smbus_i2c_reg_write(void *context, unsigned int reg, unsigned int val) 193 + { 194 + struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context); 195 + u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK); 196 + u8 data = (u8)val; 197 + int err; 198 + 199 + err = rsmu_write_page_register(rsmu, reg, rsmu_smbus_i2c_write_device); 200 + if (err) 201 + return err; 202 + 203 + err = rsmu_smbus_i2c_write_device(rsmu, addr, &data, 1); 204 + if (err) 205 + dev_err(rsmu->dev, 206 + "Failed to write offset address 0x%x\n", addr); 207 + 208 + return err; 209 + } 210 + 211 + static const struct regmap_config rsmu_i2c_cm_regmap_config = { 201 212 .reg_bits = 32, 202 213 .val_bits = 8, 203 214 .max_register = 0x20120000, 204 - .reg_read = rsmu_reg_read, 205 - .reg_write = rsmu_reg_write, 215 + .reg_read = rsmu_i2c_reg_read, 216 + .reg_write = rsmu_i2c_reg_write, 217 + .cache_type = REGCACHE_NONE, 218 + }; 219 + 220 + static const struct regmap_config rsmu_smbus_i2c_cm_regmap_config = { 221 + .reg_bits = 32, 222 + .val_bits = 8, 223 + .max_register = 0x20120000, 224 + .reg_read = rsmu_smbus_i2c_reg_read, 225 + .reg_write = rsmu_smbus_i2c_reg_write, 206 226 .cache_type = REGCACHE_NONE, 207 227 }; 208 228 ··· 289 219 290 220 switch (rsmu->type) { 291 221 case RSMU_CM: 292 - cfg = &rsmu_cm_regmap_config; 222 + if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 223 + cfg = &rsmu_i2c_cm_regmap_config; 224 + } else if (i2c_check_functionality(client->adapter, 225 + I2C_FUNC_SMBUS_I2C_BLOCK)) { 226 + cfg = &rsmu_smbus_i2c_cm_regmap_config; 227 + } else { 228 + dev_err(rsmu->dev, "Unsupported i2c adapter\n"); 229 + return -ENOTSUPP; 230 + } 293 231 break; 294 232 case RSMU_SABRE: 295 233 cfg = &rsmu_sabre_regmap_config; ··· 314 236 rsmu->regmap = devm_regmap_init(&client->dev, NULL, client, cfg); 315 237 else 316 238 rsmu->regmap = devm_regmap_init_i2c(client, cfg); 239 + 317 240 if (IS_ERR(rsmu->regmap)) { 318 241 ret = PTR_ERR(rsmu->regmap); 319 242 dev_err(rsmu->dev, "Failed to allocate register map: %d\n", ret);
+4 -4
drivers/mfd/rsmu_spi.c
··· 106 106 return 0; 107 107 page_reg = RSMU_CM_PAGE_ADDR; 108 108 page = reg & RSMU_PAGE_MASK; 109 - buf[0] = (u8)(page & 0xff); 110 - buf[1] = (u8)((page >> 8) & 0xff); 111 - buf[2] = (u8)((page >> 16) & 0xff); 112 - buf[3] = (u8)((page >> 24) & 0xff); 109 + buf[0] = (u8)(page & 0xFF); 110 + buf[1] = (u8)((page >> 8) & 0xFF); 111 + buf[2] = (u8)((page >> 16) & 0xFF); 112 + buf[3] = (u8)((page >> 24) & 0xFF); 113 113 bytes = 4; 114 114 break; 115 115 case RSMU_SABRE: