ds1302.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /*!***************************************************************************
  2. *!
  3. *! FILE NAME : ds1302.c
  4. *!
  5. *! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O
  6. *!
  7. *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
  8. *!
  9. *! $Log: ds1302.c,v $
  10. *! Revision 1.18 2005/01/24 09:11:26 mikaelam
  11. *! Minor changes to get DS1302 RTC chip driver to work
  12. *!
  13. *! Revision 1.17 2005/01/05 06:11:22 starvik
  14. *! No need to do local_irq_disable after local_irq_save.
  15. *!
  16. *! Revision 1.16 2004/12/13 12:21:52 starvik
  17. *! Added I/O and DMA allocators from Linux 2.4
  18. *!
  19. *! Revision 1.14 2004/08/24 06:48:43 starvik
  20. *! Whitespace cleanup
  21. *!
  22. *! Revision 1.13 2004/05/28 09:26:59 starvik
  23. *! Modified I2C initialization to work in 2.6.
  24. *!
  25. *! Revision 1.12 2004/05/14 07:58:03 starvik
  26. *! Merge of changes from 2.4
  27. *!
  28. *! Revision 1.10 2004/02/04 09:25:12 starvik
  29. *! Merge of Linux 2.6.2
  30. *!
  31. *! Revision 1.9 2003/07/04 08:27:37 starvik
  32. *! Merge of Linux 2.5.74
  33. *!
  34. *! Revision 1.8 2003/04/09 05:20:47 starvik
  35. *! Merge of Linux 2.5.67
  36. *!
  37. *! Revision 1.6 2003/01/09 14:42:51 starvik
  38. *! Merge of Linux 2.5.55
  39. *!
  40. *! Revision 1.4 2002/12/11 13:13:57 starvik
  41. *! Added arch/ to v10 specific includes
  42. *! Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
  43. *!
  44. *! Revision 1.3 2002/11/20 11:56:10 starvik
  45. *! Merge of Linux 2.5.48
  46. *!
  47. *! Revision 1.2 2002/11/18 13:16:06 starvik
  48. *! Linux 2.5 port of latest 2.4 drivers
  49. *!
  50. *! Revision 1.15 2002/10/11 16:14:33 johana
  51. *! Added CONFIG_ETRAX_DS1302_TRICKLE_CHARGE and initial setting of the
  52. *! trcklecharge register.
  53. *!
  54. *! Revision 1.14 2002/10/10 12:15:38 magnusmn
  55. *! Added support for having the RST signal on bit g0
  56. *!
  57. *! Revision 1.13 2002/05/29 15:16:08 johana
  58. *! Removed unused variables.
  59. *!
  60. *! Revision 1.12 2002/04/10 15:35:25 johana
  61. *! Moved probe function closer to init function and marked it __init.
  62. *!
  63. *! Revision 1.11 2001/06/14 12:35:52 jonashg
  64. *! The ATA hack is back. It is unfortunately the only way to set g27 to output.
  65. *!
  66. *! Revision 1.9 2001/06/14 10:00:14 jonashg
  67. *! No need for tempudelay to be inline anymore (had to adjust the usec to
  68. *! loops conversion because of this to make it slow enough to be a udelay).
  69. *!
  70. *! Revision 1.8 2001/06/14 08:06:32 jonashg
  71. *! Made tempudelay delay usecs (well, just a tad more).
  72. *!
  73. *! Revision 1.7 2001/06/13 14:18:11 jonashg
  74. *! Only allow processes with SYS_TIME capability to set time and charge.
  75. *!
  76. *! Revision 1.6 2001/06/12 15:22:07 jonashg
  77. *! * Made init function __init.
  78. *! * Parameter to out_byte() is unsigned char.
  79. *! * The magic number 42 has got a name.
  80. *! * Removed comment about /proc (nothing is exported there).
  81. *!
  82. *! Revision 1.5 2001/06/12 14:35:13 jonashg
  83. *! Gave the module a name and added it to printk's.
  84. *!
  85. *! Revision 1.4 2001/05/31 14:53:40 jonashg
  86. *! Made tempudelay() inline so that the watchdog doesn't reset (see
  87. *! function comment).
  88. *!
  89. *! Revision 1.3 2001/03/26 16:03:06 bjornw
  90. *! Needs linux/config.h
  91. *!
  92. *! Revision 1.2 2001/03/20 19:42:00 bjornw
  93. *! Use the ETRAX prefix on the DS1302 options
  94. *!
  95. *! Revision 1.1 2001/03/20 09:13:50 magnusmn
  96. *! Linux 2.4 port
  97. *!
  98. *! Revision 1.10 2000/07/05 15:38:23 bjornw
  99. *! Dont update kernel time when a RTC_SET_TIME is done
  100. *!
  101. *! Revision 1.9 2000/03/02 15:42:59 macce
  102. *! * Hack to make RTC work on all 2100/2400
  103. *!
  104. *! Revision 1.8 2000/02/23 16:59:18 torbjore
  105. *! added setup of R_GEN_CONFIG when RTC is connected to the generic port.
  106. *!
  107. *! Revision 1.7 2000/01/17 15:51:43 johana
  108. *! Added RTC_SET_CHARGE ioctl to enable trickle charger.
  109. *!
  110. *! Revision 1.6 1999/10/27 13:19:47 bjornw
  111. *! Added update_xtime_from_cmos which reads back the updated RTC into the kernel.
  112. *! /dev/rtc calls it now.
  113. *!
  114. *! Revision 1.5 1999/10/27 12:39:37 bjornw
  115. *! Disabled superuser check. Anyone can now set the time.
  116. *!
  117. *! Revision 1.4 1999/09/02 13:27:46 pkj
  118. *! Added shadow for R_PORT_PB_CONFIG.
  119. *! Renamed port_g_shadow to port_g_data_shadow.
  120. *!
  121. *! Revision 1.3 1999/09/02 08:28:06 pkj
  122. *! Made it possible to select either port PB or the generic port for the RST
  123. *! signal line to the DS1302 RTC.
  124. *! Also make sure the RST bit is configured as output on Port PB (if used).
  125. *!
  126. *! Revision 1.2 1999/09/01 14:47:20 bjornw
  127. *! Added support for /dev/rtc operations with ioctl RD_TIME and SET_TIME to read
  128. *! and set the date. Register as major 121.
  129. *!
  130. *! Revision 1.1 1999/09/01 09:45:29 bjornw
  131. *! Implemented a DS1302 RTC driver.
  132. *!
  133. *!
  134. *! ---------------------------------------------------------------------------
  135. *!
  136. *! (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004 Axis Communications AB, LUND, SWEDEN
  137. *!
  138. *! $Id: ds1302.c,v 1.18 2005/01/24 09:11:26 mikaelam Exp $
  139. *!
  140. *!***************************************************************************/
  141. #include <linux/config.h>
  142. #include <linux/fs.h>
  143. #include <linux/init.h>
  144. #include <linux/mm.h>
  145. #include <linux/module.h>
  146. #include <linux/miscdevice.h>
  147. #include <linux/delay.h>
  148. #include <linux/bcd.h>
  149. #include <asm/uaccess.h>
  150. #include <asm/system.h>
  151. #include <asm/arch/svinto.h>
  152. #include <asm/io.h>
  153. #include <asm/rtc.h>
  154. #include <asm/arch/io_interface_mux.h>
  155. #define RTC_MAJOR_NR 121 /* local major, change later */
  156. static const char ds1302_name[] = "ds1302";
  157. /* The DS1302 might be connected to different bits on different products.
  158. * It has three signals - SDA, SCL and RST. RST and SCL are always outputs,
  159. * but SDA can have a selected direction.
  160. * For now, only PORT_PB is hardcoded.
  161. */
  162. /* The RST bit may be on either the Generic Port or Port PB. */
  163. #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
  164. #define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
  165. #define TK_RST_DIR(x)
  166. #else
  167. #define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
  168. #define TK_RST_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
  169. #endif
  170. #define TK_SDA_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SDABIT, x)
  171. #define TK_SCL_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x)
  172. #define TK_SDA_IN() ((*R_PORT_PB_READ >> CONFIG_ETRAX_DS1302_SDABIT) & 1)
  173. /* 1 is out, 0 is in */
  174. #define TK_SDA_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SDABIT, x)
  175. #define TK_SCL_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR, port_pb_dir_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x)
  176. /*
  177. * The reason for tempudelay and not udelay is that loops_per_usec
  178. * (used in udelay) is not set when functions here are called from time.c
  179. */
  180. static void tempudelay(int usecs)
  181. {
  182. volatile int loops;
  183. for(loops = usecs * 12; loops > 0; loops--)
  184. /* nothing */;
  185. }
  186. /* Send 8 bits. */
  187. static void
  188. out_byte(unsigned char x)
  189. {
  190. int i;
  191. TK_SDA_DIR(1);
  192. for (i = 8; i--;) {
  193. /* The chip latches incoming bits on the rising edge of SCL. */
  194. TK_SCL_OUT(0);
  195. TK_SDA_OUT(x & 1);
  196. tempudelay(1);
  197. TK_SCL_OUT(1);
  198. tempudelay(1);
  199. x >>= 1;
  200. }
  201. TK_SDA_DIR(0);
  202. }
  203. static unsigned char
  204. in_byte(void)
  205. {
  206. unsigned char x = 0;
  207. int i;
  208. /* Read byte. Bits come LSB first, on the falling edge of SCL.
  209. * Assume SDA is in input direction already.
  210. */
  211. TK_SDA_DIR(0);
  212. for (i = 8; i--;) {
  213. TK_SCL_OUT(0);
  214. tempudelay(1);
  215. x >>= 1;
  216. x |= (TK_SDA_IN() << 7);
  217. TK_SCL_OUT(1);
  218. tempudelay(1);
  219. }
  220. return x;
  221. }
  222. /* Prepares for a transaction by de-activating RST (active-low). */
  223. static void
  224. start(void)
  225. {
  226. TK_SCL_OUT(0);
  227. tempudelay(1);
  228. TK_RST_OUT(0);
  229. tempudelay(5);
  230. TK_RST_OUT(1);
  231. }
  232. /* Ends a transaction by taking RST active again. */
  233. static void
  234. stop(void)
  235. {
  236. tempudelay(2);
  237. TK_RST_OUT(0);
  238. }
  239. /* Enable writing. */
  240. static void
  241. ds1302_wenable(void)
  242. {
  243. start();
  244. out_byte(0x8e); /* Write control register */
  245. out_byte(0x00); /* Disable write protect bit 7 = 0 */
  246. stop();
  247. }
  248. /* Disable writing. */
  249. static void
  250. ds1302_wdisable(void)
  251. {
  252. start();
  253. out_byte(0x8e); /* Write control register */
  254. out_byte(0x80); /* Disable write protect bit 7 = 0 */
  255. stop();
  256. }
  257. /* Read a byte from the selected register in the DS1302. */
  258. unsigned char
  259. ds1302_readreg(int reg)
  260. {
  261. unsigned char x;
  262. start();
  263. out_byte(0x81 | (reg << 1)); /* read register */
  264. x = in_byte();
  265. stop();
  266. return x;
  267. }
  268. /* Write a byte to the selected register. */
  269. void
  270. ds1302_writereg(int reg, unsigned char val)
  271. {
  272. #ifndef CONFIG_ETRAX_RTC_READONLY
  273. int do_writereg = 1;
  274. #else
  275. int do_writereg = 0;
  276. if (reg == RTC_TRICKLECHARGER)
  277. do_writereg = 1;
  278. #endif
  279. if (do_writereg) {
  280. ds1302_wenable();
  281. start();
  282. out_byte(0x80 | (reg << 1)); /* write register */
  283. out_byte(val);
  284. stop();
  285. ds1302_wdisable();
  286. }
  287. }
  288. void
  289. get_rtc_time(struct rtc_time *rtc_tm)
  290. {
  291. unsigned long flags;
  292. local_irq_save(flags);
  293. rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
  294. rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
  295. rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
  296. rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
  297. rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
  298. rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
  299. local_irq_restore(flags);
  300. BCD_TO_BIN(rtc_tm->tm_sec);
  301. BCD_TO_BIN(rtc_tm->tm_min);
  302. BCD_TO_BIN(rtc_tm->tm_hour);
  303. BCD_TO_BIN(rtc_tm->tm_mday);
  304. BCD_TO_BIN(rtc_tm->tm_mon);
  305. BCD_TO_BIN(rtc_tm->tm_year);
  306. /*
  307. * Account for differences between how the RTC uses the values
  308. * and how they are defined in a struct rtc_time;
  309. */
  310. if (rtc_tm->tm_year <= 69)
  311. rtc_tm->tm_year += 100;
  312. rtc_tm->tm_mon--;
  313. }
  314. static unsigned char days_in_mo[] =
  315. {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  316. /* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date). */
  317. static int
  318. rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
  319. unsigned long arg)
  320. {
  321. unsigned long flags;
  322. switch(cmd) {
  323. case RTC_RD_TIME: /* read the time/date from RTC */
  324. {
  325. struct rtc_time rtc_tm;
  326. memset(&rtc_tm, 0, sizeof (struct rtc_time));
  327. get_rtc_time(&rtc_tm);
  328. if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
  329. return -EFAULT;
  330. return 0;
  331. }
  332. case RTC_SET_TIME: /* set the RTC */
  333. {
  334. struct rtc_time rtc_tm;
  335. unsigned char mon, day, hrs, min, sec, leap_yr;
  336. unsigned int yrs;
  337. if (!capable(CAP_SYS_TIME))
  338. return -EPERM;
  339. if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
  340. return -EFAULT;
  341. yrs = rtc_tm.tm_year + 1900;
  342. mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
  343. day = rtc_tm.tm_mday;
  344. hrs = rtc_tm.tm_hour;
  345. min = rtc_tm.tm_min;
  346. sec = rtc_tm.tm_sec;
  347. if ((yrs < 1970) || (yrs > 2069))
  348. return -EINVAL;
  349. leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
  350. if ((mon > 12) || (day == 0))
  351. return -EINVAL;
  352. if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
  353. return -EINVAL;
  354. if ((hrs >= 24) || (min >= 60) || (sec >= 60))
  355. return -EINVAL;
  356. if (yrs >= 2000)
  357. yrs -= 2000; /* RTC (0, 1, ... 69) */
  358. else
  359. yrs -= 1900; /* RTC (70, 71, ... 99) */
  360. BIN_TO_BCD(sec);
  361. BIN_TO_BCD(min);
  362. BIN_TO_BCD(hrs);
  363. BIN_TO_BCD(day);
  364. BIN_TO_BCD(mon);
  365. BIN_TO_BCD(yrs);
  366. local_irq_save(flags);
  367. CMOS_WRITE(yrs, RTC_YEAR);
  368. CMOS_WRITE(mon, RTC_MONTH);
  369. CMOS_WRITE(day, RTC_DAY_OF_MONTH);
  370. CMOS_WRITE(hrs, RTC_HOURS);
  371. CMOS_WRITE(min, RTC_MINUTES);
  372. CMOS_WRITE(sec, RTC_SECONDS);
  373. local_irq_restore(flags);
  374. /* Notice that at this point, the RTC is updated but
  375. * the kernel is still running with the old time.
  376. * You need to set that separately with settimeofday
  377. * or adjtimex.
  378. */
  379. return 0;
  380. }
  381. case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
  382. {
  383. int tcs_val;
  384. if (!capable(CAP_SYS_TIME))
  385. return -EPERM;
  386. if(copy_from_user(&tcs_val, (int*)arg, sizeof(int)))
  387. return -EFAULT;
  388. tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F);
  389. ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
  390. return 0;
  391. }
  392. case RTC_VLOW_RD:
  393. {
  394. /* TODO:
  395. * Implement voltage low detection support
  396. */
  397. printk(KERN_WARNING "DS1302: RTC Voltage Low detection"
  398. " is not supported\n");
  399. return 0;
  400. }
  401. case RTC_VLOW_SET:
  402. {
  403. /* TODO:
  404. * Nothing to do since Voltage Low detection is not supported
  405. */
  406. return 0;
  407. }
  408. default:
  409. return -ENOIOCTLCMD;
  410. }
  411. }
  412. static void
  413. print_rtc_status(void)
  414. {
  415. struct rtc_time tm;
  416. get_rtc_time(&tm);
  417. /*
  418. * There is no way to tell if the luser has the RTC set for local
  419. * time or for Universal Standard Time (GMT). Probably local though.
  420. */
  421. printk(KERN_INFO "rtc_time\t: %02d:%02d:%02d\n",
  422. tm.tm_hour, tm.tm_min, tm.tm_sec);
  423. printk(KERN_INFO "rtc_date\t: %04d-%02d-%02d\n",
  424. tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
  425. }
  426. /* The various file operations we support. */
  427. static struct file_operations rtc_fops = {
  428. .owner = THIS_MODULE,
  429. .ioctl = rtc_ioctl,
  430. };
  431. /* Probe for the chip by writing something to its RAM and try reading it back. */
  432. #define MAGIC_PATTERN 0x42
  433. static int __init
  434. ds1302_probe(void)
  435. {
  436. int retval, res;
  437. TK_RST_DIR(1);
  438. TK_SCL_DIR(1);
  439. TK_SDA_DIR(0);
  440. /* Try to talk to timekeeper. */
  441. ds1302_wenable();
  442. start();
  443. out_byte(0xc0); /* write RAM byte 0 */
  444. out_byte(MAGIC_PATTERN); /* write something magic */
  445. start();
  446. out_byte(0xc1); /* read RAM byte 0 */
  447. if((res = in_byte()) == MAGIC_PATTERN) {
  448. stop();
  449. ds1302_wdisable();
  450. printk(KERN_INFO "%s: RTC found.\n", ds1302_name);
  451. printk(KERN_INFO "%s: SDA, SCL, RST on PB%i, PB%i, %s%i\n",
  452. ds1302_name,
  453. CONFIG_ETRAX_DS1302_SDABIT,
  454. CONFIG_ETRAX_DS1302_SCLBIT,
  455. #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
  456. "GENIO",
  457. #else
  458. "PB",
  459. #endif
  460. CONFIG_ETRAX_DS1302_RSTBIT);
  461. print_rtc_status();
  462. retval = 1;
  463. } else {
  464. stop();
  465. retval = 0;
  466. }
  467. return retval;
  468. }
  469. /* Just probe for the RTC and register the device to handle the ioctl needed. */
  470. int __init
  471. ds1302_init(void)
  472. {
  473. #ifdef CONFIG_ETRAX_I2C
  474. i2c_init();
  475. #endif
  476. if (!ds1302_probe()) {
  477. #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
  478. #if CONFIG_ETRAX_DS1302_RSTBIT == 27
  479. /*
  480. * The only way to set g27 to output is to enable ATA.
  481. *
  482. * Make sure that R_GEN_CONFIG is setup correct.
  483. */
  484. /* Allocating the ATA interface will grab almost all
  485. * pins in I/O groups a, b, c and d. A consequence of
  486. * allocating the ATA interface is that the fixed
  487. * interfaces shared RAM, parallel port 0, parallel
  488. * port 1, parallel port W, SCSI-8 port 0, SCSI-8 port
  489. * 1, SCSI-W, serial port 2, serial port 3,
  490. * synchronous serial port 3 and USB port 2 and almost
  491. * all GPIO pins on port g cannot be used.
  492. */
  493. if (cris_request_io_interface(if_ata, "ds1302/ATA")) {
  494. printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
  495. return -1;
  496. }
  497. #elif CONFIG_ETRAX_DS1302_RSTBIT == 0
  498. if (cris_io_interface_allocate_pins(if_gpio_grp_a,
  499. 'g',
  500. CONFIG_ETRAX_DS1302_RSTBIT,
  501. CONFIG_ETRAX_DS1302_RSTBIT)) {
  502. printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
  503. return -1;
  504. }
  505. /* Set the direction of this bit to out. */
  506. genconfig_shadow = ((genconfig_shadow &
  507. ~IO_MASK(R_GEN_CONFIG, g0dir)) |
  508. (IO_STATE(R_GEN_CONFIG, g0dir, out)));
  509. *R_GEN_CONFIG = genconfig_shadow;
  510. #endif
  511. if (!ds1302_probe()) {
  512. printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
  513. return -1;
  514. }
  515. #else
  516. printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
  517. return -1;
  518. #endif
  519. }
  520. /* Initialise trickle charger */
  521. ds1302_writereg(RTC_TRICKLECHARGER,
  522. RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F));
  523. /* Start clock by resetting CLOCK_HALT */
  524. ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F));
  525. return 0;
  526. }
  527. static int __init ds1302_register(void)
  528. {
  529. ds1302_init();
  530. if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) {
  531. printk(KERN_INFO "%s: unable to get major %d for rtc\n",
  532. ds1302_name, RTC_MAJOR_NR);
  533. return -1;
  534. }
  535. return 0;
  536. }
  537. module_init(ds1302_register);