aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/chips/lm83.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/chips/lm83.c')
-rw-r--r--drivers/i2c/chips/lm83.c160
1 files changed, 78 insertions, 82 deletions
diff --git a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c
index 4d6d7d21e14b..a49008b444c8 100644
--- a/drivers/i2c/chips/lm83.c
+++ b/drivers/i2c/chips/lm83.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * lm83.c - Part of lm_sensors, Linux kernel modules for hardware 2 * lm83.c - Part of lm_sensors, Linux kernel modules for hardware
3 * monitoring 3 * monitoring
4 * Copyright (C) 2003 Jean Delvare <khali@linux-fr.org> 4 * Copyright (C) 2003-2005 Jean Delvare <khali@linux-fr.org>
5 * 5 *
6 * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is 6 * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is
7 * a sensor chip made by National Semiconductor. It reports up to four 7 * a sensor chip made by National Semiconductor. It reports up to four
@@ -27,13 +27,13 @@
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
34#include <linux/jiffies.h> 33#include <linux/jiffies.h>
35#include <linux/i2c.h> 34#include <linux/i2c.h>
36#include <linux/i2c-sensor.h> 35#include <linux/i2c-sensor.h>
36#include <linux/hwmon-sysfs.h>
37 37
38/* 38/*
39 * Addresses to scan 39 * Addresses to scan
@@ -81,7 +81,7 @@ SENSORS_INSMOD_1(lm83);
81 81
82/* 82/*
83 * Conversions and various macros 83 * Conversions and various macros
84 * The LM83 uses signed 8-bit values with LSB = 1 degree Celcius. 84 * The LM83 uses signed 8-bit values with LSB = 1 degree Celsius.
85 */ 85 */
86 86
87#define TEMP_FROM_REG(val) ((val) * 1000) 87#define TEMP_FROM_REG(val) ((val) * 1000)
@@ -94,21 +94,20 @@ static const u8 LM83_REG_R_TEMP[] = {
94 LM83_REG_R_LOCAL_TEMP, 94 LM83_REG_R_LOCAL_TEMP,
95 LM83_REG_R_REMOTE1_TEMP, 95 LM83_REG_R_REMOTE1_TEMP,
96 LM83_REG_R_REMOTE2_TEMP, 96 LM83_REG_R_REMOTE2_TEMP,
97 LM83_REG_R_REMOTE3_TEMP 97 LM83_REG_R_REMOTE3_TEMP,
98};
99
100static const u8 LM83_REG_R_HIGH[] = {
101 LM83_REG_R_LOCAL_HIGH, 98 LM83_REG_R_LOCAL_HIGH,
102 LM83_REG_R_REMOTE1_HIGH, 99 LM83_REG_R_REMOTE1_HIGH,
103 LM83_REG_R_REMOTE2_HIGH, 100 LM83_REG_R_REMOTE2_HIGH,
104 LM83_REG_R_REMOTE3_HIGH 101 LM83_REG_R_REMOTE3_HIGH,
102 LM83_REG_R_TCRIT,
105}; 103};
106 104
107static const u8 LM83_REG_W_HIGH[] = { 105static const u8 LM83_REG_W_HIGH[] = {
108 LM83_REG_W_LOCAL_HIGH, 106 LM83_REG_W_LOCAL_HIGH,
109 LM83_REG_W_REMOTE1_HIGH, 107 LM83_REG_W_REMOTE1_HIGH,
110 LM83_REG_W_REMOTE2_HIGH, 108 LM83_REG_W_REMOTE2_HIGH,
111 LM83_REG_W_REMOTE3_HIGH 109 LM83_REG_W_REMOTE3_HIGH,
110 LM83_REG_W_TCRIT,
112}; 111};
113 112
114/* 113/*
@@ -144,9 +143,9 @@ struct lm83_data {
144 unsigned long last_updated; /* in jiffies */ 143 unsigned long last_updated; /* in jiffies */
145 144
146 /* registers values */ 145 /* registers values */
147 s8 temp_input[4]; 146 s8 temp[9]; /* 0..3: input 1-4,
148 s8 temp_high[4]; 147 4..7: high limit 1-4,
149 s8 temp_crit; 148 8 : critical limit */
150 u16 alarms; /* bitvector, combined */ 149 u16 alarms; /* bitvector, combined */
151}; 150};
152 151
@@ -154,65 +153,55 @@ struct lm83_data {
154 * Sysfs stuff 153 * Sysfs stuff
155 */ 154 */
156 155
157#define show_temp(suffix, value) \ 156static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
158static ssize_t show_temp_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \ 157 char *buf)
159{ \ 158{
160 struct lm83_data *data = lm83_update_device(dev); \ 159 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
161 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \ 160 struct lm83_data *data = lm83_update_device(dev);
161 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
162} 162}
163show_temp(input1, temp_input[0]); 163
164show_temp(input2, temp_input[1]); 164static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
165show_temp(input3, temp_input[2]); 165 const char *buf, size_t count)
166show_temp(input4, temp_input[3]); 166{
167show_temp(high1, temp_high[0]); 167 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
168show_temp(high2, temp_high[1]); 168 struct i2c_client *client = to_i2c_client(dev);
169show_temp(high3, temp_high[2]); 169 struct lm83_data *data = i2c_get_clientdata(client);
170show_temp(high4, temp_high[3]); 170 long val = simple_strtol(buf, NULL, 10);
171show_temp(crit, temp_crit); 171 int nr = attr->index;
172 172
173#define set_temp(suffix, value, reg) \ 173 down(&data->update_lock);
174static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ 174 data->temp[nr] = TEMP_TO_REG(val);
175 size_t count) \ 175 i2c_smbus_write_byte_data(client, LM83_REG_W_HIGH[nr - 4],
176{ \ 176 data->temp[nr]);
177 struct i2c_client *client = to_i2c_client(dev); \ 177 up(&data->update_lock);
178 struct lm83_data *data = i2c_get_clientdata(client); \ 178 return count;
179 long val = simple_strtol(buf, NULL, 10); \
180 \
181 down(&data->update_lock); \
182 data->value = TEMP_TO_REG(val); \
183 i2c_smbus_write_byte_data(client, reg, data->value); \
184 up(&data->update_lock); \
185 return count; \
186} 179}
187set_temp(high1, temp_high[0], LM83_REG_W_LOCAL_HIGH);
188set_temp(high2, temp_high[1], LM83_REG_W_REMOTE1_HIGH);
189set_temp(high3, temp_high[2], LM83_REG_W_REMOTE2_HIGH);
190set_temp(high4, temp_high[3], LM83_REG_W_REMOTE3_HIGH);
191set_temp(crit, temp_crit, LM83_REG_W_TCRIT);
192 180
193static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) 181static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
182 char *buf)
194{ 183{
195 struct lm83_data *data = lm83_update_device(dev); 184 struct lm83_data *data = lm83_update_device(dev);
196 return sprintf(buf, "%d\n", data->alarms); 185 return sprintf(buf, "%d\n", data->alarms);
197} 186}
198 187
199static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); 188static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
200static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL); 189static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
201static DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_input3, NULL); 190static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
202static DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_input4, NULL); 191static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3);
203static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_high1, 192static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp,
204 set_temp_high1); 193 set_temp, 4);
205static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_high2, 194static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp,
206 set_temp_high2); 195 set_temp, 5);
207static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_high3, 196static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp,
208 set_temp_high3); 197 set_temp, 6);
209static DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_high4, 198static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp,
210 set_temp_high4); 199 set_temp, 7);
211static DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL); 200static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, 8);
212static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL); 201static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp, NULL, 8);
213static DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp_crit, 202static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp,
214 set_temp_crit); 203 set_temp, 8);
215static DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL); 204static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp, NULL, 8);
216static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 205static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
217 206
218/* 207/*
@@ -323,18 +312,30 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
323 */ 312 */
324 313
325 /* Register sysfs hooks */ 314 /* Register sysfs hooks */
326 device_create_file(&new_client->dev, &dev_attr_temp1_input); 315 device_create_file(&new_client->dev,
327 device_create_file(&new_client->dev, &dev_attr_temp2_input); 316 &sensor_dev_attr_temp1_input.dev_attr);
328 device_create_file(&new_client->dev, &dev_attr_temp3_input); 317 device_create_file(&new_client->dev,
329 device_create_file(&new_client->dev, &dev_attr_temp4_input); 318 &sensor_dev_attr_temp2_input.dev_attr);
330 device_create_file(&new_client->dev, &dev_attr_temp1_max); 319 device_create_file(&new_client->dev,
331 device_create_file(&new_client->dev, &dev_attr_temp2_max); 320 &sensor_dev_attr_temp3_input.dev_attr);
332 device_create_file(&new_client->dev, &dev_attr_temp3_max); 321 device_create_file(&new_client->dev,
333 device_create_file(&new_client->dev, &dev_attr_temp4_max); 322 &sensor_dev_attr_temp4_input.dev_attr);
334 device_create_file(&new_client->dev, &dev_attr_temp1_crit); 323 device_create_file(&new_client->dev,
335 device_create_file(&new_client->dev, &dev_attr_temp2_crit); 324 &sensor_dev_attr_temp1_max.dev_attr);
336 device_create_file(&new_client->dev, &dev_attr_temp3_crit); 325 device_create_file(&new_client->dev,
337 device_create_file(&new_client->dev, &dev_attr_temp4_crit); 326 &sensor_dev_attr_temp2_max.dev_attr);
327 device_create_file(&new_client->dev,
328 &sensor_dev_attr_temp3_max.dev_attr);
329 device_create_file(&new_client->dev,
330 &sensor_dev_attr_temp4_max.dev_attr);
331 device_create_file(&new_client->dev,
332 &sensor_dev_attr_temp1_crit.dev_attr);
333 device_create_file(&new_client->dev,
334 &sensor_dev_attr_temp2_crit.dev_attr);
335 device_create_file(&new_client->dev,
336 &sensor_dev_attr_temp3_crit.dev_attr);
337 device_create_file(&new_client->dev,
338 &sensor_dev_attr_temp4_crit.dev_attr);
338 device_create_file(&new_client->dev, &dev_attr_alarms); 339 device_create_file(&new_client->dev, &dev_attr_alarms);
339 340
340 return 0; 341 return 0;
@@ -370,16 +371,11 @@ static struct lm83_data *lm83_update_device(struct device *dev)
370 int nr; 371 int nr;
371 372
372 dev_dbg(&client->dev, "Updating lm83 data.\n"); 373 dev_dbg(&client->dev, "Updating lm83 data.\n");
373 for (nr = 0; nr < 4 ; nr++) { 374 for (nr = 0; nr < 9; nr++) {
374 data->temp_input[nr] = 375 data->temp[nr] =
375 i2c_smbus_read_byte_data(client, 376 i2c_smbus_read_byte_data(client,
376 LM83_REG_R_TEMP[nr]); 377 LM83_REG_R_TEMP[nr]);
377 data->temp_high[nr] =
378 i2c_smbus_read_byte_data(client,
379 LM83_REG_R_HIGH[nr]);
380 } 378 }
381 data->temp_crit =
382 i2c_smbus_read_byte_data(client, LM83_REG_R_TCRIT);
383 data->alarms = 379 data->alarms =
384 i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1) 380 i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1)
385 + (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2) 381 + (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2)