thmc50.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /*
  2. thmc50.c - Part of lm_sensors, Linux kernel modules for hardware
  3. monitoring
  4. Copyright (C) 2007 Krzysztof Helt <krzysztof.h1@wp.pl>
  5. Based on 2.4 driver by Frodo Looijaard <frodol@dds.nl> and
  6. Philip Edelbrock <phil@netroedge.com>
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <linux/module.h>
  20. #include <linux/init.h>
  21. #include <linux/slab.h>
  22. #include <linux/i2c.h>
  23. #include <linux/hwmon.h>
  24. #include <linux/hwmon-sysfs.h>
  25. #include <linux/err.h>
  26. #include <linux/mutex.h>
  27. MODULE_LICENSE("GPL");
  28. /* Addresses to scan */
  29. static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
  30. /* Insmod parameters */
  31. I2C_CLIENT_INSMOD_2(thmc50, adm1022);
  32. I2C_CLIENT_MODULE_PARM(adm1022_temp3, "List of adapter,address pairs "
  33. "to enable 3rd temperature (ADM1022 only)");
  34. /* Many THMC50 constants specified below */
  35. /* The THMC50 registers */
  36. #define THMC50_REG_CONF 0x40
  37. #define THMC50_REG_COMPANY_ID 0x3E
  38. #define THMC50_REG_DIE_CODE 0x3F
  39. #define THMC50_REG_ANALOG_OUT 0x19
  40. const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
  41. const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
  42. const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
  43. #define THMC50_REG_CONF_nFANOFF 0x20
  44. /* Each client has this additional data */
  45. struct thmc50_data {
  46. struct i2c_client client;
  47. struct class_device *class_dev;
  48. struct mutex update_lock;
  49. enum chips type;
  50. unsigned long last_updated; /* In jiffies */
  51. char has_temp3; /* !=0 if it is ADM1022 in temp3 mode */
  52. char valid; /* !=0 if following fields are valid */
  53. /* Register values */
  54. s8 temp_input[3];
  55. s8 temp_max[3];
  56. s8 temp_min[3];
  57. u8 analog_out;
  58. };
  59. static int thmc50_attach_adapter(struct i2c_adapter *adapter);
  60. static int thmc50_detach_client(struct i2c_client *client);
  61. static void thmc50_init_client(struct i2c_client *client);
  62. static struct thmc50_data *thmc50_update_device(struct device *dev);
  63. static struct i2c_driver thmc50_driver = {
  64. .driver = {
  65. .name = "thmc50",
  66. },
  67. .attach_adapter = thmc50_attach_adapter,
  68. .detach_client = thmc50_detach_client,
  69. };
  70. static ssize_t show_analog_out(struct device *dev,
  71. struct device_attribute *attr, char *buf)
  72. {
  73. struct thmc50_data *data = thmc50_update_device(dev);
  74. return sprintf(buf, "%d\n", data->analog_out);
  75. }
  76. static ssize_t set_analog_out(struct device *dev,
  77. struct device_attribute *attr,
  78. const char *buf, size_t count)
  79. {
  80. struct i2c_client *client = to_i2c_client(dev);
  81. struct thmc50_data *data = i2c_get_clientdata(client);
  82. int tmp = simple_strtoul(buf, NULL, 10);
  83. int config;
  84. mutex_lock(&data->update_lock);
  85. data->analog_out = SENSORS_LIMIT(tmp, 0, 255);
  86. i2c_smbus_write_byte_data(client, THMC50_REG_ANALOG_OUT,
  87. data->analog_out);
  88. config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
  89. if (data->analog_out == 0)
  90. config &= ~THMC50_REG_CONF_nFANOFF;
  91. else
  92. config |= THMC50_REG_CONF_nFANOFF;
  93. i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);
  94. mutex_unlock(&data->update_lock);
  95. return count;
  96. }
  97. /* There is only one PWM mode = DC */
  98. static ssize_t show_pwm_mode(struct device *dev, struct device_attribute *attr,
  99. char *buf)
  100. {
  101. return sprintf(buf, "0\n");
  102. }
  103. /* Temperatures */
  104. static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
  105. char *buf)
  106. {
  107. int nr = to_sensor_dev_attr(attr)->index;
  108. struct thmc50_data *data = thmc50_update_device(dev);
  109. return sprintf(buf, "%d\n", data->temp_input[nr] * 1000);
  110. }
  111. static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
  112. char *buf)
  113. {
  114. int nr = to_sensor_dev_attr(attr)->index;
  115. struct thmc50_data *data = thmc50_update_device(dev);
  116. return sprintf(buf, "%d\n", data->temp_min[nr] * 1000);
  117. }
  118. static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
  119. const char *buf, size_t count)
  120. {
  121. int nr = to_sensor_dev_attr(attr)->index;
  122. struct i2c_client *client = to_i2c_client(dev);
  123. struct thmc50_data *data = i2c_get_clientdata(client);
  124. int val = simple_strtol(buf, NULL, 10);
  125. mutex_lock(&data->update_lock);
  126. data->temp_min[nr] = SENSORS_LIMIT(val / 1000, -128, 127);
  127. i2c_smbus_write_byte_data(client, THMC50_REG_TEMP_MIN[nr],
  128. data->temp_min[nr]);
  129. mutex_unlock(&data->update_lock);
  130. return count;
  131. }
  132. static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
  133. char *buf)
  134. {
  135. int nr = to_sensor_dev_attr(attr)->index;
  136. struct thmc50_data *data = thmc50_update_device(dev);
  137. return sprintf(buf, "%d\n", data->temp_max[nr] * 1000);
  138. }
  139. static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
  140. const char *buf, size_t count)
  141. {
  142. int nr = to_sensor_dev_attr(attr)->index;
  143. struct i2c_client *client = to_i2c_client(dev);
  144. struct thmc50_data *data = i2c_get_clientdata(client);
  145. int val = simple_strtol(buf, NULL, 10);
  146. mutex_lock(&data->update_lock);
  147. data->temp_max[nr] = SENSORS_LIMIT(val / 1000, -128, 127);
  148. i2c_smbus_write_byte_data(client, THMC50_REG_TEMP_MAX[nr],
  149. data->temp_max[nr]);
  150. mutex_unlock(&data->update_lock);
  151. return count;
  152. }
  153. #define temp_reg(offset) \
  154. static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, \
  155. NULL, offset - 1); \
  156. static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
  157. show_temp_min, set_temp_min, offset - 1); \
  158. static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
  159. show_temp_max, set_temp_max, offset - 1);
  160. temp_reg(1);
  161. temp_reg(2);
  162. temp_reg(3);
  163. static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_analog_out,
  164. set_analog_out, 0);
  165. static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL, 0);
  166. static struct attribute *thmc50_attributes[] = {
  167. &sensor_dev_attr_temp1_max.dev_attr.attr,
  168. &sensor_dev_attr_temp1_min.dev_attr.attr,
  169. &sensor_dev_attr_temp1_input.dev_attr.attr,
  170. &sensor_dev_attr_temp2_max.dev_attr.attr,
  171. &sensor_dev_attr_temp2_min.dev_attr.attr,
  172. &sensor_dev_attr_temp2_input.dev_attr.attr,
  173. &sensor_dev_attr_pwm1.dev_attr.attr,
  174. &sensor_dev_attr_pwm1_mode.dev_attr.attr,
  175. NULL
  176. };
  177. static const struct attribute_group thmc50_group = {
  178. .attrs = thmc50_attributes,
  179. };
  180. /* for ADM1022 3rd temperature mode */
  181. static struct attribute *adm1022_attributes[] = {
  182. &sensor_dev_attr_temp3_max.dev_attr.attr,
  183. &sensor_dev_attr_temp3_min.dev_attr.attr,
  184. &sensor_dev_attr_temp3_input.dev_attr.attr,
  185. NULL
  186. };
  187. static const struct attribute_group adm1022_group = {
  188. .attrs = adm1022_attributes,
  189. };
  190. static int thmc50_detect(struct i2c_adapter *adapter, int address, int kind)
  191. {
  192. unsigned company;
  193. unsigned revision;
  194. unsigned config;
  195. struct i2c_client *client;
  196. struct thmc50_data *data;
  197. struct device *dev;
  198. int err = 0;
  199. const char *type_name = "";
  200. if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
  201. pr_debug("thmc50: detect failed, "
  202. "smbus byte data not supported!\n");
  203. goto exit;
  204. }
  205. /* OK. For now, we presume we have a valid client. We now create the
  206. client structure, even though we cannot fill it completely yet.
  207. But it allows us to access thmc50 registers. */
  208. if (!(data = kzalloc(sizeof(struct thmc50_data), GFP_KERNEL))) {
  209. pr_debug("thmc50: detect failed, kzalloc failed!\n");
  210. err = -ENOMEM;
  211. goto exit;
  212. }
  213. client = &data->client;
  214. i2c_set_clientdata(client, data);
  215. client->addr = address;
  216. client->adapter = adapter;
  217. client->driver = &thmc50_driver;
  218. dev = &client->dev;
  219. pr_debug("thmc50: Probing for THMC50 at 0x%2X on bus %d\n",
  220. client->addr, i2c_adapter_id(client->adapter));
  221. /* Now, we do the remaining detection. */
  222. company = i2c_smbus_read_byte_data(client, THMC50_REG_COMPANY_ID);
  223. revision = i2c_smbus_read_byte_data(client, THMC50_REG_DIE_CODE);
  224. config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
  225. if (kind == 0)
  226. kind = thmc50;
  227. else if (kind < 0) {
  228. err = -ENODEV;
  229. if (revision >= 0xc0 && ((config & 0x10) == 0)) {
  230. if (company == 0x49) {
  231. kind = thmc50;
  232. err = 0;
  233. } else if (company == 0x41) {
  234. kind = adm1022;
  235. err = 0;
  236. }
  237. }
  238. }
  239. if (err == -ENODEV) {
  240. pr_debug("thmc50: Detection of THMC50/ADM1022 failed\n");
  241. goto exit_free;
  242. }
  243. pr_debug("thmc50: Detected %s (version %x, revision %x)\n",
  244. type_name, (revision >> 4) - 0xc, revision & 0xf);
  245. data->type = kind;
  246. if (kind == thmc50)
  247. type_name = "thmc50";
  248. else if (kind == adm1022) {
  249. int id = i2c_adapter_id(client->adapter);
  250. int i;
  251. type_name = "adm1022";
  252. data->has_temp3 = (config >> 7) & 1; /* config MSB */
  253. for (i = 0; i + 1 < adm1022_temp3_num; i += 2)
  254. if (adm1022_temp3[i] == id &&
  255. adm1022_temp3[i + 1] == address) {
  256. /* enable 2nd remote temp */
  257. data->has_temp3 = 1;
  258. break;
  259. }
  260. }
  261. /* Fill in the remaining client fields & put it into the global list */
  262. strlcpy(client->name, type_name, I2C_NAME_SIZE);
  263. mutex_init(&data->update_lock);
  264. /* Tell the I2C layer a new client has arrived */
  265. if ((err = i2c_attach_client(client)))
  266. goto exit_free;
  267. thmc50_init_client(client);
  268. /* Register sysfs hooks */
  269. if ((err = sysfs_create_group(&client->dev.kobj, &thmc50_group)))
  270. goto exit_detach;
  271. /* Register ADM1022 sysfs hooks */
  272. if (data->type == adm1022)
  273. if ((err = sysfs_create_group(&client->dev.kobj,
  274. &adm1022_group)))
  275. goto exit_remove_sysfs_thmc50;
  276. /* Register a new directory entry with module sensors */
  277. data->class_dev = hwmon_device_register(&client->dev);
  278. if (IS_ERR(data->class_dev)) {
  279. err = PTR_ERR(data->class_dev);
  280. goto exit_remove_sysfs;
  281. }
  282. return 0;
  283. exit_remove_sysfs:
  284. if (data->type == adm1022)
  285. sysfs_remove_group(&client->dev.kobj, &adm1022_group);
  286. exit_remove_sysfs_thmc50:
  287. sysfs_remove_group(&client->dev.kobj, &thmc50_group);
  288. exit_detach:
  289. i2c_detach_client(client);
  290. exit_free:
  291. kfree(data);
  292. exit:
  293. return err;
  294. }
  295. static int thmc50_attach_adapter(struct i2c_adapter *adapter)
  296. {
  297. if (!(adapter->class & I2C_CLASS_HWMON))
  298. return 0;
  299. return i2c_probe(adapter, &addr_data, thmc50_detect);
  300. }
  301. static int thmc50_detach_client(struct i2c_client *client)
  302. {
  303. struct thmc50_data *data = i2c_get_clientdata(client);
  304. int err;
  305. hwmon_device_unregister(data->class_dev);
  306. sysfs_remove_group(&client->dev.kobj, &thmc50_group);
  307. if (data->type == adm1022)
  308. sysfs_remove_group(&client->dev.kobj, &adm1022_group);
  309. if ((err = i2c_detach_client(client)))
  310. return err;
  311. kfree(data);
  312. return 0;
  313. }
  314. static void thmc50_init_client(struct i2c_client *client)
  315. {
  316. struct thmc50_data *data = i2c_get_clientdata(client);
  317. int config;
  318. data->analog_out = i2c_smbus_read_byte_data(client,
  319. THMC50_REG_ANALOG_OUT);
  320. /* set up to at least 1 */
  321. if (data->analog_out == 0) {
  322. data->analog_out = 1;
  323. i2c_smbus_write_byte_data(client, THMC50_REG_ANALOG_OUT,
  324. data->analog_out);
  325. }
  326. config = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
  327. config |= 0x1; /* start the chip if it is in standby mode */
  328. if (data->has_temp3)
  329. config |= 0x80; /* enable 2nd remote temp */
  330. i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);
  331. }
  332. static struct thmc50_data *thmc50_update_device(struct device *dev)
  333. {
  334. struct i2c_client *client = to_i2c_client(dev);
  335. struct thmc50_data *data = i2c_get_clientdata(client);
  336. int timeout = HZ / 5 + (data->type == thmc50 ? HZ : 0);
  337. mutex_lock(&data->update_lock);
  338. if (time_after(jiffies, data->last_updated + timeout)
  339. || !data->valid) {
  340. int temps = data->has_temp3 ? 3 : 2;
  341. int i;
  342. for (i = 0; i < temps; i++) {
  343. data->temp_input[i] = i2c_smbus_read_byte_data(client,
  344. THMC50_REG_TEMP[i]);
  345. data->temp_max[i] = i2c_smbus_read_byte_data(client,
  346. THMC50_REG_TEMP_MAX[i]);
  347. data->temp_min[i] = i2c_smbus_read_byte_data(client,
  348. THMC50_REG_TEMP_MIN[i]);
  349. }
  350. data->analog_out =
  351. i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
  352. data->last_updated = jiffies;
  353. data->valid = 1;
  354. }
  355. mutex_unlock(&data->update_lock);
  356. return data;
  357. }
  358. static int __init sm_thmc50_init(void)
  359. {
  360. return i2c_add_driver(&thmc50_driver);
  361. }
  362. static void __exit sm_thmc50_exit(void)
  363. {
  364. i2c_del_driver(&thmc50_driver);
  365. }
  366. MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
  367. MODULE_DESCRIPTION("THMC50 driver");
  368. module_init(sm_thmc50_init);
  369. module_exit(sm_thmc50_exit);