rtc-isl1208.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. /*
  2. * Intersil ISL1208 rtc class driver
  3. *
  4. * Copyright 2005,2006 Hebert Valerio Riedel <hvr@gnu.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2 of the License, or (at your
  9. * option) any later version.
  10. *
  11. */
  12. #include <linux/module.h>
  13. #include <linux/i2c.h>
  14. #include <linux/bcd.h>
  15. #include <linux/rtc.h>
  16. #define DRV_VERSION "0.3"
  17. /* Register map */
  18. /* rtc section */
  19. #define ISL1208_REG_SC 0x00
  20. #define ISL1208_REG_MN 0x01
  21. #define ISL1208_REG_HR 0x02
  22. #define ISL1208_REG_HR_MIL (1<<7) /* 24h/12h mode */
  23. #define ISL1208_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */
  24. #define ISL1208_REG_DT 0x03
  25. #define ISL1208_REG_MO 0x04
  26. #define ISL1208_REG_YR 0x05
  27. #define ISL1208_REG_DW 0x06
  28. #define ISL1208_RTC_SECTION_LEN 7
  29. /* control/status section */
  30. #define ISL1208_REG_SR 0x07
  31. #define ISL1208_REG_SR_ARST (1<<7) /* auto reset */
  32. #define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */
  33. #define ISL1208_REG_SR_WRTC (1<<4) /* write rtc */
  34. #define ISL1208_REG_SR_ALM (1<<2) /* alarm */
  35. #define ISL1208_REG_SR_BAT (1<<1) /* battery */
  36. #define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */
  37. #define ISL1208_REG_INT 0x08
  38. #define ISL1208_REG_09 0x09 /* reserved */
  39. #define ISL1208_REG_ATR 0x0a
  40. #define ISL1208_REG_DTR 0x0b
  41. /* alarm section */
  42. #define ISL1208_REG_SCA 0x0c
  43. #define ISL1208_REG_MNA 0x0d
  44. #define ISL1208_REG_HRA 0x0e
  45. #define ISL1208_REG_DTA 0x0f
  46. #define ISL1208_REG_MOA 0x10
  47. #define ISL1208_REG_DWA 0x11
  48. #define ISL1208_ALARM_SECTION_LEN 6
  49. /* user section */
  50. #define ISL1208_REG_USR1 0x12
  51. #define ISL1208_REG_USR2 0x13
  52. #define ISL1208_USR_SECTION_LEN 2
  53. static struct i2c_driver isl1208_driver;
  54. /* block read */
  55. static int
  56. isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
  57. unsigned len)
  58. {
  59. u8 reg_addr[1] = { reg };
  60. struct i2c_msg msgs[2] = {
  61. {client->addr, 0, sizeof(reg_addr), reg_addr}
  62. ,
  63. {client->addr, I2C_M_RD, len, buf}
  64. };
  65. int ret;
  66. BUG_ON(reg > ISL1208_REG_USR2);
  67. BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
  68. ret = i2c_transfer(client->adapter, msgs, 2);
  69. if (ret > 0)
  70. ret = 0;
  71. return ret;
  72. }
  73. /* block write */
  74. static int
  75. isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
  76. unsigned len)
  77. {
  78. u8 i2c_buf[ISL1208_REG_USR2 + 2];
  79. struct i2c_msg msgs[1] = {
  80. {client->addr, 0, len + 1, i2c_buf}
  81. };
  82. int ret;
  83. BUG_ON(reg > ISL1208_REG_USR2);
  84. BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
  85. i2c_buf[0] = reg;
  86. memcpy(&i2c_buf[1], &buf[0], len);
  87. ret = i2c_transfer(client->adapter, msgs, 1);
  88. if (ret > 0)
  89. ret = 0;
  90. return ret;
  91. }
  92. /* simple check to see wether we have a isl1208 */
  93. static int
  94. isl1208_i2c_validate_client(struct i2c_client *client)
  95. {
  96. u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
  97. u8 zero_mask[ISL1208_RTC_SECTION_LEN] = {
  98. 0x80, 0x80, 0x40, 0xc0, 0xe0, 0x00, 0xf8
  99. };
  100. int i;
  101. int ret;
  102. ret = isl1208_i2c_read_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
  103. if (ret < 0)
  104. return ret;
  105. for (i = 0; i < ISL1208_RTC_SECTION_LEN; ++i) {
  106. if (regs[i] & zero_mask[i]) /* check if bits are cleared */
  107. return -ENODEV;
  108. }
  109. return 0;
  110. }
  111. static int
  112. isl1208_i2c_get_sr(struct i2c_client *client)
  113. {
  114. int sr = i2c_smbus_read_byte_data(client, ISL1208_REG_SR);
  115. if (sr < 0)
  116. return -EIO;
  117. return sr;
  118. }
  119. static int
  120. isl1208_i2c_get_atr(struct i2c_client *client)
  121. {
  122. int atr = i2c_smbus_read_byte_data(client, ISL1208_REG_ATR);
  123. if (atr < 0)
  124. return atr;
  125. /* The 6bit value in the ATR register controls the load
  126. * capacitance C_load * in steps of 0.25pF
  127. *
  128. * bit (1<<5) of the ATR register is inverted
  129. *
  130. * C_load(ATR=0x20) = 4.50pF
  131. * C_load(ATR=0x00) = 12.50pF
  132. * C_load(ATR=0x1f) = 20.25pF
  133. *
  134. */
  135. atr &= 0x3f; /* mask out lsb */
  136. atr ^= 1 << 5; /* invert 6th bit */
  137. atr += 2 * 9; /* add offset of 4.5pF; unit[atr] = 0.25pF */
  138. return atr;
  139. }
  140. static int
  141. isl1208_i2c_get_dtr(struct i2c_client *client)
  142. {
  143. int dtr = i2c_smbus_read_byte_data(client, ISL1208_REG_DTR);
  144. if (dtr < 0)
  145. return -EIO;
  146. /* dtr encodes adjustments of {-60,-40,-20,0,20,40,60} ppm */
  147. dtr = ((dtr & 0x3) * 20) * (dtr & (1 << 2) ? -1 : 1);
  148. return dtr;
  149. }
  150. static int
  151. isl1208_i2c_get_usr(struct i2c_client *client)
  152. {
  153. u8 buf[ISL1208_USR_SECTION_LEN] = { 0, };
  154. int ret;
  155. ret = isl1208_i2c_read_regs(client, ISL1208_REG_USR1, buf,
  156. ISL1208_USR_SECTION_LEN);
  157. if (ret < 0)
  158. return ret;
  159. return (buf[1] << 8) | buf[0];
  160. }
  161. static int
  162. isl1208_i2c_set_usr(struct i2c_client *client, u16 usr)
  163. {
  164. u8 buf[ISL1208_USR_SECTION_LEN];
  165. buf[0] = usr & 0xff;
  166. buf[1] = (usr >> 8) & 0xff;
  167. return isl1208_i2c_set_regs(client, ISL1208_REG_USR1, buf,
  168. ISL1208_USR_SECTION_LEN);
  169. }
  170. static int
  171. isl1208_rtc_proc(struct device *dev, struct seq_file *seq)
  172. {
  173. struct i2c_client *const client = to_i2c_client(dev);
  174. int sr, dtr, atr, usr;
  175. sr = isl1208_i2c_get_sr(client);
  176. if (sr < 0) {
  177. dev_err(&client->dev, "%s: reading SR failed\n", __func__);
  178. return sr;
  179. }
  180. seq_printf(seq, "status_reg\t:%s%s%s%s%s%s (0x%.2x)\n",
  181. (sr & ISL1208_REG_SR_RTCF) ? " RTCF" : "",
  182. (sr & ISL1208_REG_SR_BAT) ? " BAT" : "",
  183. (sr & ISL1208_REG_SR_ALM) ? " ALM" : "",
  184. (sr & ISL1208_REG_SR_WRTC) ? " WRTC" : "",
  185. (sr & ISL1208_REG_SR_XTOSCB) ? " XTOSCB" : "",
  186. (sr & ISL1208_REG_SR_ARST) ? " ARST" : "", sr);
  187. seq_printf(seq, "batt_status\t: %s\n",
  188. (sr & ISL1208_REG_SR_RTCF) ? "bad" : "okay");
  189. dtr = isl1208_i2c_get_dtr(client);
  190. if (dtr >= 0 - 1)
  191. seq_printf(seq, "digital_trim\t: %d ppm\n", dtr);
  192. atr = isl1208_i2c_get_atr(client);
  193. if (atr >= 0)
  194. seq_printf(seq, "analog_trim\t: %d.%.2d pF\n",
  195. atr >> 2, (atr & 0x3) * 25);
  196. usr = isl1208_i2c_get_usr(client);
  197. if (usr >= 0)
  198. seq_printf(seq, "user_data\t: 0x%.4x\n", usr);
  199. return 0;
  200. }
  201. static int
  202. isl1208_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
  203. {
  204. int sr;
  205. u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
  206. sr = isl1208_i2c_get_sr(client);
  207. if (sr < 0) {
  208. dev_err(&client->dev, "%s: reading SR failed\n", __func__);
  209. return -EIO;
  210. }
  211. sr = isl1208_i2c_read_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
  212. if (sr < 0) {
  213. dev_err(&client->dev, "%s: reading RTC section failed\n",
  214. __func__);
  215. return sr;
  216. }
  217. tm->tm_sec = bcd2bin(regs[ISL1208_REG_SC]);
  218. tm->tm_min = bcd2bin(regs[ISL1208_REG_MN]);
  219. /* HR field has a more complex interpretation */
  220. {
  221. const u8 _hr = regs[ISL1208_REG_HR];
  222. if (_hr & ISL1208_REG_HR_MIL) /* 24h format */
  223. tm->tm_hour = bcd2bin(_hr & 0x3f);
  224. else {
  225. /* 12h format */
  226. tm->tm_hour = bcd2bin(_hr & 0x1f);
  227. if (_hr & ISL1208_REG_HR_PM) /* PM flag set */
  228. tm->tm_hour += 12;
  229. }
  230. }
  231. tm->tm_mday = bcd2bin(regs[ISL1208_REG_DT]);
  232. tm->tm_mon = bcd2bin(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */
  233. tm->tm_year = bcd2bin(regs[ISL1208_REG_YR]) + 100;
  234. tm->tm_wday = bcd2bin(regs[ISL1208_REG_DW]);
  235. return 0;
  236. }
  237. static int
  238. isl1208_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
  239. {
  240. struct rtc_time *const tm = &alarm->time;
  241. u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, };
  242. int sr;
  243. sr = isl1208_i2c_get_sr(client);
  244. if (sr < 0) {
  245. dev_err(&client->dev, "%s: reading SR failed\n", __func__);
  246. return sr;
  247. }
  248. sr = isl1208_i2c_read_regs(client, ISL1208_REG_SCA, regs,
  249. ISL1208_ALARM_SECTION_LEN);
  250. if (sr < 0) {
  251. dev_err(&client->dev, "%s: reading alarm section failed\n",
  252. __func__);
  253. return sr;
  254. }
  255. /* MSB of each alarm register is an enable bit */
  256. tm->tm_sec = bcd2bin(regs[ISL1208_REG_SCA - ISL1208_REG_SCA] & 0x7f);
  257. tm->tm_min = bcd2bin(regs[ISL1208_REG_MNA - ISL1208_REG_SCA] & 0x7f);
  258. tm->tm_hour = bcd2bin(regs[ISL1208_REG_HRA - ISL1208_REG_SCA] & 0x3f);
  259. tm->tm_mday = bcd2bin(regs[ISL1208_REG_DTA - ISL1208_REG_SCA] & 0x3f);
  260. tm->tm_mon =
  261. bcd2bin(regs[ISL1208_REG_MOA - ISL1208_REG_SCA] & 0x1f) - 1;
  262. tm->tm_wday = bcd2bin(regs[ISL1208_REG_DWA - ISL1208_REG_SCA] & 0x03);
  263. return 0;
  264. }
  265. static int
  266. isl1208_rtc_read_time(struct device *dev, struct rtc_time *tm)
  267. {
  268. return isl1208_i2c_read_time(to_i2c_client(dev), tm);
  269. }
  270. static int
  271. isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
  272. {
  273. int sr;
  274. u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
  275. /* The clock has an 8 bit wide bcd-coded register (they never learn)
  276. * for the year. tm_year is an offset from 1900 and we are interested
  277. * in the 2000-2099 range, so any value less than 100 is invalid.
  278. */
  279. if (tm->tm_year < 100)
  280. return -EINVAL;
  281. regs[ISL1208_REG_SC] = bin2bcd(tm->tm_sec);
  282. regs[ISL1208_REG_MN] = bin2bcd(tm->tm_min);
  283. regs[ISL1208_REG_HR] = bin2bcd(tm->tm_hour) | ISL1208_REG_HR_MIL;
  284. regs[ISL1208_REG_DT] = bin2bcd(tm->tm_mday);
  285. regs[ISL1208_REG_MO] = bin2bcd(tm->tm_mon + 1);
  286. regs[ISL1208_REG_YR] = bin2bcd(tm->tm_year - 100);
  287. regs[ISL1208_REG_DW] = bin2bcd(tm->tm_wday & 7);
  288. sr = isl1208_i2c_get_sr(client);
  289. if (sr < 0) {
  290. dev_err(&client->dev, "%s: reading SR failed\n", __func__);
  291. return sr;
  292. }
  293. /* set WRTC */
  294. sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR,
  295. sr | ISL1208_REG_SR_WRTC);
  296. if (sr < 0) {
  297. dev_err(&client->dev, "%s: writing SR failed\n", __func__);
  298. return sr;
  299. }
  300. /* write RTC registers */
  301. sr = isl1208_i2c_set_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN);
  302. if (sr < 0) {
  303. dev_err(&client->dev, "%s: writing RTC section failed\n",
  304. __func__);
  305. return sr;
  306. }
  307. /* clear WRTC again */
  308. sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR,
  309. sr & ~ISL1208_REG_SR_WRTC);
  310. if (sr < 0) {
  311. dev_err(&client->dev, "%s: writing SR failed\n", __func__);
  312. return sr;
  313. }
  314. return 0;
  315. }
  316. static int
  317. isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm)
  318. {
  319. return isl1208_i2c_set_time(to_i2c_client(dev), tm);
  320. }
  321. static int
  322. isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
  323. {
  324. return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm);
  325. }
  326. static const struct rtc_class_ops isl1208_rtc_ops = {
  327. .proc = isl1208_rtc_proc,
  328. .read_time = isl1208_rtc_read_time,
  329. .set_time = isl1208_rtc_set_time,
  330. .read_alarm = isl1208_rtc_read_alarm,
  331. /*.set_alarm = isl1208_rtc_set_alarm, */
  332. };
  333. /* sysfs interface */
  334. static ssize_t
  335. isl1208_sysfs_show_atrim(struct device *dev,
  336. struct device_attribute *attr, char *buf)
  337. {
  338. int atr = isl1208_i2c_get_atr(to_i2c_client(dev));
  339. if (atr < 0)
  340. return atr;
  341. return sprintf(buf, "%d.%.2d pF\n", atr >> 2, (atr & 0x3) * 25);
  342. }
  343. static DEVICE_ATTR(atrim, S_IRUGO, isl1208_sysfs_show_atrim, NULL);
  344. static ssize_t
  345. isl1208_sysfs_show_dtrim(struct device *dev,
  346. struct device_attribute *attr, char *buf)
  347. {
  348. int dtr = isl1208_i2c_get_dtr(to_i2c_client(dev));
  349. if (dtr < 0)
  350. return dtr;
  351. return sprintf(buf, "%d ppm\n", dtr);
  352. }
  353. static DEVICE_ATTR(dtrim, S_IRUGO, isl1208_sysfs_show_dtrim, NULL);
  354. static ssize_t
  355. isl1208_sysfs_show_usr(struct device *dev,
  356. struct device_attribute *attr, char *buf)
  357. {
  358. int usr = isl1208_i2c_get_usr(to_i2c_client(dev));
  359. if (usr < 0)
  360. return usr;
  361. return sprintf(buf, "0x%.4x\n", usr);
  362. }
  363. static ssize_t
  364. isl1208_sysfs_store_usr(struct device *dev,
  365. struct device_attribute *attr,
  366. const char *buf, size_t count)
  367. {
  368. int usr = -1;
  369. if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) {
  370. if (sscanf(buf, "%x", &usr) != 1)
  371. return -EINVAL;
  372. } else {
  373. if (sscanf(buf, "%d", &usr) != 1)
  374. return -EINVAL;
  375. }
  376. if (usr < 0 || usr > 0xffff)
  377. return -EINVAL;
  378. return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count;
  379. }
  380. static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr,
  381. isl1208_sysfs_store_usr);
  382. static int
  383. isl1208_sysfs_register(struct device *dev)
  384. {
  385. int err;
  386. err = device_create_file(dev, &dev_attr_atrim);
  387. if (err)
  388. return err;
  389. err = device_create_file(dev, &dev_attr_dtrim);
  390. if (err) {
  391. device_remove_file(dev, &dev_attr_atrim);
  392. return err;
  393. }
  394. err = device_create_file(dev, &dev_attr_usr);
  395. if (err) {
  396. device_remove_file(dev, &dev_attr_atrim);
  397. device_remove_file(dev, &dev_attr_dtrim);
  398. }
  399. return 0;
  400. }
  401. static int
  402. isl1208_sysfs_unregister(struct device *dev)
  403. {
  404. device_remove_file(dev, &dev_attr_dtrim);
  405. device_remove_file(dev, &dev_attr_atrim);
  406. device_remove_file(dev, &dev_attr_usr);
  407. return 0;
  408. }
  409. static int
  410. isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
  411. {
  412. int rc = 0;
  413. struct rtc_device *rtc;
  414. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
  415. return -ENODEV;
  416. if (isl1208_i2c_validate_client(client) < 0)
  417. return -ENODEV;
  418. dev_info(&client->dev,
  419. "chip found, driver version " DRV_VERSION "\n");
  420. rtc = rtc_device_register(isl1208_driver.driver.name,
  421. &client->dev, &isl1208_rtc_ops,
  422. THIS_MODULE);
  423. if (IS_ERR(rtc))
  424. return PTR_ERR(rtc);
  425. i2c_set_clientdata(client, rtc);
  426. rc = isl1208_i2c_get_sr(client);
  427. if (rc < 0) {
  428. dev_err(&client->dev, "reading status failed\n");
  429. goto exit_unregister;
  430. }
  431. if (rc & ISL1208_REG_SR_RTCF)
  432. dev_warn(&client->dev, "rtc power failure detected, "
  433. "please set clock.\n");
  434. rc = isl1208_sysfs_register(&client->dev);
  435. if (rc)
  436. goto exit_unregister;
  437. return 0;
  438. exit_unregister:
  439. rtc_device_unregister(rtc);
  440. return rc;
  441. }
  442. static int
  443. isl1208_remove(struct i2c_client *client)
  444. {
  445. struct rtc_device *rtc = i2c_get_clientdata(client);
  446. isl1208_sysfs_unregister(&client->dev);
  447. rtc_device_unregister(rtc);
  448. return 0;
  449. }
  450. static const struct i2c_device_id isl1208_id[] = {
  451. { "isl1208", 0 },
  452. { }
  453. };
  454. MODULE_DEVICE_TABLE(i2c, isl1208_id);
  455. static struct i2c_driver isl1208_driver = {
  456. .driver = {
  457. .name = "rtc-isl1208",
  458. },
  459. .probe = isl1208_probe,
  460. .remove = isl1208_remove,
  461. .id_table = isl1208_id,
  462. };
  463. static int __init
  464. isl1208_init(void)
  465. {
  466. return i2c_add_driver(&isl1208_driver);
  467. }
  468. static void __exit
  469. isl1208_exit(void)
  470. {
  471. i2c_del_driver(&isl1208_driver);
  472. }
  473. MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
  474. MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
  475. MODULE_LICENSE("GPL");
  476. MODULE_VERSION(DRV_VERSION);
  477. module_init(isl1208_init);
  478. module_exit(isl1208_exit);