提交 8b662f38 编写于 作者: S Sven Schuchmann 提交者: Guenter Roeck

hwmon: (mcp3021) Prepare MCP3021 driver to support other chips

This Patch is to prepare the MCP3021 driver to support
other chips like the MCP3221. The hard defined chip data
is now stored within the data struct of each chip.
Signed-off-by: NSven Schuchmann <schuchmann@schleissheimer.de>
Signed-off-by: NGuenter Roeck <linux@roeck-us.net>
上级 a9169813
......@@ -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
......@@ -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;
......@@ -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,
......@@ -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);
}
......@@ -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)
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册