Skip to content

Commit 6da24a2

Browse files
committed
hwmon: (lm75) Hide register size differences in regmap access functions
Hide register size differences in regmap access functions to simplify runtime code and to simplify adding support for I3C devices. Also use regmap API functions for bit operations where possible. For this to work, the 16-bit and 8-bit configuration register has to be mapped to a 16-bit value. Unlike other registers, this register is a low-byte-first register, presumably for compatibility with chips with 8-bit wide configuration registers. Hide the differences in the regmap access code. While at it, enable alarm attribute support for TMP112. Cc: Wolfram Sang <wsa+renesas@sang-engineering.com> Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
1 parent de07619 commit 6da24a2

File tree

1 file changed

+62
-69
lines changed

1 file changed

+62
-69
lines changed

drivers/hwmon/lm75.c

Lines changed: 62 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ struct lm75_data {
111111
struct regmap *regmap;
112112
struct regulator *vs;
113113
u16 orig_conf;
114-
u16 current_conf;
115114
u8 resolution; /* In bits, 9 to 16 */
116115
unsigned int sample_time; /* In ms */
117116
enum lm75_type kind;
@@ -284,6 +283,7 @@ static const struct lm75_params device_params[] = {
284283
.default_sample_time = 125,
285284
.num_sample_times = 4,
286285
.sample_times = (unsigned int []){ 125, 250, 1000, 4000 },
286+
.alarm = true,
287287
},
288288
[tmp175] = {
289289
.set_mask = 3 << 5, /* 12-bit mode */
@@ -343,40 +343,16 @@ static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
343343
static int lm75_write_config(struct lm75_data *data, u16 set_mask,
344344
u16 clr_mask)
345345
{
346-
unsigned int value;
346+
int err;
347347

348-
clr_mask |= LM75_SHUTDOWN << (8 * data->params->config_reg_16bits);
349-
value = data->current_conf & ~clr_mask;
350-
value |= set_mask;
348+
err = regmap_update_bits(data->regmap, LM75_REG_CONF,
349+
clr_mask | LM75_SHUTDOWN, set_mask);
350+
if (err)
351+
return err;
351352

352-
if (data->current_conf != value) {
353-
s32 err;
354-
if (data->params->config_reg_16bits)
355-
err = regmap_write(data->regmap, LM75_REG_CONF, value);
356-
else
357-
err = i2c_smbus_write_byte_data(data->client,
358-
LM75_REG_CONF,
359-
value);
360-
if (err)
361-
return err;
362-
data->current_conf = value;
363-
}
364353
return 0;
365354
}
366355

367-
static int lm75_read_config(struct lm75_data *data)
368-
{
369-
int ret;
370-
unsigned int status;
371-
372-
if (data->params->config_reg_16bits) {
373-
ret = regmap_read(data->regmap, LM75_REG_CONF, &status);
374-
return ret ? ret : status;
375-
}
376-
377-
return i2c_smbus_read_byte_data(data->client, LM75_REG_CONF);
378-
}
379-
380356
static irqreturn_t lm75_alarm_handler(int irq, void *private)
381357
{
382358
struct device *hwmon_dev = private;
@@ -426,7 +402,8 @@ static int lm75_read(struct device *dev, enum hwmon_sensor_types type,
426402
if (attr == hwmon_temp_alarm) {
427403
switch (data->kind) {
428404
case as6200:
429-
*val = (regval >> 5) & 0x1;
405+
case tmp112:
406+
*val = (regval >> 13) & 0x1;
430407
break;
431408
default:
432409
return -EINVAL;
@@ -477,7 +454,6 @@ static int lm75_write_temp(struct device *dev, u32 attr, long temp)
477454
static int lm75_update_interval(struct device *dev, long val)
478455
{
479456
struct lm75_data *data = dev_get_drvdata(dev);
480-
unsigned int reg;
481457
u8 index;
482458
s32 err;
483459

@@ -497,19 +473,14 @@ static int lm75_update_interval(struct device *dev, long val)
497473
break;
498474
case tmp112:
499475
case as6200:
500-
err = regmap_read(data->regmap, LM75_REG_CONF, &reg);
501-
if (err < 0)
502-
return err;
503-
reg &= ~0x00c0;
504-
reg |= (3 - index) << 6;
505-
err = regmap_write(data->regmap, LM75_REG_CONF, reg);
476+
err = regmap_update_bits(data->regmap, LM75_REG_CONF,
477+
0xc000, (3 - index) << 14);
506478
if (err < 0)
507479
return err;
508480
data->sample_time = data->params->sample_times[index];
509481
break;
510482
case pct2075:
511-
err = i2c_smbus_write_byte_data(data->client, PCT2075_REG_IDLE,
512-
index + 1);
483+
err = regmap_write(data->regmap, PCT2075_REG_IDLE, index + 1);
513484
if (err)
514485
return err;
515486
data->sample_time = data->params->sample_times[index];
@@ -606,6 +577,39 @@ static bool lm75_is_volatile_reg(struct device *dev, unsigned int reg)
606577
return reg == LM75_REG_TEMP || reg == LM75_REG_CONF;
607578
}
608579

580+
static int lm75_i2c_reg_read(void *context, unsigned int reg, unsigned int *val)
581+
{
582+
struct lm75_data *data = context;
583+
struct i2c_client *client = data->client;
584+
int ret;
585+
586+
if (reg == LM75_REG_CONF) {
587+
if (!data->params->config_reg_16bits)
588+
ret = i2c_smbus_read_byte_data(client, LM75_REG_CONF);
589+
else
590+
ret = i2c_smbus_read_word_data(client, LM75_REG_CONF);
591+
} else {
592+
ret = i2c_smbus_read_word_swapped(client, reg);
593+
}
594+
if (ret < 0)
595+
return ret;
596+
*val = ret;
597+
return 0;
598+
}
599+
600+
static int lm75_i2c_reg_write(void *context, unsigned int reg, unsigned int val)
601+
{
602+
struct lm75_data *data = context;
603+
struct i2c_client *client = data->client;
604+
605+
if (reg == PCT2075_REG_IDLE ||
606+
(reg == LM75_REG_CONF && !data->params->config_reg_16bits))
607+
return i2c_smbus_write_byte_data(client, reg, val);
608+
else if (reg == LM75_REG_CONF)
609+
return i2c_smbus_write_word_data(client, reg, val);
610+
return i2c_smbus_write_word_swapped(client, reg, val);
611+
}
612+
609613
static const struct regmap_config lm75_regmap_config = {
610614
.reg_bits = 8,
611615
.val_bits = 16,
@@ -618,6 +622,11 @@ static const struct regmap_config lm75_regmap_config = {
618622
.use_single_write = true,
619623
};
620624

625+
static const struct regmap_bus lm75_i2c_regmap_bus = {
626+
.reg_read = lm75_i2c_reg_read,
627+
.reg_write = lm75_i2c_reg_write,
628+
};
629+
621630
static void lm75_disable_regulator(void *data)
622631
{
623632
struct lm75_data *lm75 = data;
@@ -628,9 +637,8 @@ static void lm75_disable_regulator(void *data)
628637
static void lm75_remove(void *data)
629638
{
630639
struct lm75_data *lm75 = data;
631-
struct i2c_client *client = lm75->client;
632640

633-
i2c_smbus_write_byte_data(client, LM75_REG_CONF, lm75->orig_conf);
641+
regmap_write(lm75->regmap, LM75_REG_CONF, lm75->orig_conf);
634642
}
635643

636644
static int lm75_probe(struct i2c_client *client)
@@ -648,14 +656,18 @@ static int lm75_probe(struct i2c_client *client)
648656
if (!data)
649657
return -ENOMEM;
650658

659+
/* needed by custom regmap callbacks */
660+
dev_set_drvdata(dev, data);
661+
651662
data->client = client;
652663
data->kind = (uintptr_t)i2c_get_match_data(client);
653664

654665
data->vs = devm_regulator_get(dev, "vs");
655666
if (IS_ERR(data->vs))
656667
return PTR_ERR(data->vs);
657668

658-
data->regmap = devm_regmap_init_i2c(client, &lm75_regmap_config);
669+
data->regmap = devm_regmap_init(dev, &lm75_i2c_regmap_bus, data,
670+
&lm75_regmap_config);
659671
if (IS_ERR(data->regmap))
660672
return PTR_ERR(data->regmap);
661673

@@ -681,13 +693,10 @@ static int lm75_probe(struct i2c_client *client)
681693
return err;
682694

683695
/* Cache original configuration */
684-
status = lm75_read_config(data);
685-
if (status < 0) {
686-
dev_dbg(dev, "Can't read config? %d\n", status);
687-
return status;
688-
}
696+
err = regmap_read(data->regmap, LM75_REG_CONF, &status);
697+
if (err)
698+
return err;
689699
data->orig_conf = status;
690-
data->current_conf = status;
691700

692701
err = lm75_write_config(data, data->params->set_mask,
693702
data->params->clr_mask);
@@ -985,32 +994,16 @@ static int lm75_detect(struct i2c_client *new_client,
985994
#ifdef CONFIG_PM
986995
static int lm75_suspend(struct device *dev)
987996
{
988-
int status;
989-
struct i2c_client *client = to_i2c_client(dev);
997+
struct lm75_data *data = dev_get_drvdata(dev);
990998

991-
status = i2c_smbus_read_byte_data(client, LM75_REG_CONF);
992-
if (status < 0) {
993-
dev_dbg(&client->dev, "Can't read config? %d\n", status);
994-
return status;
995-
}
996-
status = status | LM75_SHUTDOWN;
997-
i2c_smbus_write_byte_data(client, LM75_REG_CONF, status);
998-
return 0;
999+
return regmap_update_bits(data->regmap, LM75_REG_CONF, LM75_SHUTDOWN, LM75_SHUTDOWN);
9991000
}
10001001

10011002
static int lm75_resume(struct device *dev)
10021003
{
1003-
int status;
1004-
struct i2c_client *client = to_i2c_client(dev);
1004+
struct lm75_data *data = dev_get_drvdata(dev);
10051005

1006-
status = i2c_smbus_read_byte_data(client, LM75_REG_CONF);
1007-
if (status < 0) {
1008-
dev_dbg(&client->dev, "Can't read config? %d\n", status);
1009-
return status;
1010-
}
1011-
status = status & ~LM75_SHUTDOWN;
1012-
i2c_smbus_write_byte_data(client, LM75_REG_CONF, status);
1013-
return 0;
1006+
return regmap_update_bits(data->regmap, LM75_REG_CONF, LM75_SHUTDOWN, 0);
10141007
}
10151008

10161009
static const struct dev_pm_ops lm75_dev_pm_ops = {

0 commit comments

Comments
 (0)