rtc-m41t80.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. /*
  2. * I2C client/driver for the ST M41T80 family of i2c rtc chips.
  3. *
  4. * Author: Alexander Bigga <ab@mycable.de>
  5. *
  6. * Based on m41t00.c by Mark A. Greer <mgreer@mvista.com>
  7. *
  8. * 2006 (c) mycable GmbH
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. *
  14. */
  15. #include <linux/bcd.h>
  16. #include <linux/i2c.h>
  17. #include <linux/init.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/rtc.h>
  21. #include <linux/slab.h>
  22. #include <linux/smp_lock.h>
  23. #include <linux/string.h>
  24. #ifdef CONFIG_RTC_DRV_M41T80_WDT
  25. #include <linux/fs.h>
  26. #include <linux/ioctl.h>
  27. #include <linux/miscdevice.h>
  28. #include <linux/reboot.h>
  29. #include <linux/watchdog.h>
  30. #endif
  31. #define M41T80_REG_SSEC 0
  32. #define M41T80_REG_SEC 1
  33. #define M41T80_REG_MIN 2
  34. #define M41T80_REG_HOUR 3
  35. #define M41T80_REG_WDAY 4
  36. #define M41T80_REG_DAY 5
  37. #define M41T80_REG_MON 6
  38. #define M41T80_REG_YEAR 7
  39. #define M41T80_REG_ALARM_MON 0xa
  40. #define M41T80_REG_ALARM_DAY 0xb
  41. #define M41T80_REG_ALARM_HOUR 0xc
  42. #define M41T80_REG_ALARM_MIN 0xd
  43. #define M41T80_REG_ALARM_SEC 0xe
  44. #define M41T80_REG_FLAGS 0xf
  45. #define M41T80_REG_SQW 0x13
  46. #define M41T80_DATETIME_REG_SIZE (M41T80_REG_YEAR + 1)
  47. #define M41T80_ALARM_REG_SIZE \
  48. (M41T80_REG_ALARM_SEC + 1 - M41T80_REG_ALARM_MON)
  49. #define M41T80_SEC_ST (1 << 7) /* ST: Stop Bit */
  50. #define M41T80_ALMON_AFE (1 << 7) /* AFE: AF Enable Bit */
  51. #define M41T80_ALMON_SQWE (1 << 6) /* SQWE: SQW Enable Bit */
  52. #define M41T80_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */
  53. #define M41T80_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */
  54. #define M41T80_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */
  55. #define M41T80_WATCHDOG_RB2 (1 << 7) /* RB: Watchdog resolution */
  56. #define M41T80_WATCHDOG_RB1 (1 << 1) /* RB: Watchdog resolution */
  57. #define M41T80_WATCHDOG_RB0 (1 << 0) /* RB: Watchdog resolution */
  58. #define M41T80_FEATURE_HT (1 << 0) /* Halt feature */
  59. #define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */
  60. #define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */
  61. #define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
  62. #define DRV_VERSION "0.05"
  63. static const struct i2c_device_id m41t80_id[] = {
  64. { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
  65. { "m41t80", M41T80_FEATURE_SQ },
  66. { "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ},
  67. { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
  68. { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
  69. { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
  70. { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
  71. { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
  72. { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
  73. { }
  74. };
  75. MODULE_DEVICE_TABLE(i2c, m41t80_id);
  76. struct m41t80_data {
  77. u8 features;
  78. struct rtc_device *rtc;
  79. };
  80. static int m41t80_get_datetime(struct i2c_client *client,
  81. struct rtc_time *tm)
  82. {
  83. u8 buf[M41T80_DATETIME_REG_SIZE], dt_addr[1] = { M41T80_REG_SEC };
  84. struct i2c_msg msgs[] = {
  85. {
  86. .addr = client->addr,
  87. .flags = 0,
  88. .len = 1,
  89. .buf = dt_addr,
  90. },
  91. {
  92. .addr = client->addr,
  93. .flags = I2C_M_RD,
  94. .len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
  95. .buf = buf + M41T80_REG_SEC,
  96. },
  97. };
  98. if (i2c_transfer(client->adapter, msgs, 2) < 0) {
  99. dev_err(&client->dev, "read error\n");
  100. return -EIO;
  101. }
  102. tm->tm_sec = bcd2bin(buf[M41T80_REG_SEC] & 0x7f);
  103. tm->tm_min = bcd2bin(buf[M41T80_REG_MIN] & 0x7f);
  104. tm->tm_hour = bcd2bin(buf[M41T80_REG_HOUR] & 0x3f);
  105. tm->tm_mday = bcd2bin(buf[M41T80_REG_DAY] & 0x3f);
  106. tm->tm_wday = buf[M41T80_REG_WDAY] & 0x07;
  107. tm->tm_mon = bcd2bin(buf[M41T80_REG_MON] & 0x1f) - 1;
  108. /* assume 20YY not 19YY, and ignore the Century Bit */
  109. tm->tm_year = bcd2bin(buf[M41T80_REG_YEAR]) + 100;
  110. return 0;
  111. }
  112. /* Sets the given date and time to the real time clock. */
  113. static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm)
  114. {
  115. u8 wbuf[1 + M41T80_DATETIME_REG_SIZE];
  116. u8 *buf = &wbuf[1];
  117. u8 dt_addr[1] = { M41T80_REG_SEC };
  118. struct i2c_msg msgs_in[] = {
  119. {
  120. .addr = client->addr,
  121. .flags = 0,
  122. .len = 1,
  123. .buf = dt_addr,
  124. },
  125. {
  126. .addr = client->addr,
  127. .flags = I2C_M_RD,
  128. .len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
  129. .buf = buf + M41T80_REG_SEC,
  130. },
  131. };
  132. struct i2c_msg msgs[] = {
  133. {
  134. .addr = client->addr,
  135. .flags = 0,
  136. .len = 1 + M41T80_DATETIME_REG_SIZE,
  137. .buf = wbuf,
  138. },
  139. };
  140. /* Read current reg values into buf[1..7] */
  141. if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
  142. dev_err(&client->dev, "read error\n");
  143. return -EIO;
  144. }
  145. wbuf[0] = 0; /* offset into rtc's regs */
  146. /* Merge time-data and register flags into buf[0..7] */
  147. buf[M41T80_REG_SSEC] = 0;
  148. buf[M41T80_REG_SEC] =
  149. bin2bcd(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f);
  150. buf[M41T80_REG_MIN] =
  151. bin2bcd(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f);
  152. buf[M41T80_REG_HOUR] =
  153. bin2bcd(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f) ;
  154. buf[M41T80_REG_WDAY] =
  155. (tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07);
  156. buf[M41T80_REG_DAY] =
  157. bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f);
  158. buf[M41T80_REG_MON] =
  159. bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f);
  160. /* assume 20YY not 19YY */
  161. buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100);
  162. if (i2c_transfer(client->adapter, msgs, 1) != 1) {
  163. dev_err(&client->dev, "write error\n");
  164. return -EIO;
  165. }
  166. return 0;
  167. }
  168. #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
  169. static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
  170. {
  171. struct i2c_client *client = to_i2c_client(dev);
  172. struct m41t80_data *clientdata = i2c_get_clientdata(client);
  173. u8 reg;
  174. if (clientdata->features & M41T80_FEATURE_BL) {
  175. reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
  176. seq_printf(seq, "battery\t\t: %s\n",
  177. (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
  178. }
  179. return 0;
  180. }
  181. #else
  182. #define m41t80_rtc_proc NULL
  183. #endif
  184. static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
  185. {
  186. return m41t80_get_datetime(to_i2c_client(dev), tm);
  187. }
  188. static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
  189. {
  190. return m41t80_set_datetime(to_i2c_client(dev), tm);
  191. }
  192. #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
  193. static int
  194. m41t80_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
  195. {
  196. struct i2c_client *client = to_i2c_client(dev);
  197. int rc;
  198. switch (cmd) {
  199. case RTC_AIE_OFF:
  200. case RTC_AIE_ON:
  201. break;
  202. default:
  203. return -ENOIOCTLCMD;
  204. }
  205. rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
  206. if (rc < 0)
  207. goto err;
  208. switch (cmd) {
  209. case RTC_AIE_OFF:
  210. rc &= ~M41T80_ALMON_AFE;
  211. break;
  212. case RTC_AIE_ON:
  213. rc |= M41T80_ALMON_AFE;
  214. break;
  215. }
  216. if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0)
  217. goto err;
  218. return 0;
  219. err:
  220. return -EIO;
  221. }
  222. #else
  223. #define m41t80_rtc_ioctl NULL
  224. #endif
  225. static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
  226. {
  227. struct i2c_client *client = to_i2c_client(dev);
  228. u8 wbuf[1 + M41T80_ALARM_REG_SIZE];
  229. u8 *buf = &wbuf[1];
  230. u8 *reg = buf - M41T80_REG_ALARM_MON;
  231. u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
  232. struct i2c_msg msgs_in[] = {
  233. {
  234. .addr = client->addr,
  235. .flags = 0,
  236. .len = 1,
  237. .buf = dt_addr,
  238. },
  239. {
  240. .addr = client->addr,
  241. .flags = I2C_M_RD,
  242. .len = M41T80_ALARM_REG_SIZE,
  243. .buf = buf,
  244. },
  245. };
  246. struct i2c_msg msgs[] = {
  247. {
  248. .addr = client->addr,
  249. .flags = 0,
  250. .len = 1 + M41T80_ALARM_REG_SIZE,
  251. .buf = wbuf,
  252. },
  253. };
  254. if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
  255. dev_err(&client->dev, "read error\n");
  256. return -EIO;
  257. }
  258. reg[M41T80_REG_ALARM_MON] &= ~(0x1f | M41T80_ALMON_AFE);
  259. reg[M41T80_REG_ALARM_DAY] = 0;
  260. reg[M41T80_REG_ALARM_HOUR] &= ~(0x3f | 0x80);
  261. reg[M41T80_REG_ALARM_MIN] = 0;
  262. reg[M41T80_REG_ALARM_SEC] = 0;
  263. wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */
  264. reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ?
  265. bin2bcd(t->time.tm_sec) : 0x80;
  266. reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ?
  267. bin2bcd(t->time.tm_min) : 0x80;
  268. reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ?
  269. bin2bcd(t->time.tm_hour) : 0x80;
  270. reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ?
  271. bin2bcd(t->time.tm_mday) : 0x80;
  272. if (t->time.tm_mon >= 0)
  273. reg[M41T80_REG_ALARM_MON] |= bin2bcd(t->time.tm_mon + 1);
  274. else
  275. reg[M41T80_REG_ALARM_DAY] |= 0x40;
  276. if (i2c_transfer(client->adapter, msgs, 1) != 1) {
  277. dev_err(&client->dev, "write error\n");
  278. return -EIO;
  279. }
  280. if (t->enabled) {
  281. reg[M41T80_REG_ALARM_MON] |= M41T80_ALMON_AFE;
  282. if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
  283. reg[M41T80_REG_ALARM_MON]) < 0) {
  284. dev_err(&client->dev, "write error\n");
  285. return -EIO;
  286. }
  287. }
  288. return 0;
  289. }
  290. static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
  291. {
  292. struct i2c_client *client = to_i2c_client(dev);
  293. u8 buf[M41T80_ALARM_REG_SIZE + 1]; /* all alarm regs and flags */
  294. u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
  295. u8 *reg = buf - M41T80_REG_ALARM_MON;
  296. struct i2c_msg msgs[] = {
  297. {
  298. .addr = client->addr,
  299. .flags = 0,
  300. .len = 1,
  301. .buf = dt_addr,
  302. },
  303. {
  304. .addr = client->addr,
  305. .flags = I2C_M_RD,
  306. .len = M41T80_ALARM_REG_SIZE + 1,
  307. .buf = buf,
  308. },
  309. };
  310. if (i2c_transfer(client->adapter, msgs, 2) < 0) {
  311. dev_err(&client->dev, "read error\n");
  312. return -EIO;
  313. }
  314. t->time.tm_sec = -1;
  315. t->time.tm_min = -1;
  316. t->time.tm_hour = -1;
  317. t->time.tm_mday = -1;
  318. t->time.tm_mon = -1;
  319. if (!(reg[M41T80_REG_ALARM_SEC] & 0x80))
  320. t->time.tm_sec = bcd2bin(reg[M41T80_REG_ALARM_SEC] & 0x7f);
  321. if (!(reg[M41T80_REG_ALARM_MIN] & 0x80))
  322. t->time.tm_min = bcd2bin(reg[M41T80_REG_ALARM_MIN] & 0x7f);
  323. if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80))
  324. t->time.tm_hour = bcd2bin(reg[M41T80_REG_ALARM_HOUR] & 0x3f);
  325. if (!(reg[M41T80_REG_ALARM_DAY] & 0x80))
  326. t->time.tm_mday = bcd2bin(reg[M41T80_REG_ALARM_DAY] & 0x3f);
  327. if (!(reg[M41T80_REG_ALARM_DAY] & 0x40))
  328. t->time.tm_mon = bcd2bin(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1;
  329. t->time.tm_year = -1;
  330. t->time.tm_wday = -1;
  331. t->time.tm_yday = -1;
  332. t->time.tm_isdst = -1;
  333. t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE);
  334. t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF);
  335. return 0;
  336. }
  337. static struct rtc_class_ops m41t80_rtc_ops = {
  338. .read_time = m41t80_rtc_read_time,
  339. .set_time = m41t80_rtc_set_time,
  340. .read_alarm = m41t80_rtc_read_alarm,
  341. .set_alarm = m41t80_rtc_set_alarm,
  342. .proc = m41t80_rtc_proc,
  343. .ioctl = m41t80_rtc_ioctl,
  344. };
  345. #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
  346. static ssize_t m41t80_sysfs_show_flags(struct device *dev,
  347. struct device_attribute *attr, char *buf)
  348. {
  349. struct i2c_client *client = to_i2c_client(dev);
  350. int val;
  351. val = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
  352. if (val < 0)
  353. return -EIO;
  354. return sprintf(buf, "%#x\n", val);
  355. }
  356. static DEVICE_ATTR(flags, S_IRUGO, m41t80_sysfs_show_flags, NULL);
  357. static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
  358. struct device_attribute *attr, char *buf)
  359. {
  360. struct i2c_client *client = to_i2c_client(dev);
  361. struct m41t80_data *clientdata = i2c_get_clientdata(client);
  362. int val;
  363. if (!(clientdata->features & M41T80_FEATURE_SQ))
  364. return -EINVAL;
  365. val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
  366. if (val < 0)
  367. return -EIO;
  368. val = (val >> 4) & 0xf;
  369. switch (val) {
  370. case 0:
  371. break;
  372. case 1:
  373. val = 32768;
  374. break;
  375. default:
  376. val = 32768 >> val;
  377. }
  378. return sprintf(buf, "%d\n", val);
  379. }
  380. static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
  381. struct device_attribute *attr,
  382. const char *buf, size_t count)
  383. {
  384. struct i2c_client *client = to_i2c_client(dev);
  385. struct m41t80_data *clientdata = i2c_get_clientdata(client);
  386. int almon, sqw;
  387. int val = simple_strtoul(buf, NULL, 0);
  388. if (!(clientdata->features & M41T80_FEATURE_SQ))
  389. return -EINVAL;
  390. if (val) {
  391. if (!is_power_of_2(val))
  392. return -EINVAL;
  393. val = ilog2(val);
  394. if (val == 15)
  395. val = 1;
  396. else if (val < 14)
  397. val = 15 - val;
  398. else
  399. return -EINVAL;
  400. }
  401. /* disable SQW, set SQW frequency & re-enable */
  402. almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
  403. if (almon < 0)
  404. return -EIO;
  405. sqw = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
  406. if (sqw < 0)
  407. return -EIO;
  408. sqw = (sqw & 0x0f) | (val << 4);
  409. if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
  410. almon & ~M41T80_ALMON_SQWE) < 0 ||
  411. i2c_smbus_write_byte_data(client, M41T80_REG_SQW, sqw) < 0)
  412. return -EIO;
  413. if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
  414. almon | M41T80_ALMON_SQWE) < 0)
  415. return -EIO;
  416. return count;
  417. }
  418. static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,
  419. m41t80_sysfs_show_sqwfreq, m41t80_sysfs_set_sqwfreq);
  420. static struct attribute *attrs[] = {
  421. &dev_attr_flags.attr,
  422. &dev_attr_sqwfreq.attr,
  423. NULL,
  424. };
  425. static struct attribute_group attr_group = {
  426. .attrs = attrs,
  427. };
  428. static int m41t80_sysfs_register(struct device *dev)
  429. {
  430. return sysfs_create_group(&dev->kobj, &attr_group);
  431. }
  432. #else
  433. static int m41t80_sysfs_register(struct device *dev)
  434. {
  435. return 0;
  436. }
  437. #endif
  438. #ifdef CONFIG_RTC_DRV_M41T80_WDT
  439. /*
  440. *****************************************************************************
  441. *
  442. * Watchdog Driver
  443. *
  444. *****************************************************************************
  445. */
  446. static struct i2c_client *save_client;
  447. /* Default margin */
  448. #define WD_TIMO 60 /* 1..31 seconds */
  449. static int wdt_margin = WD_TIMO;
  450. module_param(wdt_margin, int, 0);
  451. MODULE_PARM_DESC(wdt_margin, "Watchdog timeout in seconds (default 60s)");
  452. static unsigned long wdt_is_open;
  453. static int boot_flag;
  454. /**
  455. * wdt_ping:
  456. *
  457. * Reload counter one with the watchdog timeout. We don't bother reloading
  458. * the cascade counter.
  459. */
  460. static void wdt_ping(void)
  461. {
  462. unsigned char i2c_data[2];
  463. struct i2c_msg msgs1[1] = {
  464. {
  465. .addr = save_client->addr,
  466. .flags = 0,
  467. .len = 2,
  468. .buf = i2c_data,
  469. },
  470. };
  471. struct m41t80_data *clientdata = i2c_get_clientdata(save_client);
  472. i2c_data[0] = 0x09; /* watchdog register */
  473. if (wdt_margin > 31)
  474. i2c_data[1] = (wdt_margin & 0xFC) | 0x83; /* resolution = 4s */
  475. else
  476. /*
  477. * WDS = 1 (0x80), mulitplier = WD_TIMO, resolution = 1s (0x02)
  478. */
  479. i2c_data[1] = wdt_margin<<2 | 0x82;
  480. /*
  481. * M41T65 has three bits for watchdog resolution. Don't set bit 7, as
  482. * that would be an invalid resolution.
  483. */
  484. if (clientdata->features & M41T80_FEATURE_WD)
  485. i2c_data[1] &= ~M41T80_WATCHDOG_RB2;
  486. i2c_transfer(save_client->adapter, msgs1, 1);
  487. }
  488. /**
  489. * wdt_disable:
  490. *
  491. * disables watchdog.
  492. */
  493. static void wdt_disable(void)
  494. {
  495. unsigned char i2c_data[2], i2c_buf[0x10];
  496. struct i2c_msg msgs0[2] = {
  497. {
  498. .addr = save_client->addr,
  499. .flags = 0,
  500. .len = 1,
  501. .buf = i2c_data,
  502. },
  503. {
  504. .addr = save_client->addr,
  505. .flags = I2C_M_RD,
  506. .len = 1,
  507. .buf = i2c_buf,
  508. },
  509. };
  510. struct i2c_msg msgs1[1] = {
  511. {
  512. .addr = save_client->addr,
  513. .flags = 0,
  514. .len = 2,
  515. .buf = i2c_data,
  516. },
  517. };
  518. i2c_data[0] = 0x09;
  519. i2c_transfer(save_client->adapter, msgs0, 2);
  520. i2c_data[0] = 0x09;
  521. i2c_data[1] = 0x00;
  522. i2c_transfer(save_client->adapter, msgs1, 1);
  523. }
  524. /**
  525. * wdt_write:
  526. * @file: file handle to the watchdog
  527. * @buf: buffer to write (unused as data does not matter here
  528. * @count: count of bytes
  529. * @ppos: pointer to the position to write. No seeks allowed
  530. *
  531. * A write to a watchdog device is defined as a keepalive signal. Any
  532. * write of data will do, as we we don't define content meaning.
  533. */
  534. static ssize_t wdt_write(struct file *file, const char __user *buf,
  535. size_t count, loff_t *ppos)
  536. {
  537. /* Can't seek (pwrite) on this device
  538. if (ppos != &file->f_pos)
  539. return -ESPIPE;
  540. */
  541. if (count) {
  542. wdt_ping();
  543. return 1;
  544. }
  545. return 0;
  546. }
  547. static ssize_t wdt_read(struct file *file, char __user *buf,
  548. size_t count, loff_t *ppos)
  549. {
  550. return 0;
  551. }
  552. /**
  553. * wdt_ioctl:
  554. * @inode: inode of the device
  555. * @file: file handle to the device
  556. * @cmd: watchdog command
  557. * @arg: argument pointer
  558. *
  559. * The watchdog API defines a common set of functions for all watchdogs
  560. * according to their available features. We only actually usefully support
  561. * querying capabilities and current status.
  562. */
  563. static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
  564. unsigned long arg)
  565. {
  566. int new_margin, rv;
  567. static struct watchdog_info ident = {
  568. .options = WDIOF_POWERUNDER | WDIOF_KEEPALIVEPING |
  569. WDIOF_SETTIMEOUT,
  570. .firmware_version = 1,
  571. .identity = "M41T80 WTD"
  572. };
  573. switch (cmd) {
  574. case WDIOC_GETSUPPORT:
  575. return copy_to_user((struct watchdog_info __user *)arg, &ident,
  576. sizeof(ident)) ? -EFAULT : 0;
  577. case WDIOC_GETSTATUS:
  578. case WDIOC_GETBOOTSTATUS:
  579. return put_user(boot_flag, (int __user *)arg);
  580. case WDIOC_KEEPALIVE:
  581. wdt_ping();
  582. return 0;
  583. case WDIOC_SETTIMEOUT:
  584. if (get_user(new_margin, (int __user *)arg))
  585. return -EFAULT;
  586. /* Arbitrary, can't find the card's limits */
  587. if (new_margin < 1 || new_margin > 124)
  588. return -EINVAL;
  589. wdt_margin = new_margin;
  590. wdt_ping();
  591. /* Fall */
  592. case WDIOC_GETTIMEOUT:
  593. return put_user(wdt_margin, (int __user *)arg);
  594. case WDIOC_SETOPTIONS:
  595. if (copy_from_user(&rv, (int __user *)arg, sizeof(int)))
  596. return -EFAULT;
  597. if (rv & WDIOS_DISABLECARD) {
  598. pr_info("rtc-m41t80: disable watchdog\n");
  599. wdt_disable();
  600. }
  601. if (rv & WDIOS_ENABLECARD) {
  602. pr_info("rtc-m41t80: enable watchdog\n");
  603. wdt_ping();
  604. }
  605. return -EINVAL;
  606. }
  607. return -ENOTTY;
  608. }
  609. /**
  610. * wdt_open:
  611. * @inode: inode of device
  612. * @file: file handle to device
  613. *
  614. */
  615. static int wdt_open(struct inode *inode, struct file *file)
  616. {
  617. if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
  618. lock_kernel();
  619. if (test_and_set_bit(0, &wdt_is_open)) {
  620. unlock_kernel();
  621. return -EBUSY;
  622. }
  623. /*
  624. * Activate
  625. */
  626. wdt_is_open = 1;
  627. unlock_kernel();
  628. return 0;
  629. }
  630. return -ENODEV;
  631. }
  632. /**
  633. * wdt_close:
  634. * @inode: inode to board
  635. * @file: file handle to board
  636. *
  637. */
  638. static int wdt_release(struct inode *inode, struct file *file)
  639. {
  640. if (MINOR(inode->i_rdev) == WATCHDOG_MINOR)
  641. clear_bit(0, &wdt_is_open);
  642. return 0;
  643. }
  644. /**
  645. * notify_sys:
  646. * @this: our notifier block
  647. * @code: the event being reported
  648. * @unused: unused
  649. *
  650. * Our notifier is called on system shutdowns. We want to turn the card
  651. * off at reboot otherwise the machine will reboot again during memory
  652. * test or worse yet during the following fsck. This would suck, in fact
  653. * trust me - if it happens it does suck.
  654. */
  655. static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
  656. void *unused)
  657. {
  658. if (code == SYS_DOWN || code == SYS_HALT)
  659. /* Disable Watchdog */
  660. wdt_disable();
  661. return NOTIFY_DONE;
  662. }
  663. static const struct file_operations wdt_fops = {
  664. .owner = THIS_MODULE,
  665. .read = wdt_read,
  666. .ioctl = wdt_ioctl,
  667. .write = wdt_write,
  668. .open = wdt_open,
  669. .release = wdt_release,
  670. };
  671. static struct miscdevice wdt_dev = {
  672. .minor = WATCHDOG_MINOR,
  673. .name = "watchdog",
  674. .fops = &wdt_fops,
  675. };
  676. /*
  677. * The WDT card needs to learn about soft shutdowns in order to
  678. * turn the timebomb registers off.
  679. */
  680. static struct notifier_block wdt_notifier = {
  681. .notifier_call = wdt_notify_sys,
  682. };
  683. #endif /* CONFIG_RTC_DRV_M41T80_WDT */
  684. /*
  685. *****************************************************************************
  686. *
  687. * Driver Interface
  688. *
  689. *****************************************************************************
  690. */
  691. static int m41t80_probe(struct i2c_client *client,
  692. const struct i2c_device_id *id)
  693. {
  694. int rc = 0;
  695. struct rtc_device *rtc = NULL;
  696. struct rtc_time tm;
  697. struct m41t80_data *clientdata = NULL;
  698. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
  699. | I2C_FUNC_SMBUS_BYTE_DATA)) {
  700. rc = -ENODEV;
  701. goto exit;
  702. }
  703. dev_info(&client->dev,
  704. "chip found, driver version " DRV_VERSION "\n");
  705. clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL);
  706. if (!clientdata) {
  707. rc = -ENOMEM;
  708. goto exit;
  709. }
  710. rtc = rtc_device_register(client->name, &client->dev,
  711. &m41t80_rtc_ops, THIS_MODULE);
  712. if (IS_ERR(rtc)) {
  713. rc = PTR_ERR(rtc);
  714. rtc = NULL;
  715. goto exit;
  716. }
  717. clientdata->rtc = rtc;
  718. clientdata->features = id->driver_data;
  719. i2c_set_clientdata(client, clientdata);
  720. /* Make sure HT (Halt Update) bit is cleared */
  721. rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
  722. if (rc < 0)
  723. goto ht_err;
  724. if (rc & M41T80_ALHOUR_HT) {
  725. if (clientdata->features & M41T80_FEATURE_HT) {
  726. m41t80_get_datetime(client, &tm);
  727. dev_info(&client->dev, "HT bit was set!\n");
  728. dev_info(&client->dev,
  729. "Power Down at "
  730. "%04i-%02i-%02i %02i:%02i:%02i\n",
  731. tm.tm_year + 1900,
  732. tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
  733. tm.tm_min, tm.tm_sec);
  734. }
  735. if (i2c_smbus_write_byte_data(client,
  736. M41T80_REG_ALARM_HOUR,
  737. rc & ~M41T80_ALHOUR_HT) < 0)
  738. goto ht_err;
  739. }
  740. /* Make sure ST (stop) bit is cleared */
  741. rc = i2c_smbus_read_byte_data(client, M41T80_REG_SEC);
  742. if (rc < 0)
  743. goto st_err;
  744. if (rc & M41T80_SEC_ST) {
  745. if (i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
  746. rc & ~M41T80_SEC_ST) < 0)
  747. goto st_err;
  748. }
  749. rc = m41t80_sysfs_register(&client->dev);
  750. if (rc)
  751. goto exit;
  752. #ifdef CONFIG_RTC_DRV_M41T80_WDT
  753. if (clientdata->features & M41T80_FEATURE_HT) {
  754. save_client = client;
  755. rc = misc_register(&wdt_dev);
  756. if (rc)
  757. goto exit;
  758. rc = register_reboot_notifier(&wdt_notifier);
  759. if (rc) {
  760. misc_deregister(&wdt_dev);
  761. goto exit;
  762. }
  763. }
  764. #endif
  765. return 0;
  766. st_err:
  767. rc = -EIO;
  768. dev_err(&client->dev, "Can't clear ST bit\n");
  769. goto exit;
  770. ht_err:
  771. rc = -EIO;
  772. dev_err(&client->dev, "Can't clear HT bit\n");
  773. goto exit;
  774. exit:
  775. if (rtc)
  776. rtc_device_unregister(rtc);
  777. kfree(clientdata);
  778. return rc;
  779. }
  780. static int m41t80_remove(struct i2c_client *client)
  781. {
  782. struct m41t80_data *clientdata = i2c_get_clientdata(client);
  783. struct rtc_device *rtc = clientdata->rtc;
  784. #ifdef CONFIG_RTC_DRV_M41T80_WDT
  785. if (clientdata->features & M41T80_FEATURE_HT) {
  786. misc_deregister(&wdt_dev);
  787. unregister_reboot_notifier(&wdt_notifier);
  788. }
  789. #endif
  790. if (rtc)
  791. rtc_device_unregister(rtc);
  792. kfree(clientdata);
  793. return 0;
  794. }
  795. static struct i2c_driver m41t80_driver = {
  796. .driver = {
  797. .name = "rtc-m41t80",
  798. },
  799. .probe = m41t80_probe,
  800. .remove = m41t80_remove,
  801. .id_table = m41t80_id,
  802. };
  803. static int __init m41t80_rtc_init(void)
  804. {
  805. return i2c_add_driver(&m41t80_driver);
  806. }
  807. static void __exit m41t80_rtc_exit(void)
  808. {
  809. i2c_del_driver(&m41t80_driver);
  810. }
  811. MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>");
  812. MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
  813. MODULE_LICENSE("GPL");
  814. MODULE_VERSION(DRV_VERSION);
  815. module_init(m41t80_rtc_init);
  816. module_exit(m41t80_rtc_exit);