[devices]: enable sonic-platform-modules-cel

This commit is contained in:
Guohan Lu 2018-02-16 03:53:12 +00:00
parent f489bea105
commit ec9dc57704
7 changed files with 351 additions and 339 deletions

View File

@ -6,7 +6,7 @@ include $(PLATFORM_PATH)/platform-modules-dell.mk
include $(PLATFORM_PATH)/platform-modules-ingrasys.mk include $(PLATFORM_PATH)/platform-modules-ingrasys.mk
include $(PLATFORM_PATH)/platform-modules-accton.mk include $(PLATFORM_PATH)/platform-modules-accton.mk
include $(PLATFORM_PATH)/platform-modules-inventec.mk include $(PLATFORM_PATH)/platform-modules-inventec.mk
#include $(PLATFORM_PATH)/platform-modules-cel.mk include $(PLATFORM_PATH)/platform-modules-cel.mk
#include $(PLATFORM_PATH)/platform-modules-delta.mk #include $(PLATFORM_PATH)/platform-modules-delta.mk
include $(PLATFORM_PATH)/platform-modules-quanta.mk include $(PLATFORM_PATH)/platform-modules-quanta.mk
#include $(PLATFORM_PATH)/platform-modules-mitac.mk #include $(PLATFORM_PATH)/platform-modules-mitac.mk

View File

@ -7,6 +7,9 @@
# Precompiled Headers # Precompiled Headers
*.gch *.gch
*.pch *.pch
*.mod.c
*.ko.cmd
*.o.cmd
# Libraries # Libraries
*.lib *.lib

View File

@ -7,6 +7,6 @@ Standards-Version: 3.9.3
Package: platform-modules-dx010 Package: platform-modules-dx010
Architecture: amd64 Architecture: amd64
Depends: linux-image-3.16.0-5-amd64 Depends: linux-image-4.9.0-5-amd64
Description: kernel modules for platform devices such as fan, led, sfp Description: kernel modules for platform devices such as fan, led, sfp

View File

View File

@ -1 +1,6 @@
obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o lm75.o obj-m := dx010_cpld.o mc24lc64t.o emc2305.o dx010_wdt.o leds-dx010.o lm75.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean

View File

@ -37,50 +37,50 @@
*/ */
enum lm75_type { /* keep sorted in alphabetical order */ enum lm75_type { /* keep sorted in alphabetical order */
adt75, adt75,
ds1775, ds1775,
ds75, ds75,
ds7505, ds7505,
g751, g751,
lm75, lm75,
lm75a, lm75a,
lm75b, lm75b,
max6625, max6625,
max6626, max6626,
mcp980x, mcp980x,
stds75, stds75,
tcn75, tcn75,
tmp100, tmp100,
tmp101, tmp101,
tmp105, tmp105,
tmp112, tmp112,
tmp175, tmp175,
tmp275, tmp275,
tmp75, tmp75,
}; };
/* Addresses scanned */ /* Addresses scanned */
static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
/* The LM75 registers */ /* The LM75 registers */
#define LM75_REG_CONF 0x01 #define LM75_REG_CONF 0x01
static const u8 LM75_REG_TEMP[3] = { static const u8 LM75_REG_TEMP[3] = {
0x00, /* input */ 0x00, /* input */
0x03, /* max */ 0x03, /* max */
0x02, /* hyst */ 0x02, /* hyst */
}; };
/* Each client has this additional data */ /* Each client has this additional data */
struct lm75_data { struct lm75_data {
struct i2c_client *client; struct i2c_client *client;
struct device *hwmon_dev; struct device *hwmon_dev;
struct thermal_zone_device *tz; struct thermal_zone_device *tz;
struct mutex update_lock; struct mutex update_lock;
u8 orig_conf; u8 orig_conf;
u8 resolution; /* In bits, between 9 and 12 */ u8 resolution; /* In bits, between 9 and 12 */
u8 resolution_limits; u8 resolution_limits;
char valid; /* !=0 if registers are valid */ char valid; /* !=0 if registers are valid */
unsigned long last_updated; /* In jiffies */ unsigned long last_updated; /* In jiffies */
unsigned long sample_time; /* In jiffies */ unsigned long sample_time; /* In jiffies */
@ -88,276 +88,280 @@ struct lm75_data {
0 = input 0 = input
1 = max 1 = max
2 = hyst */ 2 = hyst */
}; };
static int lm75_read_value(struct i2c_client *client, u8 reg); static int lm75_read_value(struct i2c_client *client, u8 reg);
static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value); static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
static struct lm75_data *lm75_update_device(struct device *dev); static struct lm75_data *lm75_update_device(struct device *dev);
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static inline long lm75_reg_to_mc(s16 temp, u8 resolution) static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
{ {
return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
} }
/* sysfs attributes for hwmon */ /* sysfs attributes for hwmon */
static int lm75_read_temp(void *dev, long *temp) static int lm75_read_temp(void *dev, int *temp)
{ {
struct lm75_data *data = lm75_update_device(dev); struct lm75_data *data = lm75_update_device(dev);
if (IS_ERR(data)) if (IS_ERR(data))
return PTR_ERR(data); return PTR_ERR(data);
*temp = lm75_reg_to_mc(data->temp[0], data->resolution); *temp = lm75_reg_to_mc(data->temp[0], data->resolution);
return 0; return 0;
} }
static ssize_t show_temp(struct device *dev, struct device_attribute *da, static ssize_t show_temp(struct device *dev, struct device_attribute *da,
char *buf) char *buf)
{ {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm75_data *data = lm75_update_device(dev); struct lm75_data *data = lm75_update_device(dev);
if (IS_ERR(data)) if (IS_ERR(data))
return PTR_ERR(data); return PTR_ERR(data);
return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index], return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index],
data->resolution)); data->resolution));
} }
static ssize_t set_temp(struct device *dev, struct device_attribute *da, static ssize_t set_temp(struct device *dev, struct device_attribute *da,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm75_data *data = dev_get_drvdata(dev); struct lm75_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client; struct i2c_client *client = data->client;
int nr = attr->index; int nr = attr->index;
long temp; long temp;
int error; int error;
u8 resolution; u8 resolution;
error = kstrtol(buf, 10, &temp); error = kstrtol(buf, 10, &temp);
if (error) if (error)
return error; return error;
/* /*
* Resolution of limit registers is assumed to be the same as the * Resolution of limit registers is assumed to be the same as the
* temperature input register resolution unless given explicitly. * temperature input register resolution unless given explicitly.
*/ */
if (attr->index && data->resolution_limits) if (attr->index && data->resolution_limits)
resolution = data->resolution_limits; resolution = data->resolution_limits;
else else
resolution = data->resolution; resolution = data->resolution;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
data->temp[nr] = DIV_ROUND_CLOSEST(temp << (resolution - 8), data->temp[nr] = DIV_ROUND_CLOSEST(temp << (resolution - 8),
1000) << (16 - resolution); 1000) << (16 - resolution);
lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]);
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return count; return count;
} }
static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
show_temp, set_temp, 1); show_temp, set_temp, 1);
static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
show_temp, set_temp, 2); show_temp, set_temp, 2);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
static struct attribute *lm75_attrs[] = { static struct attribute *lm75_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr, &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
NULL NULL
}; };
ATTRIBUTE_GROUPS(lm75); ATTRIBUTE_GROUPS(lm75);
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = {
.get_temp = lm75_read_temp,
};
/* device probe and removal */ /* device probe and removal */
static int static int
lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
{ {
struct device *dev = &client->dev; struct device *dev = &client->dev;
struct lm75_data *data; struct lm75_data *data;
int status; int status;
u8 set_mask, clr_mask; u8 set_mask, clr_mask;
int new; int new;
enum lm75_type kind = id->driver_data; enum lm75_type kind = id->driver_data;
if (!i2c_check_functionality(client->adapter, if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
return -EIO; return -EIO;
data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL); data = devm_kzalloc(dev, sizeof(struct lm75_data), GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
data->client = client; data->client = client;
i2c_set_clientdata(client, data); i2c_set_clientdata(client, data);
mutex_init(&data->update_lock); mutex_init(&data->update_lock);
/* Set to LM75 resolution (9 bits, 1/2 degree C) and range. /* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
* Then tweak to be more precise when appropriate. * Then tweak to be more precise when appropriate.
*/ */
set_mask = 0; set_mask = 0;
clr_mask = LM75_SHUTDOWN; /* continuous conversions */ clr_mask = LM75_SHUTDOWN; /* continuous conversions */
switch (kind) { switch (kind) {
case adt75: case adt75:
clr_mask |= 1 << 5; /* not one-shot mode */ clr_mask |= 1 << 5; /* not one-shot mode */
data->resolution = 12; data->resolution = 12;
data->sample_time = HZ / 8; data->sample_time = HZ / 8;
break; break;
case ds1775: case ds1775:
case ds75: case ds75:
case stds75: case stds75:
clr_mask |= 3 << 5; clr_mask |= 3 << 5;
set_mask |= 2 << 5; /* 11-bit mode */ set_mask |= 2 << 5; /* 11-bit mode */
data->resolution = 11; data->resolution = 11;
data->sample_time = HZ; data->sample_time = HZ;
break; break;
case ds7505: case ds7505:
set_mask |= 3 << 5; /* 12-bit mode */ set_mask |= 3 << 5; /* 12-bit mode */
data->resolution = 12; data->resolution = 12;
data->sample_time = HZ / 4; data->sample_time = HZ / 4;
break; break;
case g751: case g751:
case lm75: case lm75:
case lm75a: case lm75a:
data->resolution = 9; data->resolution = 9;
data->sample_time = HZ / 2; data->sample_time = HZ / 2;
break; break;
case lm75b: case lm75b:
data->resolution = 11; data->resolution = 11;
data->sample_time = HZ / 4; data->sample_time = HZ / 4;
break; break;
case max6625: case max6625:
data->resolution = 9; data->resolution = 9;
data->sample_time = HZ / 4; data->sample_time = HZ / 4;
break; break;
case max6626: case max6626:
data->resolution = 12; data->resolution = 12;
data->resolution_limits = 9; data->resolution_limits = 9;
data->sample_time = HZ / 4; data->sample_time = HZ / 4;
break; break;
case tcn75: case tcn75:
data->resolution = 9; data->resolution = 9;
data->sample_time = HZ / 8; data->sample_time = HZ / 8;
break; break;
case mcp980x: case mcp980x:
data->resolution_limits = 9; data->resolution_limits = 9;
/* fall through */ /* fall through */
case tmp100: case tmp100:
case tmp101: case tmp101:
set_mask |= 3 << 5; /* 12-bit mode */ set_mask |= 3 << 5; /* 12-bit mode */
data->resolution = 12; data->resolution = 12;
data->sample_time = HZ; data->sample_time = HZ;
clr_mask |= 1 << 7; /* not one-shot mode */ clr_mask |= 1 << 7; /* not one-shot mode */
break; break;
case tmp112: case tmp112:
set_mask |= 3 << 5; /* 12-bit mode */ set_mask |= 3 << 5; /* 12-bit mode */
clr_mask |= 1 << 7; /* not one-shot mode */ clr_mask |= 1 << 7; /* not one-shot mode */
data->resolution = 12; data->resolution = 12;
data->sample_time = HZ / 4; data->sample_time = HZ / 4;
break; break;
case tmp105: case tmp105:
case tmp175: case tmp175:
case tmp275: case tmp275:
case tmp75: case tmp75:
set_mask |= 3 << 5; /* 12-bit mode */ set_mask |= 3 << 5; /* 12-bit mode */
clr_mask |= 1 << 7; /* not one-shot mode */ clr_mask |= 1 << 7; /* not one-shot mode */
data->resolution = 12; data->resolution = 12;
data->sample_time = HZ / 2; data->sample_time = HZ / 2;
break; break;
} }
/* configure as specified */ /* configure as specified */
status = lm75_read_value(client, LM75_REG_CONF); status = lm75_read_value(client, LM75_REG_CONF);
if (status < 0) { if (status < 0) {
dev_dbg(dev, "Can't read config? %d\n", status); dev_dbg(dev, "Can't read config? %d\n", status);
return status; return status;
}
data->orig_conf = status;
new = status & ~clr_mask;
new |= set_mask;
if (status != new)
lm75_write_value(client, LM75_REG_CONF, new);
dev_dbg(dev, "Config %02x\n", new);
data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
data, lm75_groups);
if (IS_ERR(data->hwmon_dev))
return PTR_ERR(data->hwmon_dev);
data->tz = thermal_zone_of_sensor_register(data->hwmon_dev,
0,
data->hwmon_dev,
&lm75_of_thermal_ops);
if (IS_ERR(data->tz))
data->tz = NULL;
dev_info(dev, "%s: sensor '%s'\n",
dev_name(data->hwmon_dev), client->name);
return 0;
} }
data->orig_conf = status;
new = status & ~clr_mask;
new |= set_mask;
if (status != new)
lm75_write_value(client, LM75_REG_CONF, new);
dev_dbg(dev, "Config %02x\n", new);
data->hwmon_dev = hwmon_device_register_with_groups(dev, client->name, static int lm75_remove(struct i2c_client *client)
data, lm75_groups); {
if (IS_ERR(data->hwmon_dev)) struct lm75_data *data = i2c_get_clientdata(client);
return PTR_ERR(data->hwmon_dev);
data->tz = thermal_zone_of_sensor_register(data->hwmon_dev, thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz);
0, hwmon_device_unregister(data->hwmon_dev);
data->hwmon_dev, lm75_write_value(client, LM75_REG_CONF, data->orig_conf);
lm75_read_temp, NULL); return 0;
if (IS_ERR(data->tz)) }
data->tz = NULL;
dev_info(dev, "%s: sensor '%s'\n", static const struct i2c_device_id lm75_ids[] = {
dev_name(data->hwmon_dev), client->name); { "adt75", adt75, },
{ "ds1775", ds1775, },
return 0; { "ds75", ds75, },
} { "ds7505", ds7505, },
{ "g751", g751, },
static int lm75_remove(struct i2c_client *client) { "lm75", lm75, },
{ { "lm75a", lm75a, },
struct lm75_data *data = i2c_get_clientdata(client); { "dx010_lm75b", lm75b, },
{ "max6625", max6625, },
thermal_zone_of_sensor_unregister(data->hwmon_dev, data->tz); { "max6626", max6626, },
hwmon_device_unregister(data->hwmon_dev); { "mcp980x", mcp980x, },
lm75_write_value(client, LM75_REG_CONF, data->orig_conf); { "stds75", stds75, },
return 0; { "tcn75", tcn75, },
} { "tmp100", tmp100, },
{ "tmp101", tmp101, },
static const struct i2c_device_id lm75_ids[] = { { "tmp105", tmp105, },
{ "adt75", adt75, }, { "tmp112", tmp112, },
{ "ds1775", ds1775, }, { "tmp175", tmp175, },
{ "ds75", ds75, }, { "tmp275", tmp275, },
{ "ds7505", ds7505, }, { "tmp75", tmp75, },
{ "g751", g751, },
{ "lm75", lm75, },
{ "lm75a", lm75a, },
{ "dx010_lm75b", lm75b, },
{ "max6625", max6625, },
{ "max6626", max6626, },
{ "mcp980x", mcp980x, },
{ "stds75", stds75, },
{ "tcn75", tcn75, },
{ "tmp100", tmp100, },
{ "tmp101", tmp101, },
{ "tmp105", tmp105, },
{ "tmp112", tmp112, },
{ "tmp175", tmp175, },
{ "tmp275", tmp275, },
{ "tmp75", tmp75, },
{ /* LIST END */ } { /* LIST END */ }
}; };
MODULE_DEVICE_TABLE(i2c, lm75_ids); MODULE_DEVICE_TABLE(i2c, lm75_ids);
#define LM75A_ID 0xA1 #define LM75A_ID 0xA1
/* Return 0 if detection is successful, -ENODEV otherwise */ /* Return 0 if detection is successful, -ENODEV otherwise */
static int lm75_detect(struct i2c_client *new_client, static int lm75_detect(struct i2c_client *new_client,
struct i2c_board_info *info) struct i2c_board_info *info)
{ {
struct i2c_adapter *adapter = new_client->adapter; struct i2c_adapter *adapter = new_client->adapter;
int i; int i;
int conf, hyst, os; int conf, hyst, os;
bool is_lm75a = 0; bool is_lm75a = 0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA)) I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV; return -ENODEV;
/* /*
* Now, we do the remaining detection. There is no identification- * Now, we do the remaining detection. There is no identification-
@ -385,105 +389,105 @@ static int lm75_detect(struct i2c_client *new_client,
*/ */
/* Unused bits */ /* Unused bits */
conf = i2c_smbus_read_byte_data(new_client, 1); conf = i2c_smbus_read_byte_data(new_client, 1);
if (conf & 0xe0) if (conf & 0xe0)
return -ENODEV; return -ENODEV;
/* First check for LM75A */ /* First check for LM75A */
if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) {
/* LM75A returns 0xff on unused registers so /* LM75A returns 0xff on unused registers so
just to be sure we check for that too. */ just to be sure we check for that too. */
if (i2c_smbus_read_byte_data(new_client, 4) != 0xff if (i2c_smbus_read_byte_data(new_client, 4) != 0xff
|| i2c_smbus_read_byte_data(new_client, 5) != 0xff || i2c_smbus_read_byte_data(new_client, 5) != 0xff
|| i2c_smbus_read_byte_data(new_client, 6) != 0xff) || i2c_smbus_read_byte_data(new_client, 6) != 0xff)
return -ENODEV; return -ENODEV;
is_lm75a = 1; is_lm75a = 1;
hyst = i2c_smbus_read_byte_data(new_client, 2); hyst = i2c_smbus_read_byte_data(new_client, 2);
os = i2c_smbus_read_byte_data(new_client, 3); os = i2c_smbus_read_byte_data(new_client, 3);
} else { /* Traditional style LM75 detection */ } else { /* Traditional style LM75 detection */
/* Unused addresses */ /* Unused addresses */
hyst = i2c_smbus_read_byte_data(new_client, 2); hyst = i2c_smbus_read_byte_data(new_client, 2);
if (i2c_smbus_read_byte_data(new_client, 4) != hyst if (i2c_smbus_read_byte_data(new_client, 4) != hyst
|| i2c_smbus_read_byte_data(new_client, 5) != hyst || i2c_smbus_read_byte_data(new_client, 5) != hyst
|| i2c_smbus_read_byte_data(new_client, 6) != hyst || i2c_smbus_read_byte_data(new_client, 6) != hyst
|| i2c_smbus_read_byte_data(new_client, 7) != hyst) || i2c_smbus_read_byte_data(new_client, 7) != hyst)
return -ENODEV; return -ENODEV;
os = i2c_smbus_read_byte_data(new_client, 3); os = i2c_smbus_read_byte_data(new_client, 3);
if (i2c_smbus_read_byte_data(new_client, 4) != os if (i2c_smbus_read_byte_data(new_client, 4) != os
|| i2c_smbus_read_byte_data(new_client, 5) != os || i2c_smbus_read_byte_data(new_client, 5) != os
|| i2c_smbus_read_byte_data(new_client, 6) != os || i2c_smbus_read_byte_data(new_client, 6) != os
|| i2c_smbus_read_byte_data(new_client, 7) != os) || i2c_smbus_read_byte_data(new_client, 7) != os)
return -ENODEV; return -ENODEV;
} }
/* Addresses cycling */ /* Addresses cycling */
for (i = 8; i <= 248; i += 40) { for (i = 8; i <= 248; i += 40) {
if (i2c_smbus_read_byte_data(new_client, i + 1) != conf if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
|| i2c_smbus_read_byte_data(new_client, i + 2) != hyst || i2c_smbus_read_byte_data(new_client, i + 2) != hyst
|| i2c_smbus_read_byte_data(new_client, i + 3) != os) || i2c_smbus_read_byte_data(new_client, i + 3) != os)
return -ENODEV; return -ENODEV;
if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7)
!= LM75A_ID) != LM75A_ID)
return -ENODEV; return -ENODEV;
}
strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE);
return 0;
} }
strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE);
return 0;
}
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int lm75_suspend(struct device *dev) static int lm75_suspend(struct device *dev)
{ {
int status; int status;
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
status = lm75_read_value(client, LM75_REG_CONF); status = lm75_read_value(client, LM75_REG_CONF);
if (status < 0) { if (status < 0) {
dev_dbg(&client->dev, "Can't read config? %d\n", status); dev_dbg(&client->dev, "Can't read config? %d\n", status);
return status; return status;
}
status = status | LM75_SHUTDOWN;
lm75_write_value(client, LM75_REG_CONF, status);
return 0;
} }
status = status | LM75_SHUTDOWN;
lm75_write_value(client, LM75_REG_CONF, status);
return 0;
}
static int lm75_resume(struct device *dev) static int lm75_resume(struct device *dev)
{ {
int status; int status;
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
status = lm75_read_value(client, LM75_REG_CONF); status = lm75_read_value(client, LM75_REG_CONF);
if (status < 0) { if (status < 0) {
dev_dbg(&client->dev, "Can't read config? %d\n", status); dev_dbg(&client->dev, "Can't read config? %d\n", status);
return status; return status;
}
status = status & ~LM75_SHUTDOWN;
lm75_write_value(client, LM75_REG_CONF, status);
return 0;
} }
status = status & ~LM75_SHUTDOWN;
lm75_write_value(client, LM75_REG_CONF, status);
return 0;
}
static const struct dev_pm_ops lm75_dev_pm_ops = { static const struct dev_pm_ops lm75_dev_pm_ops = {
.suspend = lm75_suspend, .suspend = lm75_suspend,
.resume = lm75_resume, .resume = lm75_resume,
}; };
#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops) #define LM75_DEV_PM_OPS (&lm75_dev_pm_ops)
#else #else
#define LM75_DEV_PM_OPS NULL #define LM75_DEV_PM_OPS NULL
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
static struct i2c_driver lm75_driver = { static struct i2c_driver lm75_driver = {
.class = I2C_CLASS_HWMON, .class = I2C_CLASS_HWMON,
.driver = { .driver = {
.name = "dx010_lm75", .name = "dx010_lm75",
.pm = LM75_DEV_PM_OPS, .pm = LM75_DEV_PM_OPS,
}, },
.probe = lm75_probe, .probe = lm75_probe,
.remove = lm75_remove, .remove = lm75_remove,
.id_table = lm75_ids, .id_table = lm75_ids,
/* /*
.detect = lm75_detect, .detect = lm75_detect,
.address_list = normal_i2c, .address_list = normal_i2c,
*/ */
}; };
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -494,33 +498,33 @@ static struct i2c_driver lm75_driver = {
* LM75 uses a high-byte first convention, which is exactly opposite to * LM75 uses a high-byte first convention, which is exactly opposite to
* the SMBus standard. * the SMBus standard.
*/ */
static int lm75_read_value(struct i2c_client *client, u8 reg) static int lm75_read_value(struct i2c_client *client, u8 reg)
{ {
if (reg == LM75_REG_CONF) if (reg == LM75_REG_CONF)
return i2c_smbus_read_byte_data(client, reg); return i2c_smbus_read_byte_data(client, reg);
else else
return i2c_smbus_read_word_swapped(client, reg); return i2c_smbus_read_word_swapped(client, reg);
} }
static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
{ {
if (reg == LM75_REG_CONF) if (reg == LM75_REG_CONF)
return i2c_smbus_write_byte_data(client, reg, value); return i2c_smbus_write_byte_data(client, reg, value);
else else
return i2c_smbus_write_word_swapped(client, reg, value); return i2c_smbus_write_word_swapped(client, reg, value);
} }
static struct lm75_data *lm75_update_device(struct device *dev) static struct lm75_data *lm75_update_device(struct device *dev)
{ {
struct lm75_data *data = dev_get_drvdata(dev); struct lm75_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client; struct i2c_client *client = data->client;
struct lm75_data *ret = data; struct lm75_data *ret = data;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + data->sample_time) if (time_after(jiffies, data->last_updated + data->sample_time)
|| !data->valid) { || !data->valid) {
int i; int i;
dev_dbg(&client->dev, "Starting lm75 update\n"); dev_dbg(&client->dev, "Starting lm75 update\n");
for (i = 0; i < ARRAY_SIZE(data->temp); i++) { for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
@ -541,7 +545,7 @@ static struct lm75_data *lm75_update_device(struct device *dev)
data->valid = 1; data->valid = 1;
} }
abort: abort:
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
return ret; return ret;
} }

View File

@ -46,4 +46,4 @@ static inline int LM75_TEMP_FROM_REG(u16 reg)
/* use integer division instead of equivalent right shift to /* use integer division instead of equivalent right shift to
guarantee arithmetic shift and preserve the sign */ guarantee arithmetic shift and preserve the sign */
return ((s16)reg / 128) * 500; return ((s16)reg / 128) * 500;
} }