Skip to content

Commit

Permalink
hwmon: (adt7475) Add attenuator bypass support
Browse files Browse the repository at this point in the history
Added support for reading DTS properties to set attenuators on
device probe for the ADT7473, ADT7475, ADT7476, and ADT7490.

Signed-off-by: Logan Shaw <logan.shaw@alliedtelesis.co.nz>
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
[groeck: Continuation line formatting; dev_err -> dev_warn]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
  • Loading branch information
Logan Shaw authored and Guenter Roeck committed Mar 9, 2020
1 parent ed39ff5 commit 2ecff39
Showing 1 changed file with 58 additions and 3 deletions.
61 changes: 58 additions & 3 deletions drivers/hwmon/adt7475.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/jiffies.h>
#include <linux/of.h>
#include <linux/util_macros.h>

/* Indexes for the sysfs hooks */
Expand Down Expand Up @@ -193,6 +194,7 @@ struct adt7475_data {
unsigned long measure_updated;
bool valid;

u8 config2;
u8 config4;
u8 config5;
u8 has_voltage;
Expand Down Expand Up @@ -1458,6 +1460,55 @@ static int adt7475_update_limits(struct i2c_client *client)
return 0;
}

static int set_property_bit(const struct i2c_client *client, char *property,
u8 *config, u8 bit_index)
{
u32 prop_value = 0;
int ret = of_property_read_u32(client->dev.of_node, property,
&prop_value);

if (!ret) {
if (prop_value)
*config |= (1 << bit_index);
else
*config &= ~(1 << bit_index);
}

return ret;
}

static int load_attenuators(const struct i2c_client *client, int chip,
struct adt7475_data *data)
{
int ret;

if (chip == adt7476 || chip == adt7490) {
set_property_bit(client, "adi,bypass-attenuator-in0",
&data->config4, 4);
set_property_bit(client, "adi,bypass-attenuator-in1",
&data->config4, 5);
set_property_bit(client, "adi,bypass-attenuator-in3",
&data->config4, 6);
set_property_bit(client, "adi,bypass-attenuator-in4",
&data->config4, 7);

ret = i2c_smbus_write_byte_data(client, REG_CONFIG4,
data->config4);
if (ret < 0)
return ret;
} else if (chip == adt7473 || chip == adt7475) {
set_property_bit(client, "adi,bypass-attenuator-in1",
&data->config2, 5);

ret = i2c_smbus_write_byte_data(client, REG_CONFIG2,
data->config2);
if (ret < 0)
return ret;
}

return 0;
}

static int adt7475_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
Expand All @@ -1472,7 +1523,7 @@ static int adt7475_probe(struct i2c_client *client,
struct adt7475_data *data;
struct device *hwmon_dev;
int i, ret = 0, revision, group_num = 0;
u8 config2, config3;
u8 config3;

data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
if (data == NULL)
Expand Down Expand Up @@ -1546,8 +1597,12 @@ static int adt7475_probe(struct i2c_client *client,
}

/* Voltage attenuators can be bypassed, globally or individually */
config2 = adt7475_read(REG_CONFIG2);
if (config2 & CONFIG2_ATTN) {
data->config2 = adt7475_read(REG_CONFIG2);
ret = load_attenuators(client, chip, data);
if (ret)
dev_warn(&client->dev, "Error configuring attenuator bypass\n");

if (data->config2 & CONFIG2_ATTN) {
data->bypass_attn = (0x3 << 3) | 0x3;
} else {
data->bypass_attn = ((data->config4 & CONFIG4_ATTN_IN10) >> 4) |
Expand Down

0 comments on commit 2ecff39

Please sign in to comment.