ds1216.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include <linux/bcd.h>
  2. #include <linux/time.h>
  3. #include <asm/ds1216.h>
  4. volatile unsigned char *ds1216_base;
  5. /*
  6. * Read the 64 bit we'd like to have - It a series
  7. * of 64 bits showing up in the LSB of the base register.
  8. *
  9. */
  10. static unsigned char *ds1216_read(void)
  11. {
  12. static unsigned char rdbuf[8];
  13. unsigned char c;
  14. int i, j;
  15. for (i = 0; i < 8; i++) {
  16. c = 0x0;
  17. for (j = 0; j < 8; j++) {
  18. c |= (*ds1216_base & 0x1) << j;
  19. }
  20. rdbuf[i] = c;
  21. }
  22. return rdbuf;
  23. }
  24. static void ds1216_switch_ds_to_clock(void)
  25. {
  26. unsigned char magic[] = {
  27. 0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c
  28. };
  29. int i,j,c;
  30. /* Reset magic pointer */
  31. c = *ds1216_base;
  32. /* Write 64 bit magic to DS1216 */
  33. for (i = 0; i < 8; i++) {
  34. c = magic[i];
  35. for (j = 0; j < 8; j++) {
  36. *ds1216_base = c;
  37. c = c >> 1;
  38. }
  39. }
  40. }
  41. unsigned long ds1216_get_cmos_time(void)
  42. {
  43. unsigned char *rdbuf;
  44. unsigned int year, month, date, hour, min, sec;
  45. ds1216_switch_ds_to_clock();
  46. rdbuf = ds1216_read();
  47. sec = BCD2BIN(DS1216_SEC(rdbuf));
  48. min = BCD2BIN(DS1216_MIN(rdbuf));
  49. hour = BCD2BIN(DS1216_HOUR(rdbuf));
  50. date = BCD2BIN(DS1216_DATE(rdbuf));
  51. month = BCD2BIN(DS1216_MONTH(rdbuf));
  52. year = BCD2BIN(DS1216_YEAR(rdbuf));
  53. if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf))
  54. hour+=12;
  55. if (year < 70)
  56. year += 2000;
  57. else
  58. year += 1900;
  59. return mktime(year, month, date, hour, min, sec);
  60. }
  61. int ds1216_set_rtc_mmss(unsigned long nowtime)
  62. {
  63. printk("ds1216_set_rtc_mmss called but not implemented\n");
  64. return -1;
  65. }