Skip to content

Commit

Permalink
hwmon: (adt7x10) Convert to use regmap
Browse files Browse the repository at this point in the history
Using regmap lets us use the regmap subsystem for SPI vs. I2C register
accesses. It lets us hide access differences in backend code and lets
the common code just access registers without knowing their size.
We can also use regmap for register caching.

Tested-by: Cosmin Tanislav <cosmin.tanislav@analog.com>
Reviewed-by: Cosmin Tanislav <cosmin.tanislav@analog.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
  • Loading branch information
groeck committed Feb 28, 2022
1 parent 7979a30 commit f532070
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 188 deletions.
1 change: 1 addition & 0 deletions drivers/hwmon/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ config SENSORS_ADM9240

config SENSORS_ADT7X10
tristate
select REGMAP
help
This module contains common code shared by the ADT7310/ADT7320 and
ADT7410/ADT7420 temperature monitoring chip drivers.
Expand Down
88 changes: 71 additions & 17 deletions drivers/hwmon/adt7310.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <linux/module.h>
#include <linux/init.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <asm/unaligned.h>

Expand Down Expand Up @@ -38,16 +39,13 @@ static const u8 adt7310_reg_table[] = {

#define AD7310_COMMAND(reg) (adt7310_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET)

static int adt7310_spi_read_word(struct device *dev, u8 reg)
static int adt7310_spi_read_word(struct spi_device *spi, u8 reg)
{
struct spi_device *spi = to_spi_device(dev);

return spi_w8r16be(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ);
}

static int adt7310_spi_write_word(struct device *dev, u8 reg, u16 data)
static int adt7310_spi_write_word(struct spi_device *spi, u8 reg, u16 data)
{
struct spi_device *spi = to_spi_device(dev);
u8 buf[3];

buf[0] = AD7310_COMMAND(reg);
Expand All @@ -56,17 +54,13 @@ static int adt7310_spi_write_word(struct device *dev, u8 reg, u16 data)
return spi_write(spi, buf, sizeof(buf));
}

static int adt7310_spi_read_byte(struct device *dev, u8 reg)
static int adt7310_spi_read_byte(struct spi_device *spi, u8 reg)
{
struct spi_device *spi = to_spi_device(dev);

return spi_w8r8(spi, AD7310_COMMAND(reg) | ADT7310_CMD_READ);
}

static int adt7310_spi_write_byte(struct device *dev, u8 reg,
u8 data)
static int adt7310_spi_write_byte(struct spi_device *spi, u8 reg, u8 data)
{
struct spi_device *spi = to_spi_device(dev);
u8 buf[2];

buf[0] = AD7310_COMMAND(reg);
Expand All @@ -75,17 +69,77 @@ static int adt7310_spi_write_byte(struct device *dev, u8 reg,
return spi_write(spi, buf, sizeof(buf));
}

static const struct adt7x10_ops adt7310_spi_ops = {
.read_word = adt7310_spi_read_word,
.write_word = adt7310_spi_write_word,
.read_byte = adt7310_spi_read_byte,
.write_byte = adt7310_spi_write_byte,
static bool adt7310_regmap_is_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
case ADT7X10_TEMPERATURE:
case ADT7X10_STATUS:
return true;
default:
return false;
}
}

static int adt7310_reg_read(void *context, unsigned int reg, unsigned int *val)
{
struct spi_device *spi = context;
int regval;

switch (reg) {
case ADT7X10_TEMPERATURE:
case ADT7X10_T_ALARM_HIGH:
case ADT7X10_T_ALARM_LOW:
case ADT7X10_T_CRIT:
regval = adt7310_spi_read_word(spi, reg);
break;
default:
regval = adt7310_spi_read_byte(spi, reg);
break;
}
if (regval < 0)
return regval;
*val = regval;
return 0;
}

static int adt7310_reg_write(void *context, unsigned int reg, unsigned int val)
{
struct spi_device *spi = context;
int ret;

switch (reg) {
case ADT7X10_TEMPERATURE:
case ADT7X10_T_ALARM_HIGH:
case ADT7X10_T_ALARM_LOW:
case ADT7X10_T_CRIT:
ret = adt7310_spi_write_word(spi, reg, val);
break;
default:
ret = adt7310_spi_write_byte(spi, reg, val);
break;
}
return ret;
}

static const struct regmap_config adt7310_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.cache_type = REGCACHE_RBTREE,
.volatile_reg = adt7310_regmap_is_volatile,
.reg_read = adt7310_reg_read,
.reg_write = adt7310_reg_write,
};

static int adt7310_spi_probe(struct spi_device *spi)
{
struct regmap *regmap;

regmap = devm_regmap_init(&spi->dev, NULL, spi, &adt7310_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);

return adt7x10_probe(&spi->dev, spi_get_device_id(spi)->name, spi->irq,
&adt7310_spi_ops);
regmap);
}

static int adt7310_spi_remove(struct spi_device *spi)
Expand Down
77 changes: 58 additions & 19 deletions drivers/hwmon/adt7410.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,82 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/regmap.h>

#include "adt7x10.h"

static int adt7410_i2c_read_word(struct device *dev, u8 reg)
static bool adt7410_regmap_is_volatile(struct device *dev, unsigned int reg)
{
return i2c_smbus_read_word_swapped(to_i2c_client(dev), reg);
switch (reg) {
case ADT7X10_TEMPERATURE:
case ADT7X10_STATUS:
return true;
default:
return false;
}
}

static int adt7410_i2c_write_word(struct device *dev, u8 reg, u16 data)
static int adt7410_reg_read(void *context, unsigned int reg, unsigned int *val)
{
return i2c_smbus_write_word_swapped(to_i2c_client(dev), reg, data);
}
struct i2c_client *client = context;
int regval;

static int adt7410_i2c_read_byte(struct device *dev, u8 reg)
{
return i2c_smbus_read_byte_data(to_i2c_client(dev), reg);
switch (reg) {
case ADT7X10_TEMPERATURE:
case ADT7X10_T_ALARM_HIGH:
case ADT7X10_T_ALARM_LOW:
case ADT7X10_T_CRIT:
regval = i2c_smbus_read_word_swapped(client, reg);
break;
default:
regval = i2c_smbus_read_byte_data(client, reg);
break;
}
if (regval < 0)
return regval;
*val = regval;
return 0;
}

static int adt7410_i2c_write_byte(struct device *dev, u8 reg, u8 data)
static int adt7410_reg_write(void *context, unsigned int reg, unsigned int val)
{
return i2c_smbus_write_byte_data(to_i2c_client(dev), reg, data);
struct i2c_client *client = context;
int ret;

switch (reg) {
case ADT7X10_TEMPERATURE:
case ADT7X10_T_ALARM_HIGH:
case ADT7X10_T_ALARM_LOW:
case ADT7X10_T_CRIT:
ret = i2c_smbus_write_word_swapped(client, reg, val);
break;
default:
ret = i2c_smbus_write_byte_data(client, reg, val);
break;
}
return ret;
}

static const struct adt7x10_ops adt7410_i2c_ops = {
.read_word = adt7410_i2c_read_word,
.write_word = adt7410_i2c_write_word,
.read_byte = adt7410_i2c_read_byte,
.write_byte = adt7410_i2c_write_byte,
static const struct regmap_config adt7410_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.max_register = ADT7X10_ID,
.cache_type = REGCACHE_RBTREE,
.volatile_reg = adt7410_regmap_is_volatile,
.reg_read = adt7410_reg_read,
.reg_write = adt7410_reg_write,
};

static int adt7410_i2c_probe(struct i2c_client *client)
{
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
struct regmap *regmap;

regmap = devm_regmap_init(&client->dev, NULL, client,
&adt7410_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);

return adt7x10_probe(&client->dev, NULL, client->irq, &adt7410_i2c_ops);
return adt7x10_probe(&client->dev, NULL, client->irq, regmap);
}

static int adt7410_i2c_remove(struct i2c_client *client)
Expand Down
Loading

0 comments on commit f532070

Please sign in to comment.