Skip to content

Commit be82d39

Browse files
committed
hwmon: (spd5118) Support 16-bit addressing for NVMEM accesses
I3C uses 16-bit register addresses. Setting the page through the legacy mode access pointer in the legacy mode device configuration register (MR11) is not needed. This is similar to 16-bit addressing in legacy mode. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent ae28532 commit be82d39

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

drivers/hwmon/spd5118.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ static const unsigned short normal_i2c[] = {
6666
#define SPD5118_EEPROM_BASE 0x80
6767
#define SPD5118_EEPROM_SIZE (SPD5118_PAGE_SIZE * SPD5118_NUM_PAGES)
6868

69+
#define PAGE_ADDR0(page) (((page) & BIT(0)) << 6)
70+
#define PAGE_ADDR1_4(page) (((page) & GENMASK(4, 1)) >> 1)
71+
6972
/* Temperature unit in millicelsius */
7073
#define SPD5118_TEMP_UNIT (MILLIDEGREE_PER_DEGREE / 4)
7174
/* Representable temperature range in millicelsius */
@@ -75,6 +78,7 @@ static const unsigned short normal_i2c[] = {
7578
struct spd5118_data {
7679
struct regmap *regmap;
7780
struct mutex nvmem_lock;
81+
bool is_16bit;
7882
};
7983

8084
/* hwmon */
@@ -331,18 +335,25 @@ static const struct hwmon_chip_info spd5118_chip_info = {
331335

332336
/* nvmem */
333337

334-
static ssize_t spd5118_nvmem_read_page(struct regmap *regmap, char *buf,
338+
static ssize_t spd5118_nvmem_read_page(struct spd5118_data *data, char *buf,
335339
unsigned int offset, size_t count)
336340
{
337-
int addr = (offset >> SPD5118_PAGE_SHIFT) * 0x100 + SPD5118_EEPROM_BASE;
338-
int err;
341+
int page = offset >> SPD5118_PAGE_SHIFT;
342+
struct regmap *regmap = data->regmap;
343+
int err, addr;
339344

340345
offset &= SPD5118_PAGE_MASK;
341346

342347
/* Can't cross page boundaries */
343348
if (offset + count > SPD5118_PAGE_SIZE)
344349
count = SPD5118_PAGE_SIZE - offset;
345350

351+
if (data->is_16bit) {
352+
addr = SPD5118_EEPROM_BASE | PAGE_ADDR0(page) |
353+
(PAGE_ADDR1_4(page) << 8);
354+
} else {
355+
addr = page * 0x100 + SPD5118_EEPROM_BASE;
356+
}
346357
err = regmap_bulk_read(regmap, addr + offset, buf, count);
347358
if (err)
348359
return err;
@@ -365,7 +376,7 @@ static int spd5118_nvmem_read(void *priv, unsigned int off, void *val, size_t co
365376
mutex_lock(&data->nvmem_lock);
366377

367378
while (count) {
368-
ret = spd5118_nvmem_read_page(data->regmap, buf, off, count);
379+
ret = spd5118_nvmem_read_page(data, buf, off, count);
369380
if (ret < 0) {
370381
mutex_unlock(&data->nvmem_lock);
371382
return ret;
@@ -516,6 +527,13 @@ static int spd5118_common_probe(struct device *dev, struct regmap *regmap)
516527
if (!(capability & SPD5118_CAP_TS_SUPPORT))
517528
return -ENODEV;
518529

530+
/*
531+
* 16-bit register addresses are not (yet) supported with I2C.
532+
* Therefore, if this is an I2C device, register addresses must be
533+
* 8 bit wide.
534+
*/
535+
data->is_16bit = !!i2c_verify_adapter(dev);
536+
519537
err = regmap_read(regmap, SPD5118_REG_REVISION, &revision);
520538
if (err)
521539
return err;

0 commit comments

Comments
 (0)