diff options
Diffstat (limited to 'drivers/rtc/rtc-ds1302.c')
| -rw-r--r-- | drivers/rtc/rtc-ds1302.c | 85 |
1 files changed, 67 insertions, 18 deletions
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 532acf9b05d8..359d1e04626c 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
| 17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
| 18 | #include <linux/bcd.h> | 18 | #include <linux/bcd.h> |
| 19 | #include <asm/rtc.h> | ||
| 20 | 19 | ||
| 21 | #define DRV_NAME "rtc-ds1302" | 20 | #define DRV_NAME "rtc-ds1302" |
| 22 | #define DRV_VERSION "0.1.1" | 21 | #define DRV_VERSION "0.1.1" |
| @@ -34,14 +33,55 @@ | |||
| 34 | #define RTC_ADDR_MIN 0x01 /* Address of minute register */ | 33 | #define RTC_ADDR_MIN 0x01 /* Address of minute register */ |
| 35 | #define RTC_ADDR_SEC 0x00 /* Address of second register */ | 34 | #define RTC_ADDR_SEC 0x00 /* Address of second register */ |
| 36 | 35 | ||
| 36 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
| 37 | #include <asm/rtc.h> | ||
| 38 | #include <mach/snapgear.h> | ||
| 39 | |||
| 37 | #define RTC_RESET 0x1000 | 40 | #define RTC_RESET 0x1000 |
| 38 | #define RTC_IODATA 0x0800 | 41 | #define RTC_IODATA 0x0800 |
| 39 | #define RTC_SCLK 0x0400 | 42 | #define RTC_SCLK 0x0400 |
| 40 | 43 | ||
| 41 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
| 42 | #include <mach/snapgear.h> | ||
| 43 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) | 44 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) |
| 44 | #define get_dp() SECUREEDGE_READ_IOPORT() | 45 | #define get_dp() SECUREEDGE_READ_IOPORT() |
| 46 | #define ds1302_set_tx() | ||
| 47 | #define ds1302_set_rx() | ||
| 48 | |||
| 49 | static inline int ds1302_hw_init(void) | ||
| 50 | { | ||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | static inline void ds1302_reset(void) | ||
| 55 | { | ||
| 56 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | ||
| 57 | } | ||
| 58 | |||
| 59 | static inline void ds1302_clock(void) | ||
| 60 | { | ||
| 61 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
| 62 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline void ds1302_start(void) | ||
| 66 | { | ||
| 67 | set_dp(get_dp() | RTC_RESET); | ||
| 68 | } | ||
| 69 | |||
| 70 | static inline void ds1302_stop(void) | ||
| 71 | { | ||
| 72 | set_dp(get_dp() & ~RTC_RESET); | ||
| 73 | } | ||
| 74 | |||
| 75 | static inline void ds1302_txbit(int bit) | ||
| 76 | { | ||
| 77 | set_dp((get_dp() & ~RTC_IODATA) | (bit ? RTC_IODATA : 0)); | ||
| 78 | } | ||
| 79 | |||
| 80 | static inline int ds1302_rxbit(void) | ||
| 81 | { | ||
| 82 | return !!(get_dp() & RTC_IODATA); | ||
| 83 | } | ||
| 84 | |||
| 45 | #else | 85 | #else |
| 46 | #error "Add support for your platform" | 86 | #error "Add support for your platform" |
| 47 | #endif | 87 | #endif |
| @@ -50,11 +90,11 @@ static void ds1302_sendbits(unsigned int val) | |||
| 50 | { | 90 | { |
| 51 | int i; | 91 | int i; |
| 52 | 92 | ||
| 93 | ds1302_set_tx(); | ||
| 94 | |||
| 53 | for (i = 8; (i); i--, val >>= 1) { | 95 | for (i = 8; (i); i--, val >>= 1) { |
| 54 | set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? | 96 | ds1302_txbit(val & 0x1); |
| 55 | RTC_IODATA : 0)); | 97 | ds1302_clock(); |
| 56 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
| 57 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
| 58 | } | 98 | } |
| 59 | } | 99 | } |
| 60 | 100 | ||
| @@ -63,10 +103,11 @@ static unsigned int ds1302_recvbits(void) | |||
| 63 | unsigned int val; | 103 | unsigned int val; |
| 64 | int i; | 104 | int i; |
| 65 | 105 | ||
| 106 | ds1302_set_rx(); | ||
| 107 | |||
| 66 | for (i = 0, val = 0; (i < 8); i++) { | 108 | for (i = 0, val = 0; (i < 8); i++) { |
| 67 | val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i); | 109 | val |= (ds1302_rxbit() << i); |
| 68 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | 110 | ds1302_clock(); |
| 69 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
| 70 | } | 111 | } |
| 71 | 112 | ||
| 72 | return val; | 113 | return val; |
| @@ -76,23 +117,24 @@ static unsigned int ds1302_readbyte(unsigned int addr) | |||
| 76 | { | 117 | { |
| 77 | unsigned int val; | 118 | unsigned int val; |
| 78 | 119 | ||
| 79 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 120 | ds1302_reset(); |
| 80 | 121 | ||
| 81 | set_dp(get_dp() | RTC_RESET); | 122 | ds1302_start(); |
| 82 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); | 123 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); |
| 83 | val = ds1302_recvbits(); | 124 | val = ds1302_recvbits(); |
| 84 | set_dp(get_dp() & ~RTC_RESET); | 125 | ds1302_stop(); |
| 85 | 126 | ||
| 86 | return val; | 127 | return val; |
| 87 | } | 128 | } |
| 88 | 129 | ||
| 89 | static void ds1302_writebyte(unsigned int addr, unsigned int val) | 130 | static void ds1302_writebyte(unsigned int addr, unsigned int val) |
| 90 | { | 131 | { |
| 91 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 132 | ds1302_reset(); |
| 92 | set_dp(get_dp() | RTC_RESET); | 133 | |
| 134 | ds1302_start(); | ||
| 93 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); | 135 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); |
| 94 | ds1302_sendbits(val); | 136 | ds1302_sendbits(val); |
| 95 | set_dp(get_dp() & ~RTC_RESET); | 137 | ds1302_stop(); |
| 96 | } | 138 | } |
| 97 | 139 | ||
| 98 | static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) | 140 | static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) |
| @@ -167,13 +209,20 @@ static int __init ds1302_rtc_probe(struct platform_device *pdev) | |||
| 167 | { | 209 | { |
| 168 | struct rtc_device *rtc; | 210 | struct rtc_device *rtc; |
| 169 | 211 | ||
| 212 | if (ds1302_hw_init()) { | ||
| 213 | dev_err(&pdev->dev, "Failed to init communication channel"); | ||
| 214 | return -EINVAL; | ||
| 215 | } | ||
| 216 | |||
| 170 | /* Reset */ | 217 | /* Reset */ |
| 171 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 218 | ds1302_reset(); |
| 172 | 219 | ||
| 173 | /* Write a magic value to the DS1302 RAM, and see if it sticks. */ | 220 | /* Write a magic value to the DS1302 RAM, and see if it sticks. */ |
| 174 | ds1302_writebyte(RTC_ADDR_RAM0, 0x42); | 221 | ds1302_writebyte(RTC_ADDR_RAM0, 0x42); |
| 175 | if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) | 222 | if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) { |
| 223 | dev_err(&pdev->dev, "Failed to probe"); | ||
| 176 | return -ENODEV; | 224 | return -ENODEV; |
| 225 | } | ||
| 177 | 226 | ||
| 178 | rtc = rtc_device_register("ds1302", &pdev->dev, | 227 | rtc = rtc_device_register("ds1302", &pdev->dev, |
| 179 | &ds1302_rtc_ops, THIS_MODULE); | 228 | &ds1302_rtc_ops, THIS_MODULE); |
