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); |