smsc47m192.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /*
  2. * smsc47m192.c - Support for hardware monitoring block of
  3. * SMSC LPC47M192 and compatible Super I/O chips
  4. *
  5. * Copyright (C) 2006 Hartmut Rick <linux@rick.claranet.de>
  6. *
  7. * Derived from lm78.c and other chip drivers.
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. */
  23. #include <linux/module.h>
  24. #include <linux/init.h>
  25. #include <linux/slab.h>
  26. #include <linux/jiffies.h>
  27. #include <linux/i2c.h>
  28. #include <linux/hwmon.h>
  29. #include <linux/hwmon-sysfs.h>
  30. #include <linux/hwmon-vid.h>
  31. #include <linux/err.h>
  32. #include <linux/sysfs.h>
  33. #include <linux/mutex.h>
  34. /* Addresses to scan */
  35. static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
  36. /* SMSC47M192 registers */
  37. #define SMSC47M192_REG_IN(nr) ((nr) < 6 ? (0x20 + (nr)) : \
  38. (0x50 + (nr) - 6))
  39. #define SMSC47M192_REG_IN_MAX(nr) ((nr) < 6 ? (0x2b + (nr) * 2) : \
  40. (0x54 + (((nr) - 6) * 2)))
  41. #define SMSC47M192_REG_IN_MIN(nr) ((nr) < 6 ? (0x2c + (nr) * 2) : \
  42. (0x55 + (((nr) - 6) * 2)))
  43. static u8 SMSC47M192_REG_TEMP[3] = { 0x27, 0x26, 0x52 };
  44. static u8 SMSC47M192_REG_TEMP_MAX[3] = { 0x39, 0x37, 0x58 };
  45. static u8 SMSC47M192_REG_TEMP_MIN[3] = { 0x3A, 0x38, 0x59 };
  46. #define SMSC47M192_REG_TEMP_OFFSET(nr) ((nr) == 2 ? 0x1e : 0x1f)
  47. #define SMSC47M192_REG_ALARM1 0x41
  48. #define SMSC47M192_REG_ALARM2 0x42
  49. #define SMSC47M192_REG_VID 0x47
  50. #define SMSC47M192_REG_VID4 0x49
  51. #define SMSC47M192_REG_CONFIG 0x40
  52. #define SMSC47M192_REG_SFR 0x4f
  53. #define SMSC47M192_REG_COMPANY_ID 0x3e
  54. #define SMSC47M192_REG_VERSION 0x3f
  55. /* generalised scaling with integer rounding */
  56. static inline int SCALE(long val, int mul, int div)
  57. {
  58. if (val < 0)
  59. return (val * mul - div / 2) / div;
  60. else
  61. return (val * mul + div / 2) / div;
  62. }
  63. /* Conversions */
  64. /* smsc47m192 internally scales voltage measurements */
  65. static const u16 nom_mv[] = { 2500, 2250, 3300, 5000, 12000, 3300, 1500, 1800 };
  66. static inline unsigned int IN_FROM_REG(u8 reg, int n)
  67. {
  68. return SCALE(reg, nom_mv[n], 192);
  69. }
  70. static inline u8 IN_TO_REG(unsigned long val, int n)
  71. {
  72. val = clamp_val(val, 0, nom_mv[n] * 255 / 192);
  73. return SCALE(val, 192, nom_mv[n]);
  74. }
  75. /*
  76. * TEMP: 0.001 degC units (-128C to +127C)
  77. * REG: 1C/bit, two's complement
  78. */
  79. static inline s8 TEMP_TO_REG(long val)
  80. {
  81. return SCALE(clamp_val(val, -128000, 127000), 1, 1000);
  82. }
  83. static inline int TEMP_FROM_REG(s8 val)
  84. {
  85. return val * 1000;
  86. }
  87. struct smsc47m192_data {
  88. struct i2c_client *client;
  89. const struct attribute_group *groups[3];
  90. struct mutex update_lock;
  91. char valid; /* !=0 if following fields are valid */
  92. unsigned long last_updated; /* In jiffies */
  93. u8 in[8]; /* Register value */
  94. u8 in_max[8]; /* Register value */
  95. u8 in_min[8]; /* Register value */
  96. s8 temp[3]; /* Register value */
  97. s8 temp_max[3]; /* Register value */
  98. s8 temp_min[3]; /* Register value */
  99. s8 temp_offset[3]; /* Register value */
  100. u16 alarms; /* Register encoding, combined */
  101. u8 vid; /* Register encoding, combined */
  102. u8 vrm;
  103. };
  104. static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
  105. {
  106. struct smsc47m192_data *data = dev_get_drvdata(dev);
  107. struct i2c_client *client = data->client;
  108. int i, config;
  109. mutex_lock(&data->update_lock);
  110. if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
  111. || !data->valid) {
  112. u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
  113. dev_dbg(&client->dev, "Starting smsc47m192 update\n");
  114. for (i = 0; i <= 7; i++) {
  115. data->in[i] = i2c_smbus_read_byte_data(client,
  116. SMSC47M192_REG_IN(i));
  117. data->in_min[i] = i2c_smbus_read_byte_data(client,
  118. SMSC47M192_REG_IN_MIN(i));
  119. data->in_max[i] = i2c_smbus_read_byte_data(client,
  120. SMSC47M192_REG_IN_MAX(i));
  121. }
  122. for (i = 0; i < 3; i++) {
  123. data->temp[i] = i2c_smbus_read_byte_data(client,
  124. SMSC47M192_REG_TEMP[i]);
  125. data->temp_max[i] = i2c_smbus_read_byte_data(client,
  126. SMSC47M192_REG_TEMP_MAX[i]);
  127. data->temp_min[i] = i2c_smbus_read_byte_data(client,
  128. SMSC47M192_REG_TEMP_MIN[i]);
  129. }
  130. for (i = 1; i < 3; i++)
  131. data->temp_offset[i] = i2c_smbus_read_byte_data(client,
  132. SMSC47M192_REG_TEMP_OFFSET(i));
  133. /*
  134. * first offset is temp_offset[0] if SFR bit 4 is set,
  135. * temp_offset[1] otherwise
  136. */
  137. if (sfr & 0x10) {
  138. data->temp_offset[0] = data->temp_offset[1];
  139. data->temp_offset[1] = 0;
  140. } else
  141. data->temp_offset[0] = 0;
  142. data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID)
  143. & 0x0f;
  144. config = i2c_smbus_read_byte_data(client,
  145. SMSC47M192_REG_CONFIG);
  146. if (config & 0x20)
  147. data->vid |= (i2c_smbus_read_byte_data(client,
  148. SMSC47M192_REG_VID4) & 0x01) << 4;
  149. data->alarms = i2c_smbus_read_byte_data(client,
  150. SMSC47M192_REG_ALARM1) |
  151. (i2c_smbus_read_byte_data(client,
  152. SMSC47M192_REG_ALARM2) << 8);
  153. data->last_updated = jiffies;
  154. data->valid = 1;
  155. }
  156. mutex_unlock(&data->update_lock);
  157. return data;
  158. }
  159. /* Voltages */
  160. static ssize_t show_in(struct device *dev, struct device_attribute *attr,
  161. char *buf)
  162. {
  163. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  164. int nr = sensor_attr->index;
  165. struct smsc47m192_data *data = smsc47m192_update_device(dev);
  166. return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr));
  167. }
  168. static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
  169. char *buf)
  170. {
  171. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  172. int nr = sensor_attr->index;
  173. struct smsc47m192_data *data = smsc47m192_update_device(dev);
  174. return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr));
  175. }
  176. static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
  177. char *buf)
  178. {
  179. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  180. int nr = sensor_attr->index;
  181. struct smsc47m192_data *data = smsc47m192_update_device(dev);
  182. return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr));
  183. }
  184. static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
  185. const char *buf, size_t count)
  186. {
  187. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  188. int nr = sensor_attr->index;
  189. struct smsc47m192_data *data = dev_get_drvdata(dev);
  190. struct i2c_client *client = data->client;
  191. unsigned long val;
  192. int err;
  193. err = kstrtoul(buf, 10, &val);
  194. if (err)
  195. return err;
  196. mutex_lock(&data->update_lock);
  197. data->in_min[nr] = IN_TO_REG(val, nr);
  198. i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MIN(nr),
  199. data->in_min[nr]);
  200. mutex_unlock(&data->update_lock);
  201. return count;
  202. }
  203. static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
  204. const char *buf, size_t count)
  205. {
  206. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  207. int nr = sensor_attr->index;
  208. struct smsc47m192_data *data = dev_get_drvdata(dev);
  209. struct i2c_client *client = data->client;
  210. unsigned long val;
  211. int err;
  212. err = kstrtoul(buf, 10, &val);
  213. if (err)
  214. return err;
  215. mutex_lock(&data->update_lock);
  216. data->in_max[nr] = IN_TO_REG(val, nr);
  217. i2c_smbus_write_byte_data(client, SMSC47M192_REG_IN_MAX(nr),
  218. data->in_max[nr]);
  219. mutex_unlock(&data->update_lock);
  220. return count;
  221. }
  222. #define show_in_offset(offset) \
  223. static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
  224. show_in, NULL, offset); \
  225. static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
  226. show_in_min, set_in_min, offset); \
  227. static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
  228. show_in_max, set_in_max, offset);
  229. show_in_offset(0)
  230. show_in_offset(1)
  231. show_in_offset(2)
  232. show_in_offset(3)
  233. show_in_offset(4)
  234. show_in_offset(5)
  235. show_in_offset(6)
  236. show_in_offset(7)
  237. /* Temperatures */
  238. static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
  239. char *buf)
  240. {
  241. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  242. int nr = sensor_attr->index;
  243. struct smsc47m192_data *data = smsc47m192_update_device(dev);
  244. return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
  245. }
  246. static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
  247. char *buf)
  248. {
  249. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  250. int nr = sensor_attr->index;
  251. struct smsc47m192_data *data = smsc47m192_update_device(dev);
  252. return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
  253. }
  254. static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
  255. char *buf)
  256. {
  257. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  258. int nr = sensor_attr->index;
  259. struct smsc47m192_data *data = smsc47m192_update_device(dev);
  260. return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
  261. }
  262. static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
  263. const char *buf, size_t count)
  264. {
  265. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  266. int nr = sensor_attr->index;
  267. struct smsc47m192_data *data = dev_get_drvdata(dev);
  268. struct i2c_client *client = data->client;
  269. long val;
  270. int err;
  271. err = kstrtol(buf, 10, &val);
  272. if (err)
  273. return err;
  274. mutex_lock(&data->update_lock);
  275. data->temp_min[nr] = TEMP_TO_REG(val);
  276. i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MIN[nr],
  277. data->temp_min[nr]);
  278. mutex_unlock(&data->update_lock);
  279. return count;
  280. }
  281. static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
  282. const char *buf, size_t count)
  283. {
  284. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  285. int nr = sensor_attr->index;
  286. struct smsc47m192_data *data = dev_get_drvdata(dev);
  287. struct i2c_client *client = data->client;
  288. long val;
  289. int err;
  290. err = kstrtol(buf, 10, &val);
  291. if (err)
  292. return err;
  293. mutex_lock(&data->update_lock);
  294. data->temp_max[nr] = TEMP_TO_REG(val);
  295. i2c_smbus_write_byte_data(client, SMSC47M192_REG_TEMP_MAX[nr],
  296. data->temp_max[nr]);
  297. mutex_unlock(&data->update_lock);
  298. return count;
  299. }
  300. static ssize_t show_temp_offset(struct device *dev, struct device_attribute
  301. *attr, char *buf)
  302. {
  303. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  304. int nr = sensor_attr->index;
  305. struct smsc47m192_data *data = smsc47m192_update_device(dev);
  306. return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_offset[nr]));
  307. }
  308. static ssize_t set_temp_offset(struct device *dev, struct device_attribute
  309. *attr, const char *buf, size_t count)
  310. {
  311. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  312. int nr = sensor_attr->index;
  313. struct smsc47m192_data *data = dev_get_drvdata(dev);
  314. struct i2c_client *client = data->client;
  315. u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
  316. long val;
  317. int err;
  318. err = kstrtol(buf, 10, &val);
  319. if (err)
  320. return err;
  321. mutex_lock(&data->update_lock);
  322. data->temp_offset[nr] = TEMP_TO_REG(val);
  323. if (nr > 1)
  324. i2c_smbus_write_byte_data(client,
  325. SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]);
  326. else if (data->temp_offset[nr] != 0) {
  327. /*
  328. * offset[0] and offset[1] share the same register,
  329. * SFR bit 4 activates offset[0]
  330. */
  331. i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR,
  332. (sfr & 0xef) | (nr == 0 ? 0x10 : 0));
  333. data->temp_offset[1-nr] = 0;
  334. i2c_smbus_write_byte_data(client,
  335. SMSC47M192_REG_TEMP_OFFSET(nr), data->temp_offset[nr]);
  336. } else if ((sfr & 0x10) == (nr == 0 ? 0x10 : 0))
  337. i2c_smbus_write_byte_data(client,
  338. SMSC47M192_REG_TEMP_OFFSET(nr), 0);
  339. mutex_unlock(&data->update_lock);
  340. return count;
  341. }
  342. #define show_temp_index(index) \
  343. static SENSOR_DEVICE_ATTR(temp##index##_input, S_IRUGO, \
  344. show_temp, NULL, index-1); \
  345. static SENSOR_DEVICE_ATTR(temp##index##_min, S_IRUGO | S_IWUSR, \
  346. show_temp_min, set_temp_min, index-1); \
  347. static SENSOR_DEVICE_ATTR(temp##index##_max, S_IRUGO | S_IWUSR, \
  348. show_temp_max, set_temp_max, index-1); \
  349. static SENSOR_DEVICE_ATTR(temp##index##_offset, S_IRUGO | S_IWUSR, \
  350. show_temp_offset, set_temp_offset, index-1);
  351. show_temp_index(1)
  352. show_temp_index(2)
  353. show_temp_index(3)
  354. /* VID */
  355. static ssize_t cpu0_vid_show(struct device *dev,
  356. struct device_attribute *attr, char *buf)
  357. {
  358. struct smsc47m192_data *data = smsc47m192_update_device(dev);
  359. return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
  360. }
  361. static DEVICE_ATTR_RO(cpu0_vid);
  362. static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
  363. char *buf)
  364. {
  365. struct smsc47m192_data *data = dev_get_drvdata(dev);
  366. return sprintf(buf, "%d\n", data->vrm);
  367. }
  368. static ssize_t vrm_store(struct device *dev, struct device_attribute *attr,
  369. const char *buf, size_t count)
  370. {
  371. struct smsc47m192_data *data = dev_get_drvdata(dev);
  372. unsigned long val;
  373. int err;
  374. err = kstrtoul(buf, 10, &val);
  375. if (err)
  376. return err;
  377. if (val > 255)
  378. return -EINVAL;
  379. data->vrm = val;
  380. return count;
  381. }
  382. static DEVICE_ATTR_RW(vrm);
  383. /* Alarms */
  384. static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
  385. char *buf)
  386. {
  387. struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
  388. int nr = sensor_attr->index;
  389. struct smsc47m192_data *data = smsc47m192_update_device(dev);
  390. return sprintf(buf, "%u\n", (data->alarms & nr) ? 1 : 0);
  391. }
  392. static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 0x0010);
  393. static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 0x0020);
  394. static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 0x0040);
  395. static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 0x4000);
  396. static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 0x8000);
  397. static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0x0001);
  398. static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 0x0002);
  399. static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 0x0004);
  400. static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 0x0008);
  401. static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 0x0100);
  402. static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 0x0200);
  403. static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 0x0400);
  404. static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 0x0800);
  405. static struct attribute *smsc47m192_attributes[] = {
  406. &sensor_dev_attr_in0_input.dev_attr.attr,
  407. &sensor_dev_attr_in0_min.dev_attr.attr,
  408. &sensor_dev_attr_in0_max.dev_attr.attr,
  409. &sensor_dev_attr_in0_alarm.dev_attr.attr,
  410. &sensor_dev_attr_in1_input.dev_attr.attr,
  411. &sensor_dev_attr_in1_min.dev_attr.attr,
  412. &sensor_dev_attr_in1_max.dev_attr.attr,
  413. &sensor_dev_attr_in1_alarm.dev_attr.attr,
  414. &sensor_dev_attr_in2_input.dev_attr.attr,
  415. &sensor_dev_attr_in2_min.dev_attr.attr,
  416. &sensor_dev_attr_in2_max.dev_attr.attr,
  417. &sensor_dev_attr_in2_alarm.dev_attr.attr,
  418. &sensor_dev_attr_in3_input.dev_attr.attr,
  419. &sensor_dev_attr_in3_min.dev_attr.attr,
  420. &sensor_dev_attr_in3_max.dev_attr.attr,
  421. &sensor_dev_attr_in3_alarm.dev_attr.attr,
  422. &sensor_dev_attr_in5_input.dev_attr.attr,
  423. &sensor_dev_attr_in5_min.dev_attr.attr,
  424. &sensor_dev_attr_in5_max.dev_attr.attr,
  425. &sensor_dev_attr_in5_alarm.dev_attr.attr,
  426. &sensor_dev_attr_in6_input.dev_attr.attr,
  427. &sensor_dev_attr_in6_min.dev_attr.attr,
  428. &sensor_dev_attr_in6_max.dev_attr.attr,
  429. &sensor_dev_attr_in6_alarm.dev_attr.attr,
  430. &sensor_dev_attr_in7_input.dev_attr.attr,
  431. &sensor_dev_attr_in7_min.dev_attr.attr,
  432. &sensor_dev_attr_in7_max.dev_attr.attr,
  433. &sensor_dev_attr_in7_alarm.dev_attr.attr,
  434. &sensor_dev_attr_temp1_input.dev_attr.attr,
  435. &sensor_dev_attr_temp1_max.dev_attr.attr,
  436. &sensor_dev_attr_temp1_min.dev_attr.attr,
  437. &sensor_dev_attr_temp1_offset.dev_attr.attr,
  438. &sensor_dev_attr_temp1_alarm.dev_attr.attr,
  439. &sensor_dev_attr_temp2_input.dev_attr.attr,
  440. &sensor_dev_attr_temp2_max.dev_attr.attr,
  441. &sensor_dev_attr_temp2_min.dev_attr.attr,
  442. &sensor_dev_attr_temp2_offset.dev_attr.attr,
  443. &sensor_dev_attr_temp2_alarm.dev_attr.attr,
  444. &sensor_dev_attr_temp2_fault.dev_attr.attr,
  445. &sensor_dev_attr_temp3_input.dev_attr.attr,
  446. &sensor_dev_attr_temp3_max.dev_attr.attr,
  447. &sensor_dev_attr_temp3_min.dev_attr.attr,
  448. &sensor_dev_attr_temp3_offset.dev_attr.attr,
  449. &sensor_dev_attr_temp3_alarm.dev_attr.attr,
  450. &sensor_dev_attr_temp3_fault.dev_attr.attr,
  451. &dev_attr_cpu0_vid.attr,
  452. &dev_attr_vrm.attr,
  453. NULL
  454. };
  455. static const struct attribute_group smsc47m192_group = {
  456. .attrs = smsc47m192_attributes,
  457. };
  458. static struct attribute *smsc47m192_attributes_in4[] = {
  459. &sensor_dev_attr_in4_input.dev_attr.attr,
  460. &sensor_dev_attr_in4_min.dev_attr.attr,
  461. &sensor_dev_attr_in4_max.dev_attr.attr,
  462. &sensor_dev_attr_in4_alarm.dev_attr.attr,
  463. NULL
  464. };
  465. static const struct attribute_group smsc47m192_group_in4 = {
  466. .attrs = smsc47m192_attributes_in4,
  467. };
  468. static void smsc47m192_init_client(struct i2c_client *client)
  469. {
  470. int i;
  471. u8 config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
  472. u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
  473. /* select cycle mode (pause 1 sec between updates) */
  474. i2c_smbus_write_byte_data(client, SMSC47M192_REG_SFR,
  475. (sfr & 0xfd) | 0x02);
  476. if (!(config & 0x01)) {
  477. /* initialize alarm limits */
  478. for (i = 0; i < 8; i++) {
  479. i2c_smbus_write_byte_data(client,
  480. SMSC47M192_REG_IN_MIN(i), 0);
  481. i2c_smbus_write_byte_data(client,
  482. SMSC47M192_REG_IN_MAX(i), 0xff);
  483. }
  484. for (i = 0; i < 3; i++) {
  485. i2c_smbus_write_byte_data(client,
  486. SMSC47M192_REG_TEMP_MIN[i], 0x80);
  487. i2c_smbus_write_byte_data(client,
  488. SMSC47M192_REG_TEMP_MAX[i], 0x7f);
  489. }
  490. /* start monitoring */
  491. i2c_smbus_write_byte_data(client, SMSC47M192_REG_CONFIG,
  492. (config & 0xf7) | 0x01);
  493. }
  494. }
  495. /* Return 0 if detection is successful, -ENODEV otherwise */
  496. static int smsc47m192_detect(struct i2c_client *client,
  497. struct i2c_board_info *info)
  498. {
  499. struct i2c_adapter *adapter = client->adapter;
  500. int version;
  501. if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
  502. return -ENODEV;
  503. /* Detection criteria from sensors_detect script */
  504. version = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VERSION);
  505. if (i2c_smbus_read_byte_data(client,
  506. SMSC47M192_REG_COMPANY_ID) == 0x55
  507. && (version & 0xf0) == 0x20
  508. && (i2c_smbus_read_byte_data(client,
  509. SMSC47M192_REG_VID) & 0x70) == 0x00
  510. && (i2c_smbus_read_byte_data(client,
  511. SMSC47M192_REG_VID4) & 0xfe) == 0x80) {
  512. dev_info(&adapter->dev,
  513. "found SMSC47M192 or compatible, "
  514. "version 2, stepping A%d\n", version & 0x0f);
  515. } else {
  516. dev_dbg(&adapter->dev,
  517. "SMSC47M192 detection failed at 0x%02x\n",
  518. client->addr);
  519. return -ENODEV;
  520. }
  521. strlcpy(info->type, "smsc47m192", I2C_NAME_SIZE);
  522. return 0;
  523. }
  524. static int smsc47m192_probe(struct i2c_client *client,
  525. const struct i2c_device_id *id)
  526. {
  527. struct device *dev = &client->dev;
  528. struct device *hwmon_dev;
  529. struct smsc47m192_data *data;
  530. int config;
  531. data = devm_kzalloc(dev, sizeof(struct smsc47m192_data), GFP_KERNEL);
  532. if (!data)
  533. return -ENOMEM;
  534. data->client = client;
  535. data->vrm = vid_which_vrm();
  536. mutex_init(&data->update_lock);
  537. /* Initialize the SMSC47M192 chip */
  538. smsc47m192_init_client(client);
  539. /* sysfs hooks */
  540. data->groups[0] = &smsc47m192_group;
  541. /* Pin 110 is either in4 (+12V) or VID4 */
  542. config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
  543. if (!(config & 0x20))
  544. data->groups[1] = &smsc47m192_group_in4;
  545. hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
  546. data, data->groups);
  547. return PTR_ERR_OR_ZERO(hwmon_dev);
  548. }
  549. static const struct i2c_device_id smsc47m192_id[] = {
  550. { "smsc47m192", 0 },
  551. { }
  552. };
  553. MODULE_DEVICE_TABLE(i2c, smsc47m192_id);
  554. static struct i2c_driver smsc47m192_driver = {
  555. .class = I2C_CLASS_HWMON,
  556. .driver = {
  557. .name = "smsc47m192",
  558. },
  559. .probe = smsc47m192_probe,
  560. .id_table = smsc47m192_id,
  561. .detect = smsc47m192_detect,
  562. .address_list = normal_i2c,
  563. };
  564. module_i2c_driver(smsc47m192_driver);
  565. MODULE_AUTHOR("Hartmut Rick <linux@rick.claranet.de>");
  566. MODULE_DESCRIPTION("SMSC47M192 driver");
  567. MODULE_LICENSE("GPL");