rtc-isl1208.c 14 KB

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