Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 326210
b: refs/heads/master
c: 8b662f3
h: refs/heads/master
v: v3
  • Loading branch information
Sven Schuchmann authored and Guenter Roeck committed Sep 24, 2012
1 parent 9283355 commit 891d703
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a91698135bef4e945b0eee1b676d6ea5085177dc
refs/heads/master: 8b662f38e066d8fc1b73a8655da547c348206904
33 changes: 26 additions & 7 deletions trunk/drivers/hwmon/mcp3021.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* Copyright (C) 2008-2009, 2012 Freescale Semiconductor, Inc.
* Author: Mingkai Hu <Mingkai.hu@freescale.com>
* Reworked by Sven Schuchmann <schuchmann@schleissheimer.de>
*
* This driver export the value of analog input voltage to sysfs, the
* voltage unit is mV. Through the sysfs interface, lm-sensors tool
Expand Down Expand Up @@ -34,16 +35,24 @@
#define MCP3021_OUTPUT_RES 10 /* 10-bit resolution */
#define MCP3021_OUTPUT_SCALE 4

enum chips {
mcp3021
};
/*
* Client data (each client gets its own)
*/
struct mcp3021_data {
struct device *hwmon_dev;
u32 vdd; /* device power supply */
u16 sar_shift;
u16 sar_mask;
u8 output_res;
u8 output_scale;
};

static int mcp3021_read16(struct i2c_client *client)
{
struct mcp3021_data *data = i2c_get_clientdata(client);
int ret;
u16 reg;
__be16 buf;
Expand All @@ -61,20 +70,20 @@ static int mcp3021_read16(struct i2c_client *client)
* The ten-bit output code is composed of the lower 4-bit of the
* first byte and the upper 6-bit of the second byte.
*/
reg = (reg >> MCP3021_SAR_SHIFT) & MCP3021_SAR_MASK;
reg = (reg >> data->sar_shift) & data->sar_mask;

return reg;
}

static inline u16 volts_from_reg(u16 vdd, u16 val)
static inline u16 volts_from_reg(struct mcp3021_data *data, u16 val)
{
if (val == 0)
return 0;

val = val * MCP3021_OUTPUT_SCALE - MCP3021_OUTPUT_SCALE / 2;
val = val * data->output_scale - data->output_scale / 2;

return val * DIV_ROUND_CLOSEST(vdd,
(1 << MCP3021_OUTPUT_RES) * MCP3021_OUTPUT_SCALE);
return val * DIV_ROUND_CLOSEST(data->vdd,
(1 << data->output_res) * data->output_scale);
}

static ssize_t show_in_input(struct device *dev, struct device_attribute *attr,
Expand All @@ -88,7 +97,8 @@ static ssize_t show_in_input(struct device *dev, struct device_attribute *attr,
if (reg < 0)
return reg;

in_input = volts_from_reg(data->vdd, reg);
in_input = volts_from_reg(data, reg);

return sprintf(buf, "%d\n", in_input);
}

Expand All @@ -110,6 +120,15 @@ static int mcp3021_probe(struct i2c_client *client,

i2c_set_clientdata(client, data);

switch (id->driver_data) {
case mcp3021:
data->sar_shift = MCP3021_SAR_SHIFT;
data->sar_mask = MCP3021_SAR_MASK;
data->output_res = MCP3021_OUTPUT_RES;
data->output_scale = MCP3021_OUTPUT_SCALE;
break;
}

if (client->dev.platform_data) {
data->vdd = *(u32 *)client->dev.platform_data;
if (data->vdd > MCP3021_VDD_MAX || data->vdd < MCP3021_VDD_MIN)
Expand Down Expand Up @@ -145,7 +164,7 @@ static int mcp3021_remove(struct i2c_client *client)
}

static const struct i2c_device_id mcp3021_id[] = {
{ "mcp3021", 0 },
{ "mcp3021", mcp3021 },
{ }
};
MODULE_DEVICE_TABLE(i2c, mcp3021_id);
Expand Down

0 comments on commit 891d703

Please sign in to comment.