Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17

Linux/drivers/hwmon/sch5627.c

  1 /***************************************************************************
  2  *   Copyright (C) 2010-2012 Hans de Goede <hdegoede@redhat.com>           *
  3  *                                                                         *
  4  *   This program is free software; you can redistribute it and/or modify  *
  5  *   it under the terms of the GNU General Public License as published by  *
  6  *   the Free Software Foundation; either version 2 of the License, or     *
  7  *   (at your option) any later version.                                   *
  8  *                                                                         *
  9  *   This program is distributed in the hope that it will be useful,       *
 10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 12  *   GNU General Public License for more details.                          *
 13  *                                                                         *
 14  *   You should have received a copy of the GNU General Public License     *
 15  *   along with this program; if not, write to the                         *
 16  *   Free Software Foundation, Inc.,                                       *
 17  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 18  ***************************************************************************/
 19 
 20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 21 
 22 #include <linux/module.h>
 23 #include <linux/init.h>
 24 #include <linux/slab.h>
 25 #include <linux/jiffies.h>
 26 #include <linux/platform_device.h>
 27 #include <linux/hwmon.h>
 28 #include <linux/hwmon-sysfs.h>
 29 #include <linux/err.h>
 30 #include <linux/mutex.h>
 31 #include "sch56xx-common.h"
 32 
 33 #define DRVNAME "sch5627"
 34 #define DEVNAME DRVNAME /* We only support one model */
 35 
 36 #define SCH5627_HWMON_ID                0xa5
 37 #define SCH5627_COMPANY_ID              0x5c
 38 #define SCH5627_PRIMARY_ID              0xa0
 39 
 40 #define SCH5627_REG_BUILD_CODE          0x39
 41 #define SCH5627_REG_BUILD_ID            0x3a
 42 #define SCH5627_REG_HWMON_ID            0x3c
 43 #define SCH5627_REG_HWMON_REV           0x3d
 44 #define SCH5627_REG_COMPANY_ID          0x3e
 45 #define SCH5627_REG_PRIMARY_ID          0x3f
 46 #define SCH5627_REG_CTRL                0x40
 47 
 48 #define SCH5627_NO_TEMPS                8
 49 #define SCH5627_NO_FANS                 4
 50 #define SCH5627_NO_IN                   5
 51 
 52 static const u16 SCH5627_REG_TEMP_MSB[SCH5627_NO_TEMPS] = {
 53         0x2B, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x180, 0x181 };
 54 static const u16 SCH5627_REG_TEMP_LSN[SCH5627_NO_TEMPS] = {
 55         0xE2, 0xE1, 0xE1, 0xE5, 0xE5, 0xE6, 0x182, 0x182 };
 56 static const u16 SCH5627_REG_TEMP_HIGH_NIBBLE[SCH5627_NO_TEMPS] = {
 57         0, 0, 1, 1, 0, 0, 0, 1 };
 58 static const u16 SCH5627_REG_TEMP_HIGH[SCH5627_NO_TEMPS] = {
 59         0x61, 0x57, 0x59, 0x5B, 0x5D, 0x5F, 0x184, 0x186 };
 60 static const u16 SCH5627_REG_TEMP_ABS[SCH5627_NO_TEMPS] = {
 61         0x9B, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x1A8, 0x1A9 };
 62 
 63 static const u16 SCH5627_REG_FAN[SCH5627_NO_FANS] = {
 64         0x2C, 0x2E, 0x30, 0x32 };
 65 static const u16 SCH5627_REG_FAN_MIN[SCH5627_NO_FANS] = {
 66         0x62, 0x64, 0x66, 0x68 };
 67 
 68 static const u16 SCH5627_REG_IN_MSB[SCH5627_NO_IN] = {
 69         0x22, 0x23, 0x24, 0x25, 0x189 };
 70 static const u16 SCH5627_REG_IN_LSN[SCH5627_NO_IN] = {
 71         0xE4, 0xE4, 0xE3, 0xE3, 0x18A };
 72 static const u16 SCH5627_REG_IN_HIGH_NIBBLE[SCH5627_NO_IN] = {
 73         1, 0, 1, 0, 1 };
 74 static const u16 SCH5627_REG_IN_FACTOR[SCH5627_NO_IN] = {
 75         10745, 3660, 9765, 10745, 3660 };
 76 static const char * const SCH5627_IN_LABELS[SCH5627_NO_IN] = {
 77         "VCC", "VTT", "VBAT", "VTR", "V_IN" };
 78 
 79 struct sch5627_data {
 80         unsigned short addr;
 81         struct device *hwmon_dev;
 82         struct sch56xx_watchdog_data *watchdog;
 83         u8 control;
 84         u8 temp_max[SCH5627_NO_TEMPS];
 85         u8 temp_crit[SCH5627_NO_TEMPS];
 86         u16 fan_min[SCH5627_NO_FANS];
 87 
 88         struct mutex update_lock;
 89         unsigned long last_battery;     /* In jiffies */
 90         char valid;                     /* !=0 if following fields are valid */
 91         unsigned long last_updated;     /* In jiffies */
 92         u16 temp[SCH5627_NO_TEMPS];
 93         u16 fan[SCH5627_NO_FANS];
 94         u16 in[SCH5627_NO_IN];
 95 };
 96 
 97 static struct sch5627_data *sch5627_update_device(struct device *dev)
 98 {
 99         struct sch5627_data *data = dev_get_drvdata(dev);
100         struct sch5627_data *ret = data;
101         int i, val;
102 
103         mutex_lock(&data->update_lock);
104 
105         /* Trigger a Vbat voltage measurement every 5 minutes */
106         if (time_after(jiffies, data->last_battery + 300 * HZ)) {
107                 sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL,
108                                           data->control | 0x10);
109                 data->last_battery = jiffies;
110         }
111 
112         /* Cache the values for 1 second */
113         if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
114                 for (i = 0; i < SCH5627_NO_TEMPS; i++) {
115                         val = sch56xx_read_virtual_reg12(data->addr,
116                                 SCH5627_REG_TEMP_MSB[i],
117                                 SCH5627_REG_TEMP_LSN[i],
118                                 SCH5627_REG_TEMP_HIGH_NIBBLE[i]);
119                         if (unlikely(val < 0)) {
120                                 ret = ERR_PTR(val);
121                                 goto abort;
122                         }
123                         data->temp[i] = val;
124                 }
125 
126                 for (i = 0; i < SCH5627_NO_FANS; i++) {
127                         val = sch56xx_read_virtual_reg16(data->addr,
128                                                          SCH5627_REG_FAN[i]);
129                         if (unlikely(val < 0)) {
130                                 ret = ERR_PTR(val);
131                                 goto abort;
132                         }
133                         data->fan[i] = val;
134                 }
135 
136                 for (i = 0; i < SCH5627_NO_IN; i++) {
137                         val = sch56xx_read_virtual_reg12(data->addr,
138                                 SCH5627_REG_IN_MSB[i],
139                                 SCH5627_REG_IN_LSN[i],
140                                 SCH5627_REG_IN_HIGH_NIBBLE[i]);
141                         if (unlikely(val < 0)) {
142                                 ret = ERR_PTR(val);
143                                 goto abort;
144                         }
145                         data->in[i] = val;
146                 }
147 
148                 data->last_updated = jiffies;
149                 data->valid = 1;
150         }
151 abort:
152         mutex_unlock(&data->update_lock);
153         return ret;
154 }
155 
156 static int sch5627_read_limits(struct sch5627_data *data)
157 {
158         int i, val;
159 
160         for (i = 0; i < SCH5627_NO_TEMPS; i++) {
161                 /*
162                  * Note what SMSC calls ABS, is what lm_sensors calls max
163                  * (aka high), and HIGH is what lm_sensors calls crit.
164                  */
165                 val = sch56xx_read_virtual_reg(data->addr,
166                                                SCH5627_REG_TEMP_ABS[i]);
167                 if (val < 0)
168                         return val;
169                 data->temp_max[i] = val;
170 
171                 val = sch56xx_read_virtual_reg(data->addr,
172                                                SCH5627_REG_TEMP_HIGH[i]);
173                 if (val < 0)
174                         return val;
175                 data->temp_crit[i] = val;
176         }
177         for (i = 0; i < SCH5627_NO_FANS; i++) {
178                 val = sch56xx_read_virtual_reg16(data->addr,
179                                                  SCH5627_REG_FAN_MIN[i]);
180                 if (val < 0)
181                         return val;
182                 data->fan_min[i] = val;
183         }
184 
185         return 0;
186 }
187 
188 static int reg_to_temp(u16 reg)
189 {
190         return (reg * 625) / 10 - 64000;
191 }
192 
193 static int reg_to_temp_limit(u8 reg)
194 {
195         return (reg - 64) * 1000;
196 }
197 
198 static int reg_to_rpm(u16 reg)
199 {
200         if (reg == 0)
201                 return -EIO;
202         if (reg == 0xffff)
203                 return 0;
204 
205         return 5400540 / reg;
206 }
207 
208 static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
209         char *buf)
210 {
211         return snprintf(buf, PAGE_SIZE, "%s\n", DEVNAME);
212 }
213 
214 static ssize_t show_temp(struct device *dev, struct device_attribute
215         *devattr, char *buf)
216 {
217         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
218         struct sch5627_data *data = sch5627_update_device(dev);
219         int val;
220 
221         if (IS_ERR(data))
222                 return PTR_ERR(data);
223 
224         val = reg_to_temp(data->temp[attr->index]);
225         return snprintf(buf, PAGE_SIZE, "%d\n", val);
226 }
227 
228 static ssize_t show_temp_fault(struct device *dev, struct device_attribute
229         *devattr, char *buf)
230 {
231         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
232         struct sch5627_data *data = sch5627_update_device(dev);
233 
234         if (IS_ERR(data))
235                 return PTR_ERR(data);
236 
237         return snprintf(buf, PAGE_SIZE, "%d\n", data->temp[attr->index] == 0);
238 }
239 
240 static ssize_t show_temp_max(struct device *dev, struct device_attribute
241         *devattr, char *buf)
242 {
243         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
244         struct sch5627_data *data = dev_get_drvdata(dev);
245         int val;
246 
247         val = reg_to_temp_limit(data->temp_max[attr->index]);
248         return snprintf(buf, PAGE_SIZE, "%d\n", val);
249 }
250 
251 static ssize_t show_temp_crit(struct device *dev, struct device_attribute
252         *devattr, char *buf)
253 {
254         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
255         struct sch5627_data *data = dev_get_drvdata(dev);
256         int val;
257 
258         val = reg_to_temp_limit(data->temp_crit[attr->index]);
259         return snprintf(buf, PAGE_SIZE, "%d\n", val);
260 }
261 
262 static ssize_t show_fan(struct device *dev, struct device_attribute
263         *devattr, char *buf)
264 {
265         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
266         struct sch5627_data *data = sch5627_update_device(dev);
267         int val;
268 
269         if (IS_ERR(data))
270                 return PTR_ERR(data);
271 
272         val = reg_to_rpm(data->fan[attr->index]);
273         if (val < 0)
274                 return val;
275 
276         return snprintf(buf, PAGE_SIZE, "%d\n", val);
277 }
278 
279 static ssize_t show_fan_fault(struct device *dev, struct device_attribute
280         *devattr, char *buf)
281 {
282         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
283         struct sch5627_data *data = sch5627_update_device(dev);
284 
285         if (IS_ERR(data))
286                 return PTR_ERR(data);
287 
288         return snprintf(buf, PAGE_SIZE, "%d\n",
289                         data->fan[attr->index] == 0xffff);
290 }
291 
292 static ssize_t show_fan_min(struct device *dev, struct device_attribute
293         *devattr, char *buf)
294 {
295         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
296         struct sch5627_data *data = dev_get_drvdata(dev);
297         int val = reg_to_rpm(data->fan_min[attr->index]);
298         if (val < 0)
299                 return val;
300 
301         return snprintf(buf, PAGE_SIZE, "%d\n", val);
302 }
303 
304 static ssize_t show_in(struct device *dev, struct device_attribute
305         *devattr, char *buf)
306 {
307         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
308         struct sch5627_data *data = sch5627_update_device(dev);
309         int val;
310 
311         if (IS_ERR(data))
312                 return PTR_ERR(data);
313 
314         val = DIV_ROUND_CLOSEST(
315                 data->in[attr->index] * SCH5627_REG_IN_FACTOR[attr->index],
316                 10000);
317         return snprintf(buf, PAGE_SIZE, "%d\n", val);
318 }
319 
320 static ssize_t show_in_label(struct device *dev, struct device_attribute
321         *devattr, char *buf)
322 {
323         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
324 
325         return snprintf(buf, PAGE_SIZE, "%s\n",
326                         SCH5627_IN_LABELS[attr->index]);
327 }
328 
329 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
330 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
331 static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
332 static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
333 static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3);
334 static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4);
335 static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp, NULL, 5);
336 static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_temp, NULL, 6);
337 static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_temp, NULL, 7);
338 static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0);
339 static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1);
340 static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2);
341 static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_temp_fault, NULL, 3);
342 static SENSOR_DEVICE_ATTR(temp5_fault, S_IRUGO, show_temp_fault, NULL, 4);
343 static SENSOR_DEVICE_ATTR(temp6_fault, S_IRUGO, show_temp_fault, NULL, 5);
344 static SENSOR_DEVICE_ATTR(temp7_fault, S_IRUGO, show_temp_fault, NULL, 6);
345 static SENSOR_DEVICE_ATTR(temp8_fault, S_IRUGO, show_temp_fault, NULL, 7);
346 static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_max, NULL, 0);
347 static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp_max, NULL, 1);
348 static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp_max, NULL, 2);
349 static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO, show_temp_max, NULL, 3);
350 static SENSOR_DEVICE_ATTR(temp5_max, S_IRUGO, show_temp_max, NULL, 4);
351 static SENSOR_DEVICE_ATTR(temp6_max, S_IRUGO, show_temp_max, NULL, 5);
352 static SENSOR_DEVICE_ATTR(temp7_max, S_IRUGO, show_temp_max, NULL, 6);
353 static SENSOR_DEVICE_ATTR(temp8_max, S_IRUGO, show_temp_max, NULL, 7);
354 static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0);
355 static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL, 1);
356 static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit, NULL, 2);
357 static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL, 3);
358 static SENSOR_DEVICE_ATTR(temp5_crit, S_IRUGO, show_temp_crit, NULL, 4);
359 static SENSOR_DEVICE_ATTR(temp6_crit, S_IRUGO, show_temp_crit, NULL, 5);
360 static SENSOR_DEVICE_ATTR(temp7_crit, S_IRUGO, show_temp_crit, NULL, 6);
361 static SENSOR_DEVICE_ATTR(temp8_crit, S_IRUGO, show_temp_crit, NULL, 7);
362 
363 static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
364 static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
365 static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
366 static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3);
367 static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0);
368 static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1);
369 static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2);
370 static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3);
371 static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO, show_fan_min, NULL, 0);
372 static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO, show_fan_min, NULL, 1);
373 static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO, show_fan_min, NULL, 2);
374 static SENSOR_DEVICE_ATTR(fan4_min, S_IRUGO, show_fan_min, NULL, 3);
375 
376 static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0);
377 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1);
378 static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2);
379 static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3);
380 static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 4);
381 static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_in_label, NULL, 0);
382 static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_in_label, NULL, 1);
383 static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_in_label, NULL, 2);
384 static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_in_label, NULL, 3);
385 
386 static struct attribute *sch5627_attributes[] = {
387         &dev_attr_name.attr,
388 
389         &sensor_dev_attr_temp1_input.dev_attr.attr,
390         &sensor_dev_attr_temp2_input.dev_attr.attr,
391         &sensor_dev_attr_temp3_input.dev_attr.attr,
392         &sensor_dev_attr_temp4_input.dev_attr.attr,
393         &sensor_dev_attr_temp5_input.dev_attr.attr,
394         &sensor_dev_attr_temp6_input.dev_attr.attr,
395         &sensor_dev_attr_temp7_input.dev_attr.attr,
396         &sensor_dev_attr_temp8_input.dev_attr.attr,
397         &sensor_dev_attr_temp1_fault.dev_attr.attr,
398         &sensor_dev_attr_temp2_fault.dev_attr.attr,
399         &sensor_dev_attr_temp3_fault.dev_attr.attr,
400         &sensor_dev_attr_temp4_fault.dev_attr.attr,
401         &sensor_dev_attr_temp5_fault.dev_attr.attr,
402         &sensor_dev_attr_temp6_fault.dev_attr.attr,
403         &sensor_dev_attr_temp7_fault.dev_attr.attr,
404         &sensor_dev_attr_temp8_fault.dev_attr.attr,
405         &sensor_dev_attr_temp1_max.dev_attr.attr,
406         &sensor_dev_attr_temp2_max.dev_attr.attr,
407         &sensor_dev_attr_temp3_max.dev_attr.attr,
408         &sensor_dev_attr_temp4_max.dev_attr.attr,
409         &sensor_dev_attr_temp5_max.dev_attr.attr,
410         &sensor_dev_attr_temp6_max.dev_attr.attr,
411         &sensor_dev_attr_temp7_max.dev_attr.attr,
412         &sensor_dev_attr_temp8_max.dev_attr.attr,
413         &sensor_dev_attr_temp1_crit.dev_attr.attr,
414         &sensor_dev_attr_temp2_crit.dev_attr.attr,
415         &sensor_dev_attr_temp3_crit.dev_attr.attr,
416         &sensor_dev_attr_temp4_crit.dev_attr.attr,
417         &sensor_dev_attr_temp5_crit.dev_attr.attr,
418         &sensor_dev_attr_temp6_crit.dev_attr.attr,
419         &sensor_dev_attr_temp7_crit.dev_attr.attr,
420         &sensor_dev_attr_temp8_crit.dev_attr.attr,
421 
422         &sensor_dev_attr_fan1_input.dev_attr.attr,
423         &sensor_dev_attr_fan2_input.dev_attr.attr,
424         &sensor_dev_attr_fan3_input.dev_attr.attr,
425         &sensor_dev_attr_fan4_input.dev_attr.attr,
426         &sensor_dev_attr_fan1_fault.dev_attr.attr,
427         &sensor_dev_attr_fan2_fault.dev_attr.attr,
428         &sensor_dev_attr_fan3_fault.dev_attr.attr,
429         &sensor_dev_attr_fan4_fault.dev_attr.attr,
430         &sensor_dev_attr_fan1_min.dev_attr.attr,
431         &sensor_dev_attr_fan2_min.dev_attr.attr,
432         &sensor_dev_attr_fan3_min.dev_attr.attr,
433         &sensor_dev_attr_fan4_min.dev_attr.attr,
434 
435         &sensor_dev_attr_in0_input.dev_attr.attr,
436         &sensor_dev_attr_in1_input.dev_attr.attr,
437         &sensor_dev_attr_in2_input.dev_attr.attr,
438         &sensor_dev_attr_in3_input.dev_attr.attr,
439         &sensor_dev_attr_in4_input.dev_attr.attr,
440         &sensor_dev_attr_in0_label.dev_attr.attr,
441         &sensor_dev_attr_in1_label.dev_attr.attr,
442         &sensor_dev_attr_in2_label.dev_attr.attr,
443         &sensor_dev_attr_in3_label.dev_attr.attr,
444         /* No in4_label as in4 is a generic input pin */
445 
446         NULL
447 };
448 
449 static const struct attribute_group sch5627_group = {
450         .attrs = sch5627_attributes,
451 };
452 
453 static int sch5627_remove(struct platform_device *pdev)
454 {
455         struct sch5627_data *data = platform_get_drvdata(pdev);
456 
457         if (data->watchdog)
458                 sch56xx_watchdog_unregister(data->watchdog);
459 
460         if (data->hwmon_dev)
461                 hwmon_device_unregister(data->hwmon_dev);
462 
463         sysfs_remove_group(&pdev->dev.kobj, &sch5627_group);
464 
465         return 0;
466 }
467 
468 static int sch5627_probe(struct platform_device *pdev)
469 {
470         struct sch5627_data *data;
471         int err, build_code, build_id, hwmon_rev, val;
472 
473         data = devm_kzalloc(&pdev->dev, sizeof(struct sch5627_data),
474                             GFP_KERNEL);
475         if (!data)
476                 return -ENOMEM;
477 
478         data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
479         mutex_init(&data->update_lock);
480         platform_set_drvdata(pdev, data);
481 
482         val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_HWMON_ID);
483         if (val < 0) {
484                 err = val;
485                 goto error;
486         }
487         if (val != SCH5627_HWMON_ID) {
488                 pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "hwmon",
489                        val, SCH5627_HWMON_ID);
490                 err = -ENODEV;
491                 goto error;
492         }
493 
494         val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_COMPANY_ID);
495         if (val < 0) {
496                 err = val;
497                 goto error;
498         }
499         if (val != SCH5627_COMPANY_ID) {
500                 pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "company",
501                        val, SCH5627_COMPANY_ID);
502                 err = -ENODEV;
503                 goto error;
504         }
505 
506         val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_PRIMARY_ID);
507         if (val < 0) {
508                 err = val;
509                 goto error;
510         }
511         if (val != SCH5627_PRIMARY_ID) {
512                 pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "primary",
513                        val, SCH5627_PRIMARY_ID);
514                 err = -ENODEV;
515                 goto error;
516         }
517 
518         build_code = sch56xx_read_virtual_reg(data->addr,
519                                               SCH5627_REG_BUILD_CODE);
520         if (build_code < 0) {
521                 err = build_code;
522                 goto error;
523         }
524 
525         build_id = sch56xx_read_virtual_reg16(data->addr,
526                                               SCH5627_REG_BUILD_ID);
527         if (build_id < 0) {
528                 err = build_id;
529                 goto error;
530         }
531 
532         hwmon_rev = sch56xx_read_virtual_reg(data->addr,
533                                              SCH5627_REG_HWMON_REV);
534         if (hwmon_rev < 0) {
535                 err = hwmon_rev;
536                 goto error;
537         }
538 
539         val = sch56xx_read_virtual_reg(data->addr, SCH5627_REG_CTRL);
540         if (val < 0) {
541                 err = val;
542                 goto error;
543         }
544         data->control = val;
545         if (!(data->control & 0x01)) {
546                 pr_err("hardware monitoring not enabled\n");
547                 err = -ENODEV;
548                 goto error;
549         }
550         /* Trigger a Vbat voltage measurement, so that we get a valid reading
551            the first time we read Vbat */
552         sch56xx_write_virtual_reg(data->addr, SCH5627_REG_CTRL,
553                                   data->control | 0x10);
554         data->last_battery = jiffies;
555 
556         /*
557          * Read limits, we do this only once as reading a register on
558          * the sch5627 is quite expensive (and they don't change).
559          */
560         err = sch5627_read_limits(data);
561         if (err)
562                 goto error;
563 
564         pr_info("found %s chip at %#hx\n", DEVNAME, data->addr);
565         pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n",
566                 build_code, build_id, hwmon_rev);
567 
568         /* Register sysfs interface files */
569         err = sysfs_create_group(&pdev->dev.kobj, &sch5627_group);
570         if (err)
571                 goto error;
572 
573         data->hwmon_dev = hwmon_device_register(&pdev->dev);
574         if (IS_ERR(data->hwmon_dev)) {
575                 err = PTR_ERR(data->hwmon_dev);
576                 data->hwmon_dev = NULL;
577                 goto error;
578         }
579 
580         /* Note failing to register the watchdog is not a fatal error */
581         data->watchdog = sch56xx_watchdog_register(&pdev->dev, data->addr,
582                         (build_code << 24) | (build_id << 8) | hwmon_rev,
583                         &data->update_lock, 1);
584 
585         return 0;
586 
587 error:
588         sch5627_remove(pdev);
589         return err;
590 }
591 
592 static struct platform_driver sch5627_driver = {
593         .driver = {
594                 .owner  = THIS_MODULE,
595                 .name   = DRVNAME,
596         },
597         .probe          = sch5627_probe,
598         .remove         = sch5627_remove,
599 };
600 
601 module_platform_driver(sch5627_driver);
602 
603 MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver");
604 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
605 MODULE_LICENSE("GPL");
606 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us