rtc-m41t80.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  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/module.h>
  16. #include <linux/init.h>
  17. #include <linux/slab.h>
  18. #include <linux/string.h>
  19. #include <linux/i2c.h>
  20. #include <linux/rtc.h>
  21. #include <linux/bcd.h>
  22. #define M41T80_REG_SSEC 0
  23. #define M41T80_REG_SEC 1
  24. #define M41T80_REG_MIN 2
  25. #define M41T80_REG_HOUR 3
  26. #define M41T80_REG_WDAY 4
  27. #define M41T80_REG_DAY 5
  28. #define M41T80_REG_MON 6
  29. #define M41T80_REG_YEAR 7
  30. #define M41T80_REG_ALARM_MON 0xa
  31. #define M41T80_REG_ALARM_DAY 0xb
  32. #define M41T80_REG_ALARM_HOUR 0xc
  33. #define M41T80_REG_ALARM_MIN 0xd
  34. #define M41T80_REG_ALARM_SEC 0xe
  35. #define M41T80_REG_FLAGS 0xf
  36. #define M41T80_REG_SQW 0x13
  37. #define M41T80_DATETIME_REG_SIZE (M41T80_REG_YEAR + 1)
  38. #define M41T80_ALARM_REG_SIZE \
  39. (M41T80_REG_ALARM_SEC + 1 - M41T80_REG_ALARM_MON)
  40. #define M41T80_SEC_ST (1 << 7) /* ST: Stop Bit */
  41. #define M41T80_ALMON_AFE (1 << 7) /* AFE: AF Enable Bit */
  42. #define M41T80_ALMON_SQWE (1 << 6) /* SQWE: SQW Enable Bit */
  43. #define M41T80_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */
  44. #define M41T80_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */
  45. #define M41T80_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */
  46. #define M41T80_FEATURE_HT (1 << 0)
  47. #define M41T80_FEATURE_BL (1 << 1)
  48. #define DRV_VERSION "0.05"
  49. struct m41t80_chip_info {
  50. const char *name;
  51. u8 features;
  52. };
  53. static const struct m41t80_chip_info m41t80_chip_info_tbl[] = {
  54. {
  55. .name = "m41t80",
  56. .features = 0,
  57. },
  58. {
  59. .name = "m41t81",
  60. .features = M41T80_FEATURE_HT,
  61. },
  62. {
  63. .name = "m41t81s",
  64. .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
  65. },
  66. {
  67. .name = "m41t82",
  68. .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
  69. },
  70. {
  71. .name = "m41t83",
  72. .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
  73. },
  74. {
  75. .name = "m41st84",
  76. .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
  77. },
  78. {
  79. .name = "m41st85",
  80. .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
  81. },
  82. {
  83. .name = "m41st87",
  84. .features = M41T80_FEATURE_HT | M41T80_FEATURE_BL,
  85. },
  86. };
  87. struct m41t80_data {
  88. const struct m41t80_chip_info *chip;
  89. struct rtc_device *rtc;
  90. };
  91. static int m41t80_get_datetime(struct i2c_client *client,
  92. struct rtc_time *tm)
  93. {
  94. u8 buf[M41T80_DATETIME_REG_SIZE], dt_addr[1] = { M41T80_REG_SEC };
  95. struct i2c_msg msgs[] = {
  96. {
  97. .addr = client->addr,
  98. .flags = 0,
  99. .len = 1,
  100. .buf = dt_addr,
  101. },
  102. {
  103. .addr = client->addr,
  104. .flags = I2C_M_RD,
  105. .len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
  106. .buf = buf + M41T80_REG_SEC,
  107. },
  108. };
  109. if (i2c_transfer(client->adapter, msgs, 2) < 0) {
  110. dev_err(&client->dev, "read error\n");
  111. return -EIO;
  112. }
  113. tm->tm_sec = BCD2BIN(buf[M41T80_REG_SEC] & 0x7f);
  114. tm->tm_min = BCD2BIN(buf[M41T80_REG_MIN] & 0x7f);
  115. tm->tm_hour = BCD2BIN(buf[M41T80_REG_HOUR] & 0x3f);
  116. tm->tm_mday = BCD2BIN(buf[M41T80_REG_DAY] & 0x3f);
  117. tm->tm_wday = buf[M41T80_REG_WDAY] & 0x07;
  118. tm->tm_mon = BCD2BIN(buf[M41T80_REG_MON] & 0x1f) - 1;
  119. /* assume 20YY not 19YY, and ignore the Century Bit */
  120. tm->tm_year = BCD2BIN(buf[M41T80_REG_YEAR]) + 100;
  121. return 0;
  122. }
  123. /* Sets the given date and time to the real time clock. */
  124. static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm)
  125. {
  126. u8 wbuf[1 + M41T80_DATETIME_REG_SIZE];
  127. u8 *buf = &wbuf[1];
  128. u8 dt_addr[1] = { M41T80_REG_SEC };
  129. struct i2c_msg msgs_in[] = {
  130. {
  131. .addr = client->addr,
  132. .flags = 0,
  133. .len = 1,
  134. .buf = dt_addr,
  135. },
  136. {
  137. .addr = client->addr,
  138. .flags = I2C_M_RD,
  139. .len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
  140. .buf = buf + M41T80_REG_SEC,
  141. },
  142. };
  143. struct i2c_msg msgs[] = {
  144. {
  145. .addr = client->addr,
  146. .flags = 0,
  147. .len = 1 + M41T80_DATETIME_REG_SIZE,
  148. .buf = wbuf,
  149. },
  150. };
  151. /* Read current reg values into buf[1..7] */
  152. if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
  153. dev_err(&client->dev, "read error\n");
  154. return -EIO;
  155. }
  156. wbuf[0] = 0; /* offset into rtc's regs */
  157. /* Merge time-data and register flags into buf[0..7] */
  158. buf[M41T80_REG_SSEC] = 0;
  159. buf[M41T80_REG_SEC] =
  160. BIN2BCD(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f);
  161. buf[M41T80_REG_MIN] =
  162. BIN2BCD(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f);
  163. buf[M41T80_REG_HOUR] =
  164. BIN2BCD(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f) ;
  165. buf[M41T80_REG_WDAY] =
  166. (tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07);
  167. buf[M41T80_REG_DAY] =
  168. BIN2BCD(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f);
  169. buf[M41T80_REG_MON] =
  170. BIN2BCD(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f);
  171. /* assume 20YY not 19YY */
  172. buf[M41T80_REG_YEAR] = BIN2BCD(tm->tm_year % 100);
  173. if (i2c_transfer(client->adapter, msgs, 1) != 1) {
  174. dev_err(&client->dev, "write error\n");
  175. return -EIO;
  176. }
  177. return 0;
  178. }
  179. #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
  180. static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
  181. {
  182. struct i2c_client *client = to_i2c_client(dev);
  183. struct m41t80_data *clientdata = i2c_get_clientdata(client);
  184. u8 reg;
  185. if (clientdata->chip->features & M41T80_FEATURE_BL) {
  186. reg = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
  187. seq_printf(seq, "battery\t\t: %s\n",
  188. (reg & M41T80_FLAGS_BATT_LOW) ? "exhausted" : "ok");
  189. }
  190. return 0;
  191. }
  192. #else
  193. #define m41t80_rtc_proc NULL
  194. #endif
  195. static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
  196. {
  197. return m41t80_get_datetime(to_i2c_client(dev), tm);
  198. }
  199. static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
  200. {
  201. return m41t80_set_datetime(to_i2c_client(dev), tm);
  202. }
  203. #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
  204. static int
  205. m41t80_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
  206. {
  207. struct i2c_client *client = to_i2c_client(dev);
  208. int rc;
  209. switch (cmd) {
  210. case RTC_AIE_OFF:
  211. case RTC_AIE_ON:
  212. break;
  213. default:
  214. return -ENOIOCTLCMD;
  215. }
  216. rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
  217. if (rc < 0)
  218. goto err;
  219. switch (cmd) {
  220. case RTC_AIE_OFF:
  221. rc &= ~M41T80_ALMON_AFE;
  222. break;
  223. case RTC_AIE_ON:
  224. rc |= M41T80_ALMON_AFE;
  225. break;
  226. }
  227. if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0)
  228. goto err;
  229. return 0;
  230. err:
  231. return -EIO;
  232. }
  233. #else
  234. #define m41t80_rtc_ioctl NULL
  235. #endif
  236. static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
  237. {
  238. struct i2c_client *client = to_i2c_client(dev);
  239. u8 wbuf[1 + M41T80_ALARM_REG_SIZE];
  240. u8 *buf = &wbuf[1];
  241. u8 *reg = buf - M41T80_REG_ALARM_MON;
  242. u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
  243. struct i2c_msg msgs_in[] = {
  244. {
  245. .addr = client->addr,
  246. .flags = 0,
  247. .len = 1,
  248. .buf = dt_addr,
  249. },
  250. {
  251. .addr = client->addr,
  252. .flags = I2C_M_RD,
  253. .len = M41T80_ALARM_REG_SIZE,
  254. .buf = buf,
  255. },
  256. };
  257. struct i2c_msg msgs[] = {
  258. {
  259. .addr = client->addr,
  260. .flags = 0,
  261. .len = 1 + M41T80_ALARM_REG_SIZE,
  262. .buf = wbuf,
  263. },
  264. };
  265. if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
  266. dev_err(&client->dev, "read error\n");
  267. return -EIO;
  268. }
  269. reg[M41T80_REG_ALARM_MON] &= ~(0x1f | M41T80_ALMON_AFE);
  270. reg[M41T80_REG_ALARM_DAY] = 0;
  271. reg[M41T80_REG_ALARM_HOUR] &= ~(0x3f | 0x80);
  272. reg[M41T80_REG_ALARM_MIN] = 0;
  273. reg[M41T80_REG_ALARM_SEC] = 0;
  274. wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */
  275. reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ?
  276. BIN2BCD(t->time.tm_sec) : 0x80;
  277. reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ?
  278. BIN2BCD(t->time.tm_min) : 0x80;
  279. reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ?
  280. BIN2BCD(t->time.tm_hour) : 0x80;
  281. reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ?
  282. BIN2BCD(t->time.tm_mday) : 0x80;
  283. if (t->time.tm_mon >= 0)
  284. reg[M41T80_REG_ALARM_MON] |= BIN2BCD(t->time.tm_mon + 1);
  285. else
  286. reg[M41T80_REG_ALARM_DAY] |= 0x40;
  287. if (i2c_transfer(client->adapter, msgs, 1) != 1) {
  288. dev_err(&client->dev, "write error\n");
  289. return -EIO;
  290. }
  291. if (t->enabled) {
  292. reg[M41T80_REG_ALARM_MON] |= M41T80_ALMON_AFE;
  293. if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
  294. reg[M41T80_REG_ALARM_MON]) < 0) {
  295. dev_err(&client->dev, "write error\n");
  296. return -EIO;
  297. }
  298. }
  299. return 0;
  300. }
  301. static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
  302. {
  303. struct i2c_client *client = to_i2c_client(dev);
  304. u8 buf[M41T80_ALARM_REG_SIZE + 1]; /* all alarm regs and flags */
  305. u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
  306. u8 *reg = buf - M41T80_REG_ALARM_MON;
  307. struct i2c_msg msgs[] = {
  308. {
  309. .addr = client->addr,
  310. .flags = 0,
  311. .len = 1,
  312. .buf = dt_addr,
  313. },
  314. {
  315. .addr = client->addr,
  316. .flags = I2C_M_RD,
  317. .len = M41T80_ALARM_REG_SIZE + 1,
  318. .buf = buf,
  319. },
  320. };
  321. if (i2c_transfer(client->adapter, msgs, 2) < 0) {
  322. dev_err(&client->dev, "read error\n");
  323. return -EIO;
  324. }
  325. t->time.tm_sec = -1;
  326. t->time.tm_min = -1;
  327. t->time.tm_hour = -1;
  328. t->time.tm_mday = -1;
  329. t->time.tm_mon = -1;
  330. if (!(reg[M41T80_REG_ALARM_SEC] & 0x80))
  331. t->time.tm_sec = BCD2BIN(reg[M41T80_REG_ALARM_SEC] & 0x7f);
  332. if (!(reg[M41T80_REG_ALARM_MIN] & 0x80))
  333. t->time.tm_min = BCD2BIN(reg[M41T80_REG_ALARM_MIN] & 0x7f);
  334. if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80))
  335. t->time.tm_hour = BCD2BIN(reg[M41T80_REG_ALARM_HOUR] & 0x3f);
  336. if (!(reg[M41T80_REG_ALARM_DAY] & 0x80))
  337. t->time.tm_mday = BCD2BIN(reg[M41T80_REG_ALARM_DAY] & 0x3f);
  338. if (!(reg[M41T80_REG_ALARM_DAY] & 0x40))
  339. t->time.tm_mon = BCD2BIN(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1;
  340. t->time.tm_year = -1;
  341. t->time.tm_wday = -1;
  342. t->time.tm_yday = -1;
  343. t->time.tm_isdst = -1;
  344. t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE);
  345. t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF);
  346. return 0;
  347. }
  348. static struct rtc_class_ops m41t80_rtc_ops = {
  349. .read_time = m41t80_rtc_read_time,
  350. .set_time = m41t80_rtc_set_time,
  351. .read_alarm = m41t80_rtc_read_alarm,
  352. .set_alarm = m41t80_rtc_set_alarm,
  353. .proc = m41t80_rtc_proc,
  354. .ioctl = m41t80_rtc_ioctl,
  355. };
  356. #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
  357. static ssize_t m41t80_sysfs_show_flags(struct device *dev,
  358. struct device_attribute *attr, char *buf)
  359. {
  360. struct i2c_client *client = to_i2c_client(dev);
  361. int val;
  362. val = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
  363. if (val < 0)
  364. return -EIO;
  365. return sprintf(buf, "%#x\n", val);
  366. }
  367. static DEVICE_ATTR(flags, S_IRUGO, m41t80_sysfs_show_flags, NULL);
  368. static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
  369. struct device_attribute *attr, char *buf)
  370. {
  371. struct i2c_client *client = to_i2c_client(dev);
  372. int val;
  373. val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
  374. if (val < 0)
  375. return -EIO;
  376. val = (val >> 4) & 0xf;
  377. switch (val) {
  378. case 0:
  379. break;
  380. case 1:
  381. val = 32768;
  382. break;
  383. default:
  384. val = 32768 >> val;
  385. }
  386. return sprintf(buf, "%d\n", val);
  387. }
  388. static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
  389. struct device_attribute *attr,
  390. const char *buf, size_t count)
  391. {
  392. struct i2c_client *client = to_i2c_client(dev);
  393. int almon, sqw;
  394. int val = simple_strtoul(buf, NULL, 0);
  395. if (val) {
  396. if (!is_power_of_2(val))
  397. return -EINVAL;
  398. val = ilog2(val);
  399. if (val == 15)
  400. val = 1;
  401. else if (val < 14)
  402. val = 15 - val;
  403. else
  404. return -EINVAL;
  405. }
  406. /* disable SQW, set SQW frequency & re-enable */
  407. almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
  408. if (almon < 0)
  409. return -EIO;
  410. sqw = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
  411. if (sqw < 0)
  412. return -EIO;
  413. sqw = (sqw & 0x0f) | (val << 4);
  414. if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
  415. almon & ~M41T80_ALMON_SQWE) < 0 ||
  416. i2c_smbus_write_byte_data(client, M41T80_REG_SQW, sqw) < 0)
  417. return -EIO;
  418. if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
  419. almon | M41T80_ALMON_SQWE) < 0)
  420. return -EIO;
  421. return count;
  422. }
  423. static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,
  424. m41t80_sysfs_show_sqwfreq, m41t80_sysfs_set_sqwfreq);
  425. static struct attribute *attrs[] = {
  426. &dev_attr_flags.attr,
  427. &dev_attr_sqwfreq.attr,
  428. NULL,
  429. };
  430. static struct attribute_group attr_group = {
  431. .attrs = attrs,
  432. };
  433. static int m41t80_sysfs_register(struct device *dev)
  434. {
  435. return sysfs_create_group(&dev->kobj, &attr_group);
  436. }
  437. #else
  438. static int m41t80_sysfs_register(struct device *dev)
  439. {
  440. return 0;
  441. }
  442. #endif
  443. /*
  444. *****************************************************************************
  445. *
  446. * Driver Interface
  447. *
  448. *****************************************************************************
  449. */
  450. static int m41t80_probe(struct i2c_client *client)
  451. {
  452. int i, rc = 0;
  453. struct rtc_device *rtc = NULL;
  454. struct rtc_time tm;
  455. const struct m41t80_chip_info *chip;
  456. struct m41t80_data *clientdata = NULL;
  457. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
  458. | I2C_FUNC_SMBUS_BYTE_DATA)) {
  459. rc = -ENODEV;
  460. goto exit;
  461. }
  462. dev_info(&client->dev,
  463. "chip found, driver version " DRV_VERSION "\n");
  464. chip = NULL;
  465. for (i = 0; i < ARRAY_SIZE(m41t80_chip_info_tbl); i++) {
  466. if (!strcmp(m41t80_chip_info_tbl[i].name, client->name)) {
  467. chip = &m41t80_chip_info_tbl[i];
  468. break;
  469. }
  470. }
  471. if (!chip) {
  472. dev_err(&client->dev, "%s is not supported\n", client->name);
  473. rc = -ENODEV;
  474. goto exit;
  475. }
  476. clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL);
  477. if (!clientdata) {
  478. rc = -ENOMEM;
  479. goto exit;
  480. }
  481. rtc = rtc_device_register(client->name, &client->dev,
  482. &m41t80_rtc_ops, THIS_MODULE);
  483. if (IS_ERR(rtc)) {
  484. rc = PTR_ERR(rtc);
  485. rtc = NULL;
  486. goto exit;
  487. }
  488. clientdata->rtc = rtc;
  489. clientdata->chip = chip;
  490. i2c_set_clientdata(client, clientdata);
  491. /* Make sure HT (Halt Update) bit is cleared */
  492. rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
  493. if (rc < 0)
  494. goto ht_err;
  495. if (rc & M41T80_ALHOUR_HT) {
  496. if (chip->features & M41T80_FEATURE_HT) {
  497. m41t80_get_datetime(client, &tm);
  498. dev_info(&client->dev, "HT bit was set!\n");
  499. dev_info(&client->dev,
  500. "Power Down at "
  501. "%04i-%02i-%02i %02i:%02i:%02i\n",
  502. tm.tm_year + 1900,
  503. tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
  504. tm.tm_min, tm.tm_sec);
  505. }
  506. if (i2c_smbus_write_byte_data(client,
  507. M41T80_REG_ALARM_HOUR,
  508. rc & ~M41T80_ALHOUR_HT) < 0)
  509. goto ht_err;
  510. }
  511. /* Make sure ST (stop) bit is cleared */
  512. rc = i2c_smbus_read_byte_data(client, M41T80_REG_SEC);
  513. if (rc < 0)
  514. goto st_err;
  515. if (rc & M41T80_SEC_ST) {
  516. if (i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
  517. rc & ~M41T80_SEC_ST) < 0)
  518. goto st_err;
  519. }
  520. rc = m41t80_sysfs_register(&client->dev);
  521. if (rc)
  522. goto exit;
  523. return 0;
  524. st_err:
  525. rc = -EIO;
  526. dev_err(&client->dev, "Can't clear ST bit\n");
  527. goto exit;
  528. ht_err:
  529. rc = -EIO;
  530. dev_err(&client->dev, "Can't clear HT bit\n");
  531. goto exit;
  532. exit:
  533. if (rtc)
  534. rtc_device_unregister(rtc);
  535. kfree(clientdata);
  536. return rc;
  537. }
  538. static int m41t80_remove(struct i2c_client *client)
  539. {
  540. struct m41t80_data *clientdata = i2c_get_clientdata(client);
  541. struct rtc_device *rtc = clientdata->rtc;
  542. if (rtc)
  543. rtc_device_unregister(rtc);
  544. kfree(clientdata);
  545. return 0;
  546. }
  547. static struct i2c_driver m41t80_driver = {
  548. .driver = {
  549. .name = "m41t80",
  550. },
  551. .probe = m41t80_probe,
  552. .remove = m41t80_remove,
  553. };
  554. static int __init m41t80_rtc_init(void)
  555. {
  556. return i2c_add_driver(&m41t80_driver);
  557. }
  558. static void __exit m41t80_rtc_exit(void)
  559. {
  560. i2c_del_driver(&m41t80_driver);
  561. }
  562. MODULE_AUTHOR("Alexander Bigga <ab@mycable.de>");
  563. MODULE_DESCRIPTION("ST Microelectronics M41T80 series RTC I2C Client Driver");
  564. MODULE_LICENSE("GPL");
  565. MODULE_VERSION(DRV_VERSION);
  566. module_init(m41t80_rtc_init);
  567. module_exit(m41t80_rtc_exit);