diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/rtc | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/alarm-dev.c | 286 | ||||
-rw-r--r-- | drivers/rtc/alarm.c | 590 | ||||
-rw-r--r-- | drivers/rtc/rtc-max77663.c | 617 | ||||
-rw-r--r-- | drivers/rtc/rtc-max8907c.c | 323 | ||||
-rw-r--r-- | drivers/rtc/rtc-ricoh583.c | 403 | ||||
-rw-r--r-- | drivers/rtc/rtc-tps6591x.c | 546 | ||||
-rw-r--r-- | drivers/rtc/rtc-tps80031.c | 449 |
7 files changed, 3214 insertions, 0 deletions
diff --git a/drivers/rtc/alarm-dev.c b/drivers/rtc/alarm-dev.c new file mode 100644 index 00000000000..686e6f7ed48 --- /dev/null +++ b/drivers/rtc/alarm-dev.c | |||
@@ -0,0 +1,286 @@ | |||
1 | /* drivers/rtc/alarm-dev.c | ||
2 | * | ||
3 | * Copyright (C) 2007-2009 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <asm/mach/time.h> | ||
17 | #include <linux/android_alarm.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/miscdevice.h> | ||
20 | #include <linux/fs.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <linux/sysdev.h> | ||
25 | #include <linux/uaccess.h> | ||
26 | #include <linux/wakelock.h> | ||
27 | |||
28 | #define ANDROID_ALARM_PRINT_INFO (1U << 0) | ||
29 | #define ANDROID_ALARM_PRINT_IO (1U << 1) | ||
30 | #define ANDROID_ALARM_PRINT_INT (1U << 2) | ||
31 | |||
32 | static int debug_mask = ANDROID_ALARM_PRINT_INFO; | ||
33 | module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); | ||
34 | |||
35 | #define pr_alarm(debug_level_mask, args...) \ | ||
36 | do { \ | ||
37 | if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ | ||
38 | pr_info(args); \ | ||
39 | } \ | ||
40 | } while (0) | ||
41 | |||
42 | #define ANDROID_ALARM_WAKEUP_MASK ( \ | ||
43 | ANDROID_ALARM_RTC_WAKEUP_MASK | \ | ||
44 | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) | ||
45 | |||
46 | /* support old usespace code */ | ||
47 | #define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ | ||
48 | #define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) | ||
49 | |||
50 | static int alarm_opened; | ||
51 | static DEFINE_SPINLOCK(alarm_slock); | ||
52 | static struct wake_lock alarm_wake_lock; | ||
53 | static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue); | ||
54 | static uint32_t alarm_pending; | ||
55 | static uint32_t alarm_enabled; | ||
56 | static uint32_t wait_pending; | ||
57 | |||
58 | static struct alarm alarms[ANDROID_ALARM_TYPE_COUNT]; | ||
59 | |||
60 | static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
61 | { | ||
62 | int rv = 0; | ||
63 | unsigned long flags; | ||
64 | struct timespec new_alarm_time; | ||
65 | struct timespec new_rtc_time; | ||
66 | struct timespec tmp_time; | ||
67 | enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd); | ||
68 | uint32_t alarm_type_mask = 1U << alarm_type; | ||
69 | |||
70 | if (alarm_type >= ANDROID_ALARM_TYPE_COUNT) | ||
71 | return -EINVAL; | ||
72 | |||
73 | if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) { | ||
74 | if ((file->f_flags & O_ACCMODE) == O_RDONLY) | ||
75 | return -EPERM; | ||
76 | if (file->private_data == NULL && | ||
77 | cmd != ANDROID_ALARM_SET_RTC) { | ||
78 | spin_lock_irqsave(&alarm_slock, flags); | ||
79 | if (alarm_opened) { | ||
80 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
81 | return -EBUSY; | ||
82 | } | ||
83 | alarm_opened = 1; | ||
84 | file->private_data = (void *)1; | ||
85 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | switch (ANDROID_ALARM_BASE_CMD(cmd)) { | ||
90 | case ANDROID_ALARM_CLEAR(0): | ||
91 | spin_lock_irqsave(&alarm_slock, flags); | ||
92 | pr_alarm(IO, "alarm %d clear\n", alarm_type); | ||
93 | alarm_try_to_cancel(&alarms[alarm_type]); | ||
94 | if (alarm_pending) { | ||
95 | alarm_pending &= ~alarm_type_mask; | ||
96 | if (!alarm_pending && !wait_pending) | ||
97 | wake_unlock(&alarm_wake_lock); | ||
98 | } | ||
99 | alarm_enabled &= ~alarm_type_mask; | ||
100 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
101 | break; | ||
102 | |||
103 | case ANDROID_ALARM_SET_OLD: | ||
104 | case ANDROID_ALARM_SET_AND_WAIT_OLD: | ||
105 | if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) { | ||
106 | rv = -EFAULT; | ||
107 | goto err1; | ||
108 | } | ||
109 | new_alarm_time.tv_nsec = 0; | ||
110 | goto from_old_alarm_set; | ||
111 | |||
112 | case ANDROID_ALARM_SET_AND_WAIT(0): | ||
113 | case ANDROID_ALARM_SET(0): | ||
114 | if (copy_from_user(&new_alarm_time, (void __user *)arg, | ||
115 | sizeof(new_alarm_time))) { | ||
116 | rv = -EFAULT; | ||
117 | goto err1; | ||
118 | } | ||
119 | from_old_alarm_set: | ||
120 | spin_lock_irqsave(&alarm_slock, flags); | ||
121 | pr_alarm(IO, "alarm %d set %ld.%09ld\n", alarm_type, | ||
122 | new_alarm_time.tv_sec, new_alarm_time.tv_nsec); | ||
123 | alarm_enabled |= alarm_type_mask; | ||
124 | alarm_start_range(&alarms[alarm_type], | ||
125 | timespec_to_ktime(new_alarm_time), | ||
126 | timespec_to_ktime(new_alarm_time)); | ||
127 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
128 | if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0) | ||
129 | && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD) | ||
130 | break; | ||
131 | /* fall though */ | ||
132 | case ANDROID_ALARM_WAIT: | ||
133 | spin_lock_irqsave(&alarm_slock, flags); | ||
134 | pr_alarm(IO, "alarm wait\n"); | ||
135 | if (!alarm_pending && wait_pending) { | ||
136 | wake_unlock(&alarm_wake_lock); | ||
137 | wait_pending = 0; | ||
138 | } | ||
139 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
140 | rv = wait_event_interruptible(alarm_wait_queue, alarm_pending); | ||
141 | if (rv) | ||
142 | goto err1; | ||
143 | spin_lock_irqsave(&alarm_slock, flags); | ||
144 | rv = alarm_pending; | ||
145 | wait_pending = 1; | ||
146 | alarm_pending = 0; | ||
147 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
148 | break; | ||
149 | case ANDROID_ALARM_SET_RTC: | ||
150 | if (copy_from_user(&new_rtc_time, (void __user *)arg, | ||
151 | sizeof(new_rtc_time))) { | ||
152 | rv = -EFAULT; | ||
153 | goto err1; | ||
154 | } | ||
155 | rv = alarm_set_rtc(new_rtc_time); | ||
156 | spin_lock_irqsave(&alarm_slock, flags); | ||
157 | alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK; | ||
158 | wake_up(&alarm_wait_queue); | ||
159 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
160 | if (rv < 0) | ||
161 | goto err1; | ||
162 | break; | ||
163 | case ANDROID_ALARM_GET_TIME(0): | ||
164 | switch (alarm_type) { | ||
165 | case ANDROID_ALARM_RTC_WAKEUP: | ||
166 | case ANDROID_ALARM_RTC: | ||
167 | getnstimeofday(&tmp_time); | ||
168 | break; | ||
169 | case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP: | ||
170 | case ANDROID_ALARM_ELAPSED_REALTIME: | ||
171 | tmp_time = | ||
172 | ktime_to_timespec(alarm_get_elapsed_realtime()); | ||
173 | break; | ||
174 | case ANDROID_ALARM_TYPE_COUNT: | ||
175 | case ANDROID_ALARM_SYSTEMTIME: | ||
176 | ktime_get_ts(&tmp_time); | ||
177 | break; | ||
178 | } | ||
179 | if (copy_to_user((void __user *)arg, &tmp_time, | ||
180 | sizeof(tmp_time))) { | ||
181 | rv = -EFAULT; | ||
182 | goto err1; | ||
183 | } | ||
184 | break; | ||
185 | |||
186 | default: | ||
187 | rv = -EINVAL; | ||
188 | goto err1; | ||
189 | } | ||
190 | err1: | ||
191 | return rv; | ||
192 | } | ||
193 | |||
194 | static int alarm_open(struct inode *inode, struct file *file) | ||
195 | { | ||
196 | file->private_data = NULL; | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static int alarm_release(struct inode *inode, struct file *file) | ||
201 | { | ||
202 | int i; | ||
203 | unsigned long flags; | ||
204 | |||
205 | spin_lock_irqsave(&alarm_slock, flags); | ||
206 | if (file->private_data != 0) { | ||
207 | for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) { | ||
208 | uint32_t alarm_type_mask = 1U << i; | ||
209 | if (alarm_enabled & alarm_type_mask) { | ||
210 | pr_alarm(INFO, "alarm_release: clear alarm, " | ||
211 | "pending %d\n", | ||
212 | !!(alarm_pending & alarm_type_mask)); | ||
213 | alarm_enabled &= ~alarm_type_mask; | ||
214 | } | ||
215 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
216 | alarm_cancel(&alarms[i]); | ||
217 | spin_lock_irqsave(&alarm_slock, flags); | ||
218 | } | ||
219 | if (alarm_pending | wait_pending) { | ||
220 | if (alarm_pending) | ||
221 | pr_alarm(INFO, "alarm_release: clear " | ||
222 | "pending alarms %x\n", alarm_pending); | ||
223 | wake_unlock(&alarm_wake_lock); | ||
224 | wait_pending = 0; | ||
225 | alarm_pending = 0; | ||
226 | } | ||
227 | alarm_opened = 0; | ||
228 | } | ||
229 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static void alarm_triggered(struct alarm *alarm) | ||
234 | { | ||
235 | unsigned long flags; | ||
236 | uint32_t alarm_type_mask = 1U << alarm->type; | ||
237 | |||
238 | pr_alarm(INT, "alarm_triggered type %d\n", alarm->type); | ||
239 | spin_lock_irqsave(&alarm_slock, flags); | ||
240 | if (alarm_enabled & alarm_type_mask) { | ||
241 | wake_lock_timeout(&alarm_wake_lock, 5 * HZ); | ||
242 | alarm_enabled &= ~alarm_type_mask; | ||
243 | alarm_pending |= alarm_type_mask; | ||
244 | wake_up(&alarm_wait_queue); | ||
245 | } | ||
246 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
247 | } | ||
248 | |||
249 | static const struct file_operations alarm_fops = { | ||
250 | .owner = THIS_MODULE, | ||
251 | .unlocked_ioctl = alarm_ioctl, | ||
252 | .open = alarm_open, | ||
253 | .release = alarm_release, | ||
254 | }; | ||
255 | |||
256 | static struct miscdevice alarm_device = { | ||
257 | .minor = MISC_DYNAMIC_MINOR, | ||
258 | .name = "alarm", | ||
259 | .fops = &alarm_fops, | ||
260 | }; | ||
261 | |||
262 | static int __init alarm_dev_init(void) | ||
263 | { | ||
264 | int err; | ||
265 | int i; | ||
266 | |||
267 | err = misc_register(&alarm_device); | ||
268 | if (err) | ||
269 | return err; | ||
270 | |||
271 | for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) | ||
272 | alarm_init(&alarms[i], i, alarm_triggered); | ||
273 | wake_lock_init(&alarm_wake_lock, WAKE_LOCK_SUSPEND, "alarm"); | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static void __exit alarm_dev_exit(void) | ||
279 | { | ||
280 | misc_deregister(&alarm_device); | ||
281 | wake_lock_destroy(&alarm_wake_lock); | ||
282 | } | ||
283 | |||
284 | module_init(alarm_dev_init); | ||
285 | module_exit(alarm_dev_exit); | ||
286 | |||
diff --git a/drivers/rtc/alarm.c b/drivers/rtc/alarm.c new file mode 100644 index 00000000000..28b0df836a3 --- /dev/null +++ b/drivers/rtc/alarm.c | |||
@@ -0,0 +1,590 @@ | |||
1 | /* drivers/rtc/alarm.c | ||
2 | * | ||
3 | * Copyright (C) 2007-2009 Google, Inc. | ||
4 | * | ||
5 | * This software is licensed under the terms of the GNU General Public | ||
6 | * License version 2, as published by the Free Software Foundation, and | ||
7 | * may be copied, distributed, and modified under those terms. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <asm/mach/time.h> | ||
17 | #include <linux/android_alarm.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/miscdevice.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/rtc.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <linux/sysdev.h> | ||
25 | #include <linux/wakelock.h> | ||
26 | |||
27 | #define ANDROID_ALARM_PRINT_ERROR (1U << 0) | ||
28 | #define ANDROID_ALARM_PRINT_INIT_STATUS (1U << 1) | ||
29 | #define ANDROID_ALARM_PRINT_TSET (1U << 2) | ||
30 | #define ANDROID_ALARM_PRINT_CALL (1U << 3) | ||
31 | #define ANDROID_ALARM_PRINT_SUSPEND (1U << 4) | ||
32 | #define ANDROID_ALARM_PRINT_INT (1U << 5) | ||
33 | #define ANDROID_ALARM_PRINT_FLOW (1U << 6) | ||
34 | |||
35 | static int debug_mask = ANDROID_ALARM_PRINT_ERROR | \ | ||
36 | ANDROID_ALARM_PRINT_INIT_STATUS; | ||
37 | module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); | ||
38 | |||
39 | #define pr_alarm(debug_level_mask, args...) \ | ||
40 | do { \ | ||
41 | if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) { \ | ||
42 | pr_info(args); \ | ||
43 | } \ | ||
44 | } while (0) | ||
45 | |||
46 | #define ANDROID_ALARM_WAKEUP_MASK ( \ | ||
47 | ANDROID_ALARM_RTC_WAKEUP_MASK | \ | ||
48 | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK) | ||
49 | |||
50 | /* support old usespace code */ | ||
51 | #define ANDROID_ALARM_SET_OLD _IOW('a', 2, time_t) /* set alarm */ | ||
52 | #define ANDROID_ALARM_SET_AND_WAIT_OLD _IOW('a', 3, time_t) | ||
53 | |||
54 | struct alarm_queue { | ||
55 | struct rb_root alarms; | ||
56 | struct rb_node *first; | ||
57 | struct hrtimer timer; | ||
58 | ktime_t delta; | ||
59 | bool stopped; | ||
60 | ktime_t stopped_time; | ||
61 | }; | ||
62 | |||
63 | static struct rtc_device *alarm_rtc_dev; | ||
64 | static DEFINE_SPINLOCK(alarm_slock); | ||
65 | static DEFINE_MUTEX(alarm_setrtc_mutex); | ||
66 | static struct wake_lock alarm_rtc_wake_lock; | ||
67 | static struct platform_device *alarm_platform_dev; | ||
68 | struct alarm_queue alarms[ANDROID_ALARM_TYPE_COUNT]; | ||
69 | static bool suspended; | ||
70 | |||
71 | static void update_timer_locked(struct alarm_queue *base, bool head_removed) | ||
72 | { | ||
73 | struct alarm *alarm; | ||
74 | bool is_wakeup = base == &alarms[ANDROID_ALARM_RTC_WAKEUP] || | ||
75 | base == &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; | ||
76 | |||
77 | if (base->stopped) { | ||
78 | pr_alarm(FLOW, "changed alarm while setting the wall time\n"); | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | if (is_wakeup && !suspended && head_removed) | ||
83 | wake_unlock(&alarm_rtc_wake_lock); | ||
84 | |||
85 | if (!base->first) | ||
86 | return; | ||
87 | |||
88 | alarm = container_of(base->first, struct alarm, node); | ||
89 | |||
90 | pr_alarm(FLOW, "selected alarm, type %d, func %pF at %lld\n", | ||
91 | alarm->type, alarm->function, ktime_to_ns(alarm->expires)); | ||
92 | |||
93 | if (is_wakeup && suspended) { | ||
94 | pr_alarm(FLOW, "changed alarm while suspened\n"); | ||
95 | wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); | ||
96 | return; | ||
97 | } | ||
98 | |||
99 | hrtimer_try_to_cancel(&base->timer); | ||
100 | base->timer.node.expires = ktime_add(base->delta, alarm->expires); | ||
101 | base->timer._softexpires = ktime_add(base->delta, alarm->softexpires); | ||
102 | hrtimer_start_expires(&base->timer, HRTIMER_MODE_ABS); | ||
103 | } | ||
104 | |||
105 | static void alarm_enqueue_locked(struct alarm *alarm) | ||
106 | { | ||
107 | struct alarm_queue *base = &alarms[alarm->type]; | ||
108 | struct rb_node **link = &base->alarms.rb_node; | ||
109 | struct rb_node *parent = NULL; | ||
110 | struct alarm *entry; | ||
111 | int leftmost = 1; | ||
112 | bool was_first = false; | ||
113 | |||
114 | pr_alarm(FLOW, "added alarm, type %d, func %pF at %lld\n", | ||
115 | alarm->type, alarm->function, ktime_to_ns(alarm->expires)); | ||
116 | |||
117 | if (base->first == &alarm->node) { | ||
118 | base->first = rb_next(&alarm->node); | ||
119 | was_first = true; | ||
120 | } | ||
121 | if (!RB_EMPTY_NODE(&alarm->node)) { | ||
122 | rb_erase(&alarm->node, &base->alarms); | ||
123 | RB_CLEAR_NODE(&alarm->node); | ||
124 | } | ||
125 | |||
126 | while (*link) { | ||
127 | parent = *link; | ||
128 | entry = rb_entry(parent, struct alarm, node); | ||
129 | /* | ||
130 | * We dont care about collisions. Nodes with | ||
131 | * the same expiry time stay together. | ||
132 | */ | ||
133 | if (alarm->expires.tv64 < entry->expires.tv64) { | ||
134 | link = &(*link)->rb_left; | ||
135 | } else { | ||
136 | link = &(*link)->rb_right; | ||
137 | leftmost = 0; | ||
138 | } | ||
139 | } | ||
140 | if (leftmost) | ||
141 | base->first = &alarm->node; | ||
142 | if (leftmost || was_first) | ||
143 | update_timer_locked(base, was_first); | ||
144 | |||
145 | rb_link_node(&alarm->node, parent, link); | ||
146 | rb_insert_color(&alarm->node, &base->alarms); | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * alarm_init - initialize an alarm | ||
151 | * @alarm: the alarm to be initialized | ||
152 | * @type: the alarm type to be used | ||
153 | * @function: alarm callback function | ||
154 | */ | ||
155 | void alarm_init(struct alarm *alarm, | ||
156 | enum android_alarm_type type, void (*function)(struct alarm *)) | ||
157 | { | ||
158 | RB_CLEAR_NODE(&alarm->node); | ||
159 | alarm->type = type; | ||
160 | alarm->function = function; | ||
161 | |||
162 | pr_alarm(FLOW, "created alarm, type %d, func %pF\n", type, function); | ||
163 | } | ||
164 | |||
165 | |||
166 | /** | ||
167 | * alarm_start_range - (re)start an alarm | ||
168 | * @alarm: the alarm to be added | ||
169 | * @start: earliest expiry time | ||
170 | * @end: expiry time | ||
171 | */ | ||
172 | void alarm_start_range(struct alarm *alarm, ktime_t start, ktime_t end) | ||
173 | { | ||
174 | unsigned long flags; | ||
175 | |||
176 | spin_lock_irqsave(&alarm_slock, flags); | ||
177 | alarm->softexpires = start; | ||
178 | alarm->expires = end; | ||
179 | alarm_enqueue_locked(alarm); | ||
180 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * alarm_try_to_cancel - try to deactivate an alarm | ||
185 | * @alarm: alarm to stop | ||
186 | * | ||
187 | * Returns: | ||
188 | * 0 when the alarm was not active | ||
189 | * 1 when the alarm was active | ||
190 | * -1 when the alarm may currently be excuting the callback function and | ||
191 | * cannot be stopped (it may also be inactive) | ||
192 | */ | ||
193 | int alarm_try_to_cancel(struct alarm *alarm) | ||
194 | { | ||
195 | struct alarm_queue *base = &alarms[alarm->type]; | ||
196 | unsigned long flags; | ||
197 | bool first = false; | ||
198 | int ret = 0; | ||
199 | |||
200 | spin_lock_irqsave(&alarm_slock, flags); | ||
201 | if (!RB_EMPTY_NODE(&alarm->node)) { | ||
202 | pr_alarm(FLOW, "canceled alarm, type %d, func %pF at %lld\n", | ||
203 | alarm->type, alarm->function, | ||
204 | ktime_to_ns(alarm->expires)); | ||
205 | ret = 1; | ||
206 | if (base->first == &alarm->node) { | ||
207 | base->first = rb_next(&alarm->node); | ||
208 | first = true; | ||
209 | } | ||
210 | rb_erase(&alarm->node, &base->alarms); | ||
211 | RB_CLEAR_NODE(&alarm->node); | ||
212 | if (first) | ||
213 | update_timer_locked(base, true); | ||
214 | } else | ||
215 | pr_alarm(FLOW, "tried to cancel alarm, type %d, func %pF\n", | ||
216 | alarm->type, alarm->function); | ||
217 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
218 | if (!ret && hrtimer_callback_running(&base->timer)) | ||
219 | ret = -1; | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * alarm_cancel - cancel an alarm and wait for the handler to finish. | ||
225 | * @alarm: the alarm to be cancelled | ||
226 | * | ||
227 | * Returns: | ||
228 | * 0 when the alarm was not active | ||
229 | * 1 when the alarm was active | ||
230 | */ | ||
231 | int alarm_cancel(struct alarm *alarm) | ||
232 | { | ||
233 | for (;;) { | ||
234 | int ret = alarm_try_to_cancel(alarm); | ||
235 | if (ret >= 0) | ||
236 | return ret; | ||
237 | cpu_relax(); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * alarm_set_rtc - set the kernel and rtc walltime | ||
243 | * @new_time: timespec value containing the new time | ||
244 | */ | ||
245 | int alarm_set_rtc(struct timespec new_time) | ||
246 | { | ||
247 | int i; | ||
248 | int ret; | ||
249 | unsigned long flags; | ||
250 | struct rtc_time rtc_new_rtc_time; | ||
251 | struct timespec tmp_time; | ||
252 | |||
253 | rtc_time_to_tm(new_time.tv_sec, &rtc_new_rtc_time); | ||
254 | |||
255 | pr_alarm(TSET, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n", | ||
256 | new_time.tv_sec, new_time.tv_nsec, | ||
257 | rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min, | ||
258 | rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1, | ||
259 | rtc_new_rtc_time.tm_mday, | ||
260 | rtc_new_rtc_time.tm_year + 1900); | ||
261 | |||
262 | mutex_lock(&alarm_setrtc_mutex); | ||
263 | spin_lock_irqsave(&alarm_slock, flags); | ||
264 | wake_lock(&alarm_rtc_wake_lock); | ||
265 | getnstimeofday(&tmp_time); | ||
266 | for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { | ||
267 | hrtimer_try_to_cancel(&alarms[i].timer); | ||
268 | alarms[i].stopped = true; | ||
269 | alarms[i].stopped_time = timespec_to_ktime(tmp_time); | ||
270 | } | ||
271 | alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = | ||
272 | alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = | ||
273 | ktime_sub(alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta, | ||
274 | timespec_to_ktime(timespec_sub(tmp_time, new_time))); | ||
275 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
276 | ret = do_settimeofday(&new_time); | ||
277 | spin_lock_irqsave(&alarm_slock, flags); | ||
278 | for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { | ||
279 | alarms[i].stopped = false; | ||
280 | update_timer_locked(&alarms[i], false); | ||
281 | } | ||
282 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
283 | if (ret < 0) { | ||
284 | pr_alarm(ERROR, "alarm_set_rtc: Failed to set time\n"); | ||
285 | goto err; | ||
286 | } | ||
287 | if (!alarm_rtc_dev) { | ||
288 | pr_alarm(ERROR, | ||
289 | "alarm_set_rtc: no RTC, time will be lost on reboot\n"); | ||
290 | goto err; | ||
291 | } | ||
292 | ret = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time); | ||
293 | if (ret < 0) | ||
294 | pr_alarm(ERROR, "alarm_set_rtc: " | ||
295 | "Failed to set RTC, time will be lost on reboot\n"); | ||
296 | err: | ||
297 | wake_unlock(&alarm_rtc_wake_lock); | ||
298 | mutex_unlock(&alarm_setrtc_mutex); | ||
299 | return ret; | ||
300 | } | ||
301 | |||
302 | /** | ||
303 | * alarm_get_elapsed_realtime - get the elapsed real time in ktime_t format | ||
304 | * | ||
305 | * returns the time in ktime_t format | ||
306 | */ | ||
307 | ktime_t alarm_get_elapsed_realtime(void) | ||
308 | { | ||
309 | ktime_t now; | ||
310 | unsigned long flags; | ||
311 | struct alarm_queue *base = &alarms[ANDROID_ALARM_ELAPSED_REALTIME]; | ||
312 | |||
313 | spin_lock_irqsave(&alarm_slock, flags); | ||
314 | now = base->stopped ? base->stopped_time : ktime_get_real(); | ||
315 | now = ktime_sub(now, base->delta); | ||
316 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
317 | return now; | ||
318 | } | ||
319 | |||
320 | static enum hrtimer_restart alarm_timer_triggered(struct hrtimer *timer) | ||
321 | { | ||
322 | struct alarm_queue *base; | ||
323 | struct alarm *alarm; | ||
324 | unsigned long flags; | ||
325 | ktime_t now; | ||
326 | |||
327 | spin_lock_irqsave(&alarm_slock, flags); | ||
328 | |||
329 | base = container_of(timer, struct alarm_queue, timer); | ||
330 | now = base->stopped ? base->stopped_time : hrtimer_cb_get_time(timer); | ||
331 | now = ktime_sub(now, base->delta); | ||
332 | |||
333 | pr_alarm(INT, "alarm_timer_triggered type %d at %lld\n", | ||
334 | base - alarms, ktime_to_ns(now)); | ||
335 | |||
336 | while (base->first) { | ||
337 | alarm = container_of(base->first, struct alarm, node); | ||
338 | if (alarm->softexpires.tv64 > now.tv64) { | ||
339 | pr_alarm(FLOW, "don't call alarm, %pF, %lld (s %lld)\n", | ||
340 | alarm->function, ktime_to_ns(alarm->expires), | ||
341 | ktime_to_ns(alarm->softexpires)); | ||
342 | break; | ||
343 | } | ||
344 | base->first = rb_next(&alarm->node); | ||
345 | rb_erase(&alarm->node, &base->alarms); | ||
346 | RB_CLEAR_NODE(&alarm->node); | ||
347 | pr_alarm(CALL, "call alarm, type %d, func %pF, %lld (s %lld)\n", | ||
348 | alarm->type, alarm->function, | ||
349 | ktime_to_ns(alarm->expires), | ||
350 | ktime_to_ns(alarm->softexpires)); | ||
351 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
352 | alarm->function(alarm); | ||
353 | spin_lock_irqsave(&alarm_slock, flags); | ||
354 | } | ||
355 | if (!base->first) | ||
356 | pr_alarm(FLOW, "no more alarms of type %d\n", base - alarms); | ||
357 | update_timer_locked(base, true); | ||
358 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
359 | return HRTIMER_NORESTART; | ||
360 | } | ||
361 | |||
362 | static void alarm_triggered_func(void *p) | ||
363 | { | ||
364 | struct rtc_device *rtc = alarm_rtc_dev; | ||
365 | if (!(rtc->irq_data & RTC_AF)) | ||
366 | return; | ||
367 | pr_alarm(INT, "rtc alarm triggered\n"); | ||
368 | wake_lock_timeout(&alarm_rtc_wake_lock, 1 * HZ); | ||
369 | } | ||
370 | |||
371 | static int alarm_suspend(struct platform_device *pdev, pm_message_t state) | ||
372 | { | ||
373 | int err = 0; | ||
374 | unsigned long flags; | ||
375 | struct rtc_wkalrm rtc_alarm; | ||
376 | struct rtc_time rtc_current_rtc_time; | ||
377 | unsigned long rtc_current_time; | ||
378 | unsigned long rtc_alarm_time; | ||
379 | struct timespec rtc_delta; | ||
380 | struct timespec wall_time; | ||
381 | struct alarm_queue *wakeup_queue = NULL; | ||
382 | struct alarm_queue *tmp_queue = NULL; | ||
383 | |||
384 | pr_alarm(SUSPEND, "alarm_suspend(%p, %d)\n", pdev, state.event); | ||
385 | |||
386 | spin_lock_irqsave(&alarm_slock, flags); | ||
387 | suspended = true; | ||
388 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
389 | |||
390 | hrtimer_cancel(&alarms[ANDROID_ALARM_RTC_WAKEUP].timer); | ||
391 | hrtimer_cancel(&alarms[ | ||
392 | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].timer); | ||
393 | |||
394 | tmp_queue = &alarms[ANDROID_ALARM_RTC_WAKEUP]; | ||
395 | if (tmp_queue->first) | ||
396 | wakeup_queue = tmp_queue; | ||
397 | tmp_queue = &alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP]; | ||
398 | if (tmp_queue->first && (!wakeup_queue || | ||
399 | hrtimer_get_expires(&tmp_queue->timer).tv64 < | ||
400 | hrtimer_get_expires(&wakeup_queue->timer).tv64)) | ||
401 | wakeup_queue = tmp_queue; | ||
402 | if (wakeup_queue) { | ||
403 | rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); | ||
404 | getnstimeofday(&wall_time); | ||
405 | rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); | ||
406 | set_normalized_timespec(&rtc_delta, | ||
407 | wall_time.tv_sec - rtc_current_time, | ||
408 | wall_time.tv_nsec); | ||
409 | |||
410 | rtc_alarm_time = timespec_sub(ktime_to_timespec( | ||
411 | hrtimer_get_expires(&wakeup_queue->timer)), | ||
412 | rtc_delta).tv_sec; | ||
413 | |||
414 | rtc_time_to_tm(rtc_alarm_time, &rtc_alarm.time); | ||
415 | rtc_alarm.enabled = 1; | ||
416 | rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); | ||
417 | rtc_read_time(alarm_rtc_dev, &rtc_current_rtc_time); | ||
418 | rtc_tm_to_time(&rtc_current_rtc_time, &rtc_current_time); | ||
419 | pr_alarm(SUSPEND, | ||
420 | "rtc alarm set at %ld, now %ld, rtc delta %ld.%09ld\n", | ||
421 | rtc_alarm_time, rtc_current_time, | ||
422 | rtc_delta.tv_sec, rtc_delta.tv_nsec); | ||
423 | if (rtc_current_time + 1 >= rtc_alarm_time) { | ||
424 | pr_alarm(SUSPEND, "alarm about to go off\n"); | ||
425 | memset(&rtc_alarm, 0, sizeof(rtc_alarm)); | ||
426 | rtc_alarm.enabled = 0; | ||
427 | rtc_set_alarm(alarm_rtc_dev, &rtc_alarm); | ||
428 | |||
429 | spin_lock_irqsave(&alarm_slock, flags); | ||
430 | suspended = false; | ||
431 | wake_lock_timeout(&alarm_rtc_wake_lock, 2 * HZ); | ||
432 | update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], | ||
433 | false); | ||
434 | update_timer_locked(&alarms[ | ||
435 | ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], false); | ||
436 | err = -EBUSY; | ||
437 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
438 | } | ||
439 | } | ||
440 | return err; | ||
441 | } | ||
442 | |||
443 | static int alarm_resume(struct platform_device *pdev) | ||
444 | { | ||
445 | struct rtc_wkalrm alarm; | ||
446 | unsigned long flags; | ||
447 | |||
448 | pr_alarm(SUSPEND, "alarm_resume(%p)\n", pdev); | ||
449 | |||
450 | memset(&alarm, 0, sizeof(alarm)); | ||
451 | alarm.enabled = 0; | ||
452 | rtc_set_alarm(alarm_rtc_dev, &alarm); | ||
453 | |||
454 | spin_lock_irqsave(&alarm_slock, flags); | ||
455 | suspended = false; | ||
456 | update_timer_locked(&alarms[ANDROID_ALARM_RTC_WAKEUP], false); | ||
457 | update_timer_locked(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP], | ||
458 | false); | ||
459 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static struct rtc_task alarm_rtc_task = { | ||
465 | .func = alarm_triggered_func | ||
466 | }; | ||
467 | |||
468 | static int rtc_alarm_add_device(struct device *dev, | ||
469 | struct class_interface *class_intf) | ||
470 | { | ||
471 | int err; | ||
472 | struct rtc_device *rtc = to_rtc_device(dev); | ||
473 | |||
474 | mutex_lock(&alarm_setrtc_mutex); | ||
475 | |||
476 | if (alarm_rtc_dev) { | ||
477 | err = -EBUSY; | ||
478 | goto err1; | ||
479 | } | ||
480 | |||
481 | alarm_platform_dev = | ||
482 | platform_device_register_simple("alarm", -1, NULL, 0); | ||
483 | if (IS_ERR(alarm_platform_dev)) { | ||
484 | err = PTR_ERR(alarm_platform_dev); | ||
485 | goto err2; | ||
486 | } | ||
487 | err = rtc_irq_register(rtc, &alarm_rtc_task); | ||
488 | if (err) | ||
489 | goto err3; | ||
490 | alarm_rtc_dev = rtc; | ||
491 | pr_alarm(INIT_STATUS, "using rtc device, %s, for alarms", rtc->name); | ||
492 | mutex_unlock(&alarm_setrtc_mutex); | ||
493 | |||
494 | return 0; | ||
495 | |||
496 | err3: | ||
497 | platform_device_unregister(alarm_platform_dev); | ||
498 | err2: | ||
499 | err1: | ||
500 | mutex_unlock(&alarm_setrtc_mutex); | ||
501 | return err; | ||
502 | } | ||
503 | |||
504 | static void rtc_alarm_remove_device(struct device *dev, | ||
505 | struct class_interface *class_intf) | ||
506 | { | ||
507 | if (dev == &alarm_rtc_dev->dev) { | ||
508 | pr_alarm(INIT_STATUS, "lost rtc device for alarms"); | ||
509 | rtc_irq_unregister(alarm_rtc_dev, &alarm_rtc_task); | ||
510 | platform_device_unregister(alarm_platform_dev); | ||
511 | alarm_rtc_dev = NULL; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | static struct class_interface rtc_alarm_interface = { | ||
516 | .add_dev = &rtc_alarm_add_device, | ||
517 | .remove_dev = &rtc_alarm_remove_device, | ||
518 | }; | ||
519 | |||
520 | static struct platform_driver alarm_driver = { | ||
521 | .suspend = alarm_suspend, | ||
522 | .resume = alarm_resume, | ||
523 | .driver = { | ||
524 | .name = "alarm" | ||
525 | } | ||
526 | }; | ||
527 | |||
528 | static int __init alarm_late_init(void) | ||
529 | { | ||
530 | unsigned long flags; | ||
531 | struct timespec tmp_time, system_time; | ||
532 | |||
533 | /* this needs to run after the rtc is read at boot */ | ||
534 | spin_lock_irqsave(&alarm_slock, flags); | ||
535 | /* We read the current rtc and system time so we can later calulate | ||
536 | * elasped realtime to be (boot_systemtime + rtc - boot_rtc) == | ||
537 | * (rtc - (boot_rtc - boot_systemtime)) | ||
538 | */ | ||
539 | getnstimeofday(&tmp_time); | ||
540 | ktime_get_ts(&system_time); | ||
541 | alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta = | ||
542 | alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta = | ||
543 | timespec_to_ktime(timespec_sub(tmp_time, system_time)); | ||
544 | |||
545 | spin_unlock_irqrestore(&alarm_slock, flags); | ||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | static int __init alarm_driver_init(void) | ||
550 | { | ||
551 | int err; | ||
552 | int i; | ||
553 | |||
554 | for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++) { | ||
555 | hrtimer_init(&alarms[i].timer, | ||
556 | CLOCK_REALTIME, HRTIMER_MODE_ABS); | ||
557 | alarms[i].timer.function = alarm_timer_triggered; | ||
558 | } | ||
559 | hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].timer, | ||
560 | CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | ||
561 | alarms[ANDROID_ALARM_SYSTEMTIME].timer.function = alarm_timer_triggered; | ||
562 | err = platform_driver_register(&alarm_driver); | ||
563 | if (err < 0) | ||
564 | goto err1; | ||
565 | wake_lock_init(&alarm_rtc_wake_lock, WAKE_LOCK_SUSPEND, "alarm_rtc"); | ||
566 | rtc_alarm_interface.class = rtc_class; | ||
567 | err = class_interface_register(&rtc_alarm_interface); | ||
568 | if (err < 0) | ||
569 | goto err2; | ||
570 | |||
571 | return 0; | ||
572 | |||
573 | err2: | ||
574 | wake_lock_destroy(&alarm_rtc_wake_lock); | ||
575 | platform_driver_unregister(&alarm_driver); | ||
576 | err1: | ||
577 | return err; | ||
578 | } | ||
579 | |||
580 | static void __exit alarm_exit(void) | ||
581 | { | ||
582 | class_interface_unregister(&rtc_alarm_interface); | ||
583 | wake_lock_destroy(&alarm_rtc_wake_lock); | ||
584 | platform_driver_unregister(&alarm_driver); | ||
585 | } | ||
586 | |||
587 | late_initcall(alarm_late_init); | ||
588 | module_init(alarm_driver_init); | ||
589 | module_exit(alarm_exit); | ||
590 | |||
diff --git a/drivers/rtc/rtc-max77663.c b/drivers/rtc/rtc-max77663.c new file mode 100644 index 00000000000..874a2df86dc --- /dev/null +++ b/drivers/rtc/rtc-max77663.c | |||
@@ -0,0 +1,617 @@ | |||
1 | /* | ||
2 | * drivers/rtc/rtc-max77663.c | ||
3 | * Max77663 RTC driver | ||
4 | * | ||
5 | * Copyright 2011 Maxim Integrated Products, Inc. | ||
6 | * Copyright (C) 2011 NVIDIA Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of the | ||
11 | * License, or (at your option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <linux/mfd/max77663-core.h> | ||
21 | |||
22 | /* RTC Registers */ | ||
23 | #define MAX77663_RTC_IRQ 0x00 | ||
24 | #define MAX77663_RTC_IRQ_MASK 0x01 | ||
25 | #define MAX77663_RTC_CTRL_MODE 0x02 | ||
26 | #define MAX77663_RTC_CTRL 0x03 | ||
27 | #define MAX77663_RTC_UPDATE0 0x04 | ||
28 | #define MAX77663_RTC_UPDATE1 0x05 | ||
29 | #define MAX77663_RTC_SEC 0x07 | ||
30 | #define MAX77663_RTC_MIN 0x08 | ||
31 | #define MAX77663_RTC_HOUR 0x09 | ||
32 | #define MAX77663_RTC_WEEKDAY 0x0A | ||
33 | #define MAX77663_RTC_MONTH 0x0B | ||
34 | #define MAX77663_RTC_YEAR 0x0C | ||
35 | #define MAX77663_RTC_MONTHDAY 0x0D | ||
36 | #define MAX77663_RTC_ALARM_SEC1 0x0E | ||
37 | #define MAX77663_RTC_ALARM_MIN1 0x0F | ||
38 | #define MAX77663_RTC_ALARM_HOUR1 0x10 | ||
39 | #define MAX77663_RTC_ALARM_WEEKDAY1 0x11 | ||
40 | #define MAX77663_RTC_ALARM_MONTH1 0x12 | ||
41 | #define MAX77663_RTC_ALARM_YEAR1 0x13 | ||
42 | #define MAX77663_RTC_ALARM_MONTHDAY1 0x14 | ||
43 | |||
44 | #define RTC_IRQ_60SEC_MASK (1 << 0) | ||
45 | #define RTC_IRQ_ALARM1_MASK (1 << 1) | ||
46 | #define RTC_IRQ_ALARM2_MASK (1 << 2) | ||
47 | #define RTC_IRQ_SMPL_MASK (1 << 3) | ||
48 | #define RTC_IRQ_1SEC_MASK (1 << 4) | ||
49 | #define RTC_IRQ_MASK 0x1F | ||
50 | |||
51 | #define BCD_MODE_MASK (1 << 0) | ||
52 | #define HR_MODE_MASK (1 << 1) | ||
53 | |||
54 | #define WB_UPDATE_MASK (1 << 0) | ||
55 | #define FLAG_AUTO_CLEAR_MASK (1 << 1) | ||
56 | #define FREEZE_SEC_MASK (1 << 2) | ||
57 | #define RTC_WAKE_MASK (1 << 3) | ||
58 | #define RB_UPDATE_MASK (1 << 4) | ||
59 | |||
60 | #define WB_UPDATE_FLAG_MASK (1 << 0) | ||
61 | #define RB_UPDATE_FLAG_MASK (1 << 1) | ||
62 | |||
63 | #define SEC_MASK 0x7F | ||
64 | #define MIN_MASK 0x7F | ||
65 | #define HOUR_MASK 0x3F | ||
66 | #define WEEKDAY_MASK 0x7F | ||
67 | #define MONTH_MASK 0x1F | ||
68 | #define YEAR_MASK 0xFF | ||
69 | #define MONTHDAY_MASK 0x3F | ||
70 | |||
71 | #define ALARM_EN_MASK 0x80 | ||
72 | #define ALARM_EN_SHIFT 7 | ||
73 | |||
74 | #define RTC_YEAR_BASE 100 | ||
75 | #define RTC_YEAR_MAX 99 | ||
76 | |||
77 | /* ON/OFF Registers */ | ||
78 | #define MAX77663_REG_ONOFF_CFG2 0x42 | ||
79 | |||
80 | #define ONOFF_WK_ALARM1_MASK (1 << 2) | ||
81 | |||
82 | enum { | ||
83 | RTC_SEC, | ||
84 | RTC_MIN, | ||
85 | RTC_HOUR, | ||
86 | RTC_WEEKDAY, | ||
87 | RTC_MONTH, | ||
88 | RTC_YEAR, | ||
89 | RTC_MONTHDAY, | ||
90 | RTC_NR | ||
91 | }; | ||
92 | |||
93 | struct max77663_rtc { | ||
94 | struct rtc_device *rtc; | ||
95 | struct device *dev; | ||
96 | |||
97 | struct mutex io_lock; | ||
98 | int irq; | ||
99 | u8 irq_mask; | ||
100 | }; | ||
101 | |||
102 | static inline struct device *_to_parent(struct max77663_rtc *rtc) | ||
103 | { | ||
104 | return rtc->dev->parent; | ||
105 | } | ||
106 | |||
107 | static inline int max77663_rtc_update_buffer(struct max77663_rtc *rtc, | ||
108 | int write) | ||
109 | { | ||
110 | struct device *parent = _to_parent(rtc); | ||
111 | u8 val = FLAG_AUTO_CLEAR_MASK | RTC_WAKE_MASK; | ||
112 | int ret; | ||
113 | |||
114 | if (write) | ||
115 | val |= WB_UPDATE_MASK; | ||
116 | else | ||
117 | val |= RB_UPDATE_MASK; | ||
118 | |||
119 | dev_dbg(rtc->dev, "rtc_update_buffer: write=%d, addr=0x%x, val=0x%x\n", | ||
120 | write, MAX77663_RTC_UPDATE0, val); | ||
121 | ret = max77663_write(parent, MAX77663_RTC_UPDATE0, &val, 1, 1); | ||
122 | if (ret < 0) { | ||
123 | dev_err(rtc->dev, "rtc_update_buffer: " | ||
124 | "Failed to get rtc update0\n"); | ||
125 | return ret; | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Must wait 14ms for buffer update. | ||
130 | * If the sleeping time is 10us - 20ms, usleep_range() is recommended. | ||
131 | * Please refer Documentation/timers/timers-howto.txt. | ||
132 | */ | ||
133 | usleep_range(14000, 14000); | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static inline int max77663_rtc_write(struct max77663_rtc *rtc, u8 addr, | ||
139 | void *values, u32 len, int update_buffer) | ||
140 | { | ||
141 | struct device *parent = _to_parent(rtc); | ||
142 | int ret; | ||
143 | |||
144 | mutex_lock(&rtc->io_lock); | ||
145 | |||
146 | dev_dbg(rtc->dev, "rtc_write: addr=0x%x, values=0x%x, len=%u, " | ||
147 | "update_buffer=%d\n", | ||
148 | addr, *((u8 *)values), len, update_buffer); | ||
149 | ret = max77663_write(parent, addr, values, len, 1); | ||
150 | if (ret < 0) | ||
151 | goto out; | ||
152 | |||
153 | if (update_buffer) | ||
154 | ret = max77663_rtc_update_buffer(rtc, 1); | ||
155 | |||
156 | out: | ||
157 | mutex_unlock(&rtc->io_lock); | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | static inline int max77663_rtc_read(struct max77663_rtc *rtc, u8 addr, | ||
162 | void *values, u32 len, int update_buffer) | ||
163 | { | ||
164 | struct device *parent = _to_parent(rtc); | ||
165 | int ret; | ||
166 | |||
167 | mutex_lock(&rtc->io_lock); | ||
168 | |||
169 | if (update_buffer) { | ||
170 | ret = max77663_rtc_update_buffer(rtc, 0); | ||
171 | if (ret < 0) | ||
172 | goto out; | ||
173 | } | ||
174 | |||
175 | ret = max77663_read(parent, addr, values, len, 1); | ||
176 | dev_dbg(rtc->dev, "rtc_read: addr=0x%x, values=0x%x, len=%u, " | ||
177 | "update_buffer=%d\n", | ||
178 | addr, *((u8 *)values), len, update_buffer); | ||
179 | |||
180 | out: | ||
181 | mutex_unlock(&rtc->io_lock); | ||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | static inline int max77663_rtc_reg_to_tm(struct max77663_rtc *rtc, u8 *buf, | ||
186 | struct rtc_time *tm) | ||
187 | { | ||
188 | int wday = buf[RTC_WEEKDAY] & WEEKDAY_MASK; | ||
189 | |||
190 | if (unlikely(!wday)) { | ||
191 | dev_err(rtc->dev, | ||
192 | "rtc_reg_to_tm: Invalid day of week, %d\n", wday); | ||
193 | return -EINVAL; | ||
194 | } | ||
195 | |||
196 | tm->tm_sec = (int)(buf[RTC_SEC] & SEC_MASK); | ||
197 | tm->tm_min = (int)(buf[RTC_MIN] & MIN_MASK); | ||
198 | tm->tm_hour = (int)(buf[RTC_HOUR] & HOUR_MASK); | ||
199 | tm->tm_mday = (int)(buf[RTC_MONTHDAY] & MONTHDAY_MASK); | ||
200 | tm->tm_mon = (int)(buf[RTC_MONTH] & MONTH_MASK) - 1; | ||
201 | tm->tm_year = (int)(buf[RTC_YEAR] & YEAR_MASK) + RTC_YEAR_BASE; | ||
202 | tm->tm_wday = ffs(wday) - 1; | ||
203 | |||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static inline int max77663_rtc_tm_to_reg(struct max77663_rtc *rtc, u8 *buf, | ||
208 | struct rtc_time *tm, int alarm) | ||
209 | { | ||
210 | u8 alarm_mask = alarm ? ALARM_EN_MASK : 0; | ||
211 | |||
212 | if (unlikely((tm->tm_year < RTC_YEAR_BASE) || | ||
213 | (tm->tm_year > RTC_YEAR_BASE + RTC_YEAR_MAX))) { | ||
214 | dev_err(rtc->dev, | ||
215 | "rtc_tm_to_reg: Invalid year, %d\n", tm->tm_year); | ||
216 | return -EINVAL; | ||
217 | } | ||
218 | |||
219 | buf[RTC_SEC] = tm->tm_sec | alarm_mask; | ||
220 | buf[RTC_MIN] = tm->tm_min | alarm_mask; | ||
221 | buf[RTC_HOUR] = tm->tm_hour | alarm_mask; | ||
222 | buf[RTC_MONTHDAY] = tm->tm_mday | alarm_mask; | ||
223 | buf[RTC_MONTH] = (tm->tm_mon + 1) | alarm_mask; | ||
224 | buf[RTC_YEAR] = (tm->tm_year - RTC_YEAR_BASE) | alarm_mask; | ||
225 | |||
226 | /* The wday is configured only when disabled alarm. */ | ||
227 | if (!alarm) | ||
228 | buf[RTC_WEEKDAY] = (1 << tm->tm_wday); | ||
229 | else | ||
230 | buf[RTC_WEEKDAY] = 0; | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static inline int max77663_rtc_irq_mask(struct max77663_rtc *rtc, u8 irq) | ||
236 | { | ||
237 | struct device *parent = _to_parent(rtc); | ||
238 | u8 irq_mask = rtc->irq_mask | irq; | ||
239 | int ret = 0; | ||
240 | |||
241 | ret = max77663_write(parent, MAX77663_RTC_IRQ_MASK, &irq_mask, 1, 1); | ||
242 | if (ret < 0) { | ||
243 | dev_err(rtc->dev, "rtc_irq_mask: Failed to set rtc irq mask\n"); | ||
244 | goto out; | ||
245 | } | ||
246 | rtc->irq_mask = irq_mask; | ||
247 | |||
248 | out: | ||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | static inline int max77663_rtc_irq_unmask(struct max77663_rtc *rtc, u8 irq) | ||
253 | { | ||
254 | struct device *parent = _to_parent(rtc); | ||
255 | u8 irq_mask = rtc->irq_mask & ~irq; | ||
256 | int ret = 0; | ||
257 | |||
258 | ret = max77663_write(parent, MAX77663_RTC_IRQ_MASK, &irq_mask, 1, 1); | ||
259 | if (ret < 0) { | ||
260 | dev_err(rtc->dev, | ||
261 | "rtc_irq_unmask: Failed to set rtc irq mask\n"); | ||
262 | goto out; | ||
263 | } | ||
264 | rtc->irq_mask = irq_mask; | ||
265 | |||
266 | out: | ||
267 | return ret; | ||
268 | } | ||
269 | |||
270 | static inline int max77663_rtc_do_irq(struct max77663_rtc *rtc) | ||
271 | { | ||
272 | struct device *parent = _to_parent(rtc); | ||
273 | u8 irq_status; | ||
274 | int ret; | ||
275 | |||
276 | ret = max77663_rtc_update_buffer(rtc, 0); | ||
277 | if (ret < 0) { | ||
278 | dev_err(rtc->dev, "rtc_irq: Failed to get rtc update buffer\n"); | ||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | ret = max77663_read(parent, MAX77663_RTC_IRQ, &irq_status, 1, 1); | ||
283 | if (ret < 0) { | ||
284 | dev_err(rtc->dev, "rtc_irq: Failed to get rtc irq status\n"); | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | dev_dbg(rtc->dev, "rtc_do_irq: irq_mask=0x%02x, irq_status=0x%02x\n", | ||
289 | rtc->irq_mask, irq_status); | ||
290 | |||
291 | if (!(rtc->irq_mask & RTC_IRQ_ALARM1_MASK) && | ||
292 | (irq_status & RTC_IRQ_ALARM1_MASK)) | ||
293 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
294 | |||
295 | if (!(rtc->irq_mask & RTC_IRQ_1SEC_MASK) && | ||
296 | (irq_status & RTC_IRQ_1SEC_MASK)) | ||
297 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_UF); | ||
298 | |||
299 | return ret; | ||
300 | } | ||
301 | |||
302 | static irqreturn_t max77663_rtc_irq(int irq, void *data) | ||
303 | { | ||
304 | struct max77663_rtc *rtc = (struct max77663_rtc *)data; | ||
305 | |||
306 | max77663_rtc_do_irq(rtc); | ||
307 | |||
308 | return IRQ_HANDLED; | ||
309 | } | ||
310 | |||
311 | static int max77663_rtc_alarm_irq_enable(struct device *dev, | ||
312 | unsigned int enabled) | ||
313 | { | ||
314 | struct max77663_rtc *rtc = dev_get_drvdata(dev); | ||
315 | int ret = 0; | ||
316 | |||
317 | if (rtc->irq < 0) | ||
318 | return -ENXIO; | ||
319 | |||
320 | mutex_lock(&rtc->io_lock); | ||
321 | |||
322 | /* Handle pending interrupt */ | ||
323 | ret = max77663_rtc_do_irq(rtc); | ||
324 | if (ret < 0) | ||
325 | goto out; | ||
326 | |||
327 | /* Config alarm interrupt */ | ||
328 | if (enabled) { | ||
329 | ret = max77663_rtc_irq_unmask(rtc, RTC_IRQ_ALARM1_MASK); | ||
330 | if (ret < 0) | ||
331 | goto out; | ||
332 | } else { | ||
333 | ret = max77663_rtc_irq_mask(rtc, RTC_IRQ_ALARM1_MASK); | ||
334 | if (ret < 0) | ||
335 | goto out; | ||
336 | } | ||
337 | out: | ||
338 | mutex_unlock(&rtc->io_lock); | ||
339 | return ret; | ||
340 | } | ||
341 | |||
342 | static int max77663_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
343 | { | ||
344 | struct max77663_rtc *rtc = dev_get_drvdata(dev); | ||
345 | u8 buf[RTC_NR]; | ||
346 | int ret; | ||
347 | |||
348 | ret = max77663_rtc_read(rtc, MAX77663_RTC_SEC, buf, sizeof(buf), 1); | ||
349 | if (ret < 0) { | ||
350 | dev_err(rtc->dev, "rtc_read_time: Failed to read rtc time\n"); | ||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | dev_dbg(rtc->dev, "rtc_read_time: " | ||
355 | "buf: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
356 | buf[RTC_SEC], buf[RTC_MIN], buf[RTC_HOUR], buf[RTC_WEEKDAY], | ||
357 | buf[RTC_MONTH], buf[RTC_YEAR], buf[RTC_MONTHDAY]); | ||
358 | |||
359 | ret = max77663_rtc_reg_to_tm(rtc, buf, tm); | ||
360 | if (ret < 0) { | ||
361 | dev_err(rtc->dev, "rtc_read_time: " | ||
362 | "Failed to convert register format into time format\n"); | ||
363 | return ret; | ||
364 | } | ||
365 | |||
366 | dev_dbg(rtc->dev, "rtc_read_time: " | ||
367 | "tm: %d-%02d-%02d %02d:%02d:%02d, wday=%d\n", | ||
368 | tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, | ||
369 | tm->tm_sec, tm->tm_wday); | ||
370 | |||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static int max77663_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
375 | { | ||
376 | struct max77663_rtc *rtc = dev_get_drvdata(dev); | ||
377 | u8 buf[RTC_NR]; | ||
378 | int ret; | ||
379 | |||
380 | dev_dbg(rtc->dev, "rtc_set_time: " | ||
381 | "tm: %d-%02d-%02d %02d:%02d:%02d, wday=%d\n", | ||
382 | tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, | ||
383 | tm->tm_sec, tm->tm_wday); | ||
384 | |||
385 | ret = max77663_rtc_tm_to_reg(rtc, buf, tm, 0); | ||
386 | if (ret < 0) { | ||
387 | dev_err(rtc->dev, "rtc_set_time: " | ||
388 | "Failed to convert time format into register format\n"); | ||
389 | return ret; | ||
390 | } | ||
391 | |||
392 | dev_dbg(rtc->dev, "rtc_set_time: " | ||
393 | "buf: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
394 | buf[RTC_SEC], buf[RTC_MIN], buf[RTC_HOUR], buf[RTC_WEEKDAY], | ||
395 | buf[RTC_MONTH], buf[RTC_YEAR], buf[RTC_MONTHDAY]); | ||
396 | |||
397 | return max77663_rtc_write(rtc, MAX77663_RTC_SEC, buf, sizeof(buf), 1); | ||
398 | } | ||
399 | |||
400 | static int max77663_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
401 | { | ||
402 | struct max77663_rtc *rtc = dev_get_drvdata(dev); | ||
403 | u8 buf[RTC_NR]; | ||
404 | int ret; | ||
405 | |||
406 | ret = max77663_rtc_read(rtc, MAX77663_RTC_ALARM_SEC1, buf, sizeof(buf), | ||
407 | 1); | ||
408 | if (ret < 0) { | ||
409 | dev_err(rtc->dev, | ||
410 | "rtc_read_alarm: Failed to read rtc alarm time\n"); | ||
411 | return ret; | ||
412 | } | ||
413 | |||
414 | dev_dbg(rtc->dev, "rtc_read_alarm: " | ||
415 | "buf: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
416 | buf[RTC_SEC], buf[RTC_MIN], buf[RTC_HOUR], buf[RTC_WEEKDAY], | ||
417 | buf[RTC_MONTH], buf[RTC_YEAR], buf[RTC_MONTHDAY]); | ||
418 | |||
419 | ret = max77663_rtc_reg_to_tm(rtc, buf, &alrm->time); | ||
420 | if (ret < 0) { | ||
421 | dev_err(rtc->dev, "rtc_read_alarm: " | ||
422 | "Failed to convert register format into time format\n"); | ||
423 | return ret; | ||
424 | } | ||
425 | |||
426 | dev_dbg(rtc->dev, "rtc_read_alarm: " | ||
427 | "tm: %d-%02d-%02d %02d:%02d:%02d, wday=%d\n", | ||
428 | alrm->time.tm_year, alrm->time.tm_mon, alrm->time.tm_mday, | ||
429 | alrm->time.tm_hour, alrm->time.tm_min, alrm->time.tm_sec, | ||
430 | alrm->time.tm_wday); | ||
431 | |||
432 | if (rtc->irq_mask & RTC_IRQ_ALARM1_MASK) | ||
433 | alrm->enabled = 1; | ||
434 | else | ||
435 | alrm->enabled = 0; | ||
436 | |||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | static int max77663_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
441 | { | ||
442 | struct max77663_rtc *rtc = dev_get_drvdata(dev); | ||
443 | u8 buf[RTC_NR]; | ||
444 | int ret; | ||
445 | |||
446 | dev_dbg(rtc->dev, "rtc_set_alarm: " | ||
447 | "tm: %d-%02d-%02d %02d:%02d:%02d, wday=%d [%s]\n", | ||
448 | alrm->time.tm_year, alrm->time.tm_mon, alrm->time.tm_mday, | ||
449 | alrm->time.tm_hour, alrm->time.tm_min, alrm->time.tm_sec, | ||
450 | alrm->time.tm_wday, alrm->enabled?"enable":"disable"); | ||
451 | |||
452 | ret = max77663_rtc_tm_to_reg(rtc, buf, &alrm->time, 1); | ||
453 | if (ret < 0) { | ||
454 | dev_err(rtc->dev, "rtc_set_alarm: " | ||
455 | "Failed to convert time format into register format\n"); | ||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | dev_dbg(rtc->dev, "rtc_set_alarm: " | ||
460 | "buf: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
461 | buf[RTC_SEC], buf[RTC_MIN], buf[RTC_HOUR], buf[RTC_WEEKDAY], | ||
462 | buf[RTC_MONTH], buf[RTC_YEAR], buf[RTC_MONTHDAY]); | ||
463 | |||
464 | ret = max77663_rtc_write(rtc, MAX77663_RTC_ALARM_SEC1, buf, sizeof(buf), | ||
465 | 1); | ||
466 | if (ret < 0) { | ||
467 | dev_err(rtc->dev, | ||
468 | "rtc_set_alarm: Failed to write rtc alarm time\n"); | ||
469 | return ret; | ||
470 | } | ||
471 | |||
472 | ret = max77663_rtc_alarm_irq_enable(dev, alrm->enabled); | ||
473 | if (ret < 0) { | ||
474 | dev_err(rtc->dev, | ||
475 | "rtc_set_alarm: Failed to enable rtc alarm\n"); | ||
476 | return ret; | ||
477 | } | ||
478 | |||
479 | return ret; | ||
480 | } | ||
481 | |||
482 | static const struct rtc_class_ops max77663_rtc_ops = { | ||
483 | .read_time = max77663_rtc_read_time, | ||
484 | .set_time = max77663_rtc_set_time, | ||
485 | .read_alarm = max77663_rtc_read_alarm, | ||
486 | .set_alarm = max77663_rtc_set_alarm, | ||
487 | .alarm_irq_enable = max77663_rtc_alarm_irq_enable, | ||
488 | }; | ||
489 | |||
490 | static int max77663_rtc_preinit(struct max77663_rtc *rtc) | ||
491 | { | ||
492 | struct device *parent = _to_parent(rtc); | ||
493 | u8 val; | ||
494 | int ret; | ||
495 | |||
496 | /* Mask all interrupts */ | ||
497 | rtc->irq_mask = 0xFF; | ||
498 | ret = max77663_rtc_write(rtc, MAX77663_RTC_IRQ_MASK, &rtc->irq_mask, 1, | ||
499 | 0); | ||
500 | if (ret < 0) { | ||
501 | dev_err(rtc->dev, "preinit: Failed to set rtc irq mask\n"); | ||
502 | return ret; | ||
503 | } | ||
504 | |||
505 | /* Configure Binary mode and 24hour mode */ | ||
506 | val = HR_MODE_MASK; | ||
507 | ret = max77663_rtc_write(rtc, MAX77663_RTC_CTRL, &val, 1, 0); | ||
508 | if (ret < 0) { | ||
509 | dev_err(rtc->dev, "preinit: Failed to set rtc control\n"); | ||
510 | return ret; | ||
511 | } | ||
512 | |||
513 | /* It should be disabled alarm wakeup to wakeup from sleep | ||
514 | * by EN1 input signal */ | ||
515 | ret = max77663_set_bits(parent, MAX77663_REG_ONOFF_CFG2, | ||
516 | ONOFF_WK_ALARM1_MASK, 0, 0); | ||
517 | if (ret < 0) { | ||
518 | dev_err(rtc->dev, "preinit: Failed to set onoff cfg2\n"); | ||
519 | return ret; | ||
520 | } | ||
521 | |||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | static int max77663_rtc_probe(struct platform_device *pdev) | ||
526 | { | ||
527 | struct max77663_platform_data *parent_pdata = | ||
528 | pdev->dev.parent->platform_data; | ||
529 | static struct max77663_rtc *rtc; | ||
530 | int ret = 0; | ||
531 | |||
532 | rtc = kzalloc(sizeof(struct max77663_rtc), GFP_KERNEL); | ||
533 | if (!rtc) { | ||
534 | dev_err(&pdev->dev, "probe: kzalloc() failed\n"); | ||
535 | return -ENOMEM; | ||
536 | } | ||
537 | |||
538 | dev_set_drvdata(&pdev->dev, rtc); | ||
539 | rtc->dev = &pdev->dev; | ||
540 | mutex_init(&rtc->io_lock); | ||
541 | |||
542 | ret = max77663_rtc_preinit(rtc); | ||
543 | if (ret) { | ||
544 | dev_err(&pdev->dev, "probe: Failed to rtc preinit\n"); | ||
545 | goto out_kfree; | ||
546 | } | ||
547 | |||
548 | rtc->rtc = rtc_device_register("max77663-rtc", &pdev->dev, | ||
549 | &max77663_rtc_ops, THIS_MODULE); | ||
550 | if (IS_ERR_OR_NULL(rtc->rtc)) { | ||
551 | dev_err(&pdev->dev, "probe: Failed to register rtc\n"); | ||
552 | ret = PTR_ERR(rtc->rtc); | ||
553 | goto out_kfree; | ||
554 | } | ||
555 | |||
556 | if (parent_pdata->irq_base < 0) | ||
557 | goto out; | ||
558 | |||
559 | rtc->irq = parent_pdata->irq_base + MAX77663_IRQ_RTC; | ||
560 | ret = request_threaded_irq(rtc->irq, NULL, max77663_rtc_irq, | ||
561 | IRQF_ONESHOT, "max77663-rtc", rtc); | ||
562 | if (ret < 0) { | ||
563 | dev_err(rtc->dev, "probe: Failed to request irq %d\n", | ||
564 | rtc->irq); | ||
565 | rtc->irq = -1; | ||
566 | } else { | ||
567 | device_init_wakeup(rtc->dev, 1); | ||
568 | enable_irq_wake(rtc->irq); | ||
569 | } | ||
570 | |||
571 | return 0; | ||
572 | |||
573 | out_kfree: | ||
574 | mutex_destroy(&rtc->io_lock); | ||
575 | kfree(rtc->rtc); | ||
576 | out: | ||
577 | return ret; | ||
578 | } | ||
579 | |||
580 | static int __devexit max77663_rtc_remove(struct platform_device *pdev) | ||
581 | { | ||
582 | struct max77663_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
583 | |||
584 | if (rtc->irq != -1) | ||
585 | free_irq(rtc->irq, rtc); | ||
586 | |||
587 | rtc_device_unregister(rtc->rtc); | ||
588 | mutex_destroy(&rtc->io_lock); | ||
589 | kfree(rtc); | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static struct platform_driver max77663_rtc_driver = { | ||
595 | .probe = max77663_rtc_probe, | ||
596 | .remove = __devexit_p(max77663_rtc_remove), | ||
597 | .driver = { | ||
598 | .name = "max77663-rtc", | ||
599 | .owner = THIS_MODULE, | ||
600 | }, | ||
601 | }; | ||
602 | |||
603 | static int __init max77663_rtc_init(void) | ||
604 | { | ||
605 | return platform_driver_register(&max77663_rtc_driver); | ||
606 | } | ||
607 | module_init(max77663_rtc_init); | ||
608 | |||
609 | static void __exit max77663_rtc_exit(void) | ||
610 | { | ||
611 | platform_driver_unregister(&max77663_rtc_driver); | ||
612 | } | ||
613 | module_exit(max77663_rtc_exit); | ||
614 | |||
615 | MODULE_DESCRIPTION("max77663 RTC driver"); | ||
616 | MODULE_LICENSE("GPL v2"); | ||
617 | MODULE_VERSION("1.0"); | ||
diff --git a/drivers/rtc/rtc-max8907c.c b/drivers/rtc/rtc-max8907c.c new file mode 100644 index 00000000000..f7287021da3 --- /dev/null +++ b/drivers/rtc/rtc-max8907c.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /* | ||
2 | * RTC driver for Maxim MAX8907c | ||
3 | * | ||
4 | * Copyright (c) 2011, NVIDIA Corporation. | ||
5 | * Based on drivers/rtc/rtc-max8925.c, Copyright (C) 2009-2010 Marvell International Ltd. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/rtc.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/mfd/max8907c.h> | ||
18 | |||
19 | enum { | ||
20 | RTC_SEC = 0, | ||
21 | RTC_MIN, | ||
22 | RTC_HOUR, | ||
23 | RTC_WEEKDAY, | ||
24 | RTC_DATE, | ||
25 | RTC_MONTH, | ||
26 | RTC_YEAR1, | ||
27 | RTC_YEAR2, | ||
28 | }; | ||
29 | |||
30 | #define TIME_NUM 8 | ||
31 | #define ALARM_1SEC (1 << 7) | ||
32 | #define HOUR_12 (1 << 7) | ||
33 | #define HOUR_AM_PM (1 << 5) | ||
34 | #define ALARM0_IRQ (1 << 3) | ||
35 | #define ALARM1_IRQ (1 << 2) | ||
36 | #define ALARM0_STATUS (1 << 2) | ||
37 | #define ALARM1_STATUS (1 << 1) | ||
38 | |||
39 | struct max8907c_rtc_info { | ||
40 | struct rtc_device *rtc_dev; | ||
41 | struct i2c_client *i2c; | ||
42 | struct max8907c *chip; | ||
43 | }; | ||
44 | |||
45 | static irqreturn_t rtc_update_handler(int irq, void *data) | ||
46 | { | ||
47 | struct max8907c_rtc_info *info = (struct max8907c_rtc_info *)data; | ||
48 | |||
49 | /* disable ALARM0 except for 1SEC alarm */ | ||
50 | max8907c_set_bits(info->i2c, MAX8907C_REG_ALARM0_CNTL, 0x7f, 0); | ||
51 | rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF); | ||
52 | return IRQ_HANDLED; | ||
53 | } | ||
54 | |||
55 | static int tm_calc(struct rtc_time *tm, u8 *buf, int len) | ||
56 | { | ||
57 | if (len < TIME_NUM) | ||
58 | return -EINVAL; | ||
59 | tm->tm_year = (buf[RTC_YEAR2] >> 4) * 1000 | ||
60 | + (buf[RTC_YEAR2] & 0xf) * 100 | ||
61 | + (buf[RTC_YEAR1] >> 4) * 10 | ||
62 | + (buf[RTC_YEAR1] & 0xf); | ||
63 | tm->tm_year -= 1900; | ||
64 | /* RTC month index issue in max8907c | ||
65 | : January index is 1 but kernel assumes it as 0 */ | ||
66 | tm->tm_mon = ((buf[RTC_MONTH] >> 4) & 0x01) * 10 | ||
67 | + (buf[RTC_MONTH] & 0x0f) - 1; | ||
68 | tm->tm_mday = ((buf[RTC_DATE] >> 4) & 0x03) * 10 | ||
69 | + (buf[RTC_DATE] & 0x0f); | ||
70 | tm->tm_wday = buf[RTC_WEEKDAY] & 0x07; | ||
71 | if (buf[RTC_HOUR] & HOUR_12) { | ||
72 | tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x1) * 10 | ||
73 | + (buf[RTC_HOUR] & 0x0f); | ||
74 | if (buf[RTC_HOUR] & HOUR_AM_PM) | ||
75 | tm->tm_hour += 12; | ||
76 | } else { | ||
77 | tm->tm_hour = ((buf[RTC_HOUR] >> 4) & 0x03) * 10 | ||
78 | + (buf[RTC_HOUR] & 0x0f); | ||
79 | } | ||
80 | tm->tm_min = ((buf[RTC_MIN] >> 4) & 0x7) * 10 | ||
81 | + (buf[RTC_MIN] & 0x0f); | ||
82 | tm->tm_sec = ((buf[RTC_SEC] >> 4) & 0x7) * 10 | ||
83 | + (buf[RTC_SEC] & 0x0f); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int data_calc(u8 *buf, struct rtc_time *tm, int len) | ||
88 | { | ||
89 | u8 high, low; | ||
90 | |||
91 | if (len < TIME_NUM) | ||
92 | return -EINVAL; | ||
93 | |||
94 | high = (tm->tm_year + 1900) / 1000; | ||
95 | low = (tm->tm_year + 1900) / 100; | ||
96 | low = low - high * 10; | ||
97 | buf[RTC_YEAR2] = (high << 4) + low; | ||
98 | high = (tm->tm_year + 1900) / 10; | ||
99 | low = tm->tm_year + 1900; | ||
100 | low = low - high * 10; | ||
101 | high = high - (high / 10) * 10; | ||
102 | buf[RTC_YEAR1] = (high << 4) + low; | ||
103 | |||
104 | /* RTC month index issue in max8907c | ||
105 | : January index is 1 but kernel assumes it as 0 */ | ||
106 | high = (tm->tm_mon + 1) / 10; | ||
107 | low = (tm->tm_mon + 1) % 10; | ||
108 | buf[RTC_MONTH] = (high << 4) + low; | ||
109 | |||
110 | high = tm->tm_mday / 10; | ||
111 | low = tm->tm_mday; | ||
112 | low = low - high * 10; | ||
113 | buf[RTC_DATE] = (high << 4) + low; | ||
114 | buf[RTC_WEEKDAY] = tm->tm_wday; | ||
115 | high = tm->tm_hour / 10; | ||
116 | low = tm->tm_hour; | ||
117 | low = low - high * 10; | ||
118 | buf[RTC_HOUR] = (high << 4) + low; | ||
119 | high = tm->tm_min / 10; | ||
120 | low = tm->tm_min; | ||
121 | low = low - high * 10; | ||
122 | buf[RTC_MIN] = (high << 4) + low; | ||
123 | high = tm->tm_sec / 10; | ||
124 | low = tm->tm_sec; | ||
125 | low = low - high * 10; | ||
126 | buf[RTC_SEC] = (high << 4) + low; | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int max8907c_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
131 | { | ||
132 | struct max8907c_rtc_info *info = dev_get_drvdata(dev); | ||
133 | u8 buf[TIME_NUM]; | ||
134 | int ret; | ||
135 | |||
136 | ret = max8907c_reg_bulk_read(info->i2c, MAX8907C_REG_RTC_SEC, TIME_NUM, buf); | ||
137 | |||
138 | if (ret < 0) | ||
139 | return ret; | ||
140 | ret = tm_calc(tm, buf, TIME_NUM); | ||
141 | |||
142 | return ret; | ||
143 | } | ||
144 | |||
145 | static int max8907c_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
146 | { | ||
147 | struct max8907c_rtc_info *info = dev_get_drvdata(dev); | ||
148 | u8 buf[TIME_NUM]; | ||
149 | int ret; | ||
150 | |||
151 | ret = data_calc(buf, tm, TIME_NUM); | ||
152 | |||
153 | if (ret < 0) | ||
154 | return ret; | ||
155 | ret = max8907c_reg_bulk_write(info->i2c, MAX8907C_REG_RTC_SEC, TIME_NUM, buf); | ||
156 | |||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | static int max8907c_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
161 | { | ||
162 | struct max8907c_rtc_info *info = dev_get_drvdata(dev); | ||
163 | unsigned char buf[TIME_NUM]; | ||
164 | int ret; | ||
165 | |||
166 | ret = max8907c_reg_bulk_read(info->i2c, MAX8907C_REG_ALARM0_SEC, TIME_NUM, buf); | ||
167 | if (ret < 0) | ||
168 | return ret; | ||
169 | ret = tm_calc(&alrm->time, buf, TIME_NUM); | ||
170 | if (ret < 0) | ||
171 | return ret; | ||
172 | ret = max8907c_reg_read(info->i2c, MAX8907C_REG_RTC_IRQ_MASK); | ||
173 | if (ret < 0) | ||
174 | return ret; | ||
175 | if ((ret & ALARM0_IRQ) == 0) | ||
176 | alrm->enabled = 1; | ||
177 | else | ||
178 | alrm->enabled = 0; | ||
179 | ret = max8907c_reg_read(info->i2c, MAX8907C_REG_RTC_STATUS); | ||
180 | if (ret < 0) | ||
181 | return ret; | ||
182 | if (ret & ALARM0_STATUS) | ||
183 | alrm->pending = 1; | ||
184 | else | ||
185 | alrm->pending = 0; | ||
186 | |||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | static int max8907c_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
191 | { | ||
192 | struct max8907c_rtc_info *info = dev_get_drvdata(dev); | ||
193 | unsigned char buf[TIME_NUM]; | ||
194 | int ret; | ||
195 | |||
196 | ret = data_calc(buf, &alrm->time, TIME_NUM); | ||
197 | if (ret < 0) | ||
198 | return ret; | ||
199 | ret = max8907c_reg_bulk_write(info->i2c, MAX8907C_REG_ALARM0_SEC, TIME_NUM, buf); | ||
200 | if (ret < 0) | ||
201 | return ret; | ||
202 | /* only enable alarm on year/month/day/hour/min/sec */ | ||
203 | ret = max8907c_reg_write(info->i2c, MAX8907C_REG_ALARM0_CNTL, 0x77); | ||
204 | |||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static const struct rtc_class_ops max8907c_rtc_ops = { | ||
209 | .read_time = max8907c_rtc_read_time, | ||
210 | .set_time = max8907c_rtc_set_time, | ||
211 | .read_alarm = max8907c_rtc_read_alarm, | ||
212 | .set_alarm = max8907c_rtc_set_alarm, | ||
213 | }; | ||
214 | |||
215 | static int __devinit max8907c_rtc_probe(struct platform_device *pdev) | ||
216 | { | ||
217 | struct max8907c *chip = dev_get_drvdata(pdev->dev.parent); | ||
218 | struct max8907c_rtc_info *info; | ||
219 | int irq, ret; | ||
220 | |||
221 | info = kzalloc(sizeof(struct max8907c_rtc_info), GFP_KERNEL); | ||
222 | if (!info) | ||
223 | return -ENOMEM; | ||
224 | info->i2c = chip->i2c_rtc; | ||
225 | info->chip = chip; | ||
226 | |||
227 | irq = chip->irq_base + MAX8907C_IRQ_RTC_ALARM0; | ||
228 | |||
229 | ret = request_threaded_irq(irq, NULL, rtc_update_handler, | ||
230 | IRQF_ONESHOT, "rtc-alarm0", info); | ||
231 | if (ret < 0) { | ||
232 | dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n", | ||
233 | irq, ret); | ||
234 | goto out_irq; | ||
235 | } | ||
236 | |||
237 | dev_set_drvdata(&pdev->dev, info); | ||
238 | info->rtc_dev = rtc_device_register("max8907c-rtc", &pdev->dev, | ||
239 | &max8907c_rtc_ops, THIS_MODULE); | ||
240 | ret = PTR_ERR(info->rtc_dev); | ||
241 | if (IS_ERR(info->rtc_dev)) { | ||
242 | dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); | ||
243 | goto out_rtc; | ||
244 | } | ||
245 | |||
246 | max8907c_set_bits(chip->i2c_power, MAX8907C_REG_SYSENSEL, 0x2, 0x2); | ||
247 | |||
248 | platform_set_drvdata(pdev, info); | ||
249 | |||
250 | device_init_wakeup(&pdev->dev, 1); | ||
251 | |||
252 | return 0; | ||
253 | out_rtc: | ||
254 | free_irq(chip->irq_base + MAX8907C_IRQ_RTC_ALARM0, info); | ||
255 | |||
256 | out_irq: | ||
257 | kfree(info); | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | static int __devexit max8907c_rtc_remove(struct platform_device *pdev) | ||
262 | { | ||
263 | struct max8907c_rtc_info *info = platform_get_drvdata(pdev); | ||
264 | |||
265 | if (info) { | ||
266 | free_irq(info->chip->irq_base + MAX8907C_IRQ_RTC_ALARM0, info); | ||
267 | |||
268 | rtc_device_unregister(info->rtc_dev); | ||
269 | kfree(info); | ||
270 | } | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | #ifdef CONFIG_PM | ||
275 | static int max8907c_rtc_suspend(struct platform_device *pdev, pm_message_t state) | ||
276 | { | ||
277 | struct device *dev=&pdev->dev; | ||
278 | struct max8907c_rtc_info *info = platform_get_drvdata(pdev); | ||
279 | |||
280 | if (device_may_wakeup(dev)) | ||
281 | enable_irq_wake(info->chip->irq_base + MAX8907C_IRQ_RTC_ALARM0); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int max8907c_rtc_resume(struct platform_device *pdev) | ||
286 | { | ||
287 | struct device *dev=&pdev->dev; | ||
288 | struct max8907c_rtc_info *info = platform_get_drvdata(pdev); | ||
289 | |||
290 | if (device_may_wakeup(dev)) | ||
291 | disable_irq_wake(info->chip->irq_base + MAX8907C_IRQ_RTC_ALARM0); | ||
292 | return 0; | ||
293 | } | ||
294 | #endif | ||
295 | |||
296 | static struct platform_driver max8907c_rtc_driver = { | ||
297 | .driver = { | ||
298 | .name = "max8907c-rtc", | ||
299 | .owner = THIS_MODULE, | ||
300 | }, | ||
301 | .probe = max8907c_rtc_probe, | ||
302 | .remove = __devexit_p(max8907c_rtc_remove), | ||
303 | #ifdef CONFIG_PM | ||
304 | .suspend = max8907c_rtc_suspend, | ||
305 | .resume = max8907c_rtc_resume, | ||
306 | #endif | ||
307 | }; | ||
308 | |||
309 | static int __init max8907c_rtc_init(void) | ||
310 | { | ||
311 | return platform_driver_register(&max8907c_rtc_driver); | ||
312 | } | ||
313 | module_init(max8907c_rtc_init); | ||
314 | |||
315 | static void __exit max8907c_rtc_exit(void) | ||
316 | { | ||
317 | platform_driver_unregister(&max8907c_rtc_driver); | ||
318 | } | ||
319 | module_exit(max8907c_rtc_exit); | ||
320 | |||
321 | MODULE_DESCRIPTION("Maxim MAX8907C RTC driver"); | ||
322 | MODULE_LICENSE("GPL"); | ||
323 | |||
diff --git a/drivers/rtc/rtc-ricoh583.c b/drivers/rtc/rtc-ricoh583.c new file mode 100644 index 00000000000..8bc17d9a101 --- /dev/null +++ b/drivers/rtc/rtc-ricoh583.c | |||
@@ -0,0 +1,403 @@ | |||
1 | /* | ||
2 | * drivers/rtc/rtc_ricoh583.c | ||
3 | * | ||
4 | * rtc driver for ricoh rc5t583 pmu | ||
5 | * | ||
6 | * copyright (c) 2011, nvidia corporation. | ||
7 | * | ||
8 | * this program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the gnu general public license as published by | ||
10 | * the free software foundation; either version 2 of the license, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * this program is distributed in the hope that it will be useful, but without | ||
14 | * any warranty; without even the implied warranty of merchantability or | ||
15 | * fitness for a particular purpose. see the gnu general public license for | ||
16 | * more details. | ||
17 | * | ||
18 | * you should have received a copy of the gnu general public license along | ||
19 | * with this program; if not, write to the free software foundation, inc., | ||
20 | * 51 franklin street, fifth floor, boston, ma 02110-1301, usa. | ||
21 | */ | ||
22 | |||
23 | /* #define debug 1 */ | ||
24 | /* #define verbose_debug 1 */ | ||
25 | |||
26 | #include <linux/device.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/mfd/ricoh583.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/rtc.h> | ||
33 | #include <linux/slab.h> | ||
34 | |||
35 | #define rtc_ctrl1 0xED | ||
36 | #define rtc_ctrl2 0xEE | ||
37 | #define rtc_seconds_reg 0xE0 | ||
38 | #define rtc_alarm_y 0xF0 | ||
39 | #define rtc_adjust 0xE7 | ||
40 | |||
41 | /* | ||
42 | linux rtc driver refers 1900 as base year in many calculations. | ||
43 | (e.g. refer drivers/rtc/rtc-lib.c) | ||
44 | */ | ||
45 | #define os_ref_year 1900 | ||
46 | |||
47 | /* | ||
48 | pmu rtc have only 2 nibbles to store year information, so using an | ||
49 | offset of 100 to set the base year as 2000 for our driver. | ||
50 | */ | ||
51 | #define rtc_year_offset 100 | ||
52 | |||
53 | struct ricoh583_rtc { | ||
54 | unsigned long epoch_start; | ||
55 | int irq; | ||
56 | struct rtc_device *rtc; | ||
57 | bool irq_en; | ||
58 | }; | ||
59 | |||
60 | static int ricoh583_read_regs(struct device *dev, int reg, int len, | ||
61 | uint8_t *val) | ||
62 | { | ||
63 | int ret; | ||
64 | |||
65 | ret = ricoh583_bulk_reads(dev->parent, reg, len, val); | ||
66 | if (ret < 0) { | ||
67 | dev_err(dev->parent, "\n %s failed reading from 0x%02x\n", | ||
68 | __func__, reg); | ||
69 | WARN_ON(1); | ||
70 | } | ||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | static int ricoh583_write_regs(struct device *dev, int reg, int len, | ||
75 | uint8_t *val) | ||
76 | { | ||
77 | int ret; | ||
78 | ret = ricoh583_bulk_writes(dev->parent, reg, len, val); | ||
79 | if (ret < 0) { | ||
80 | dev_err(dev->parent, "\n %s failed writing\n", __func__); | ||
81 | WARN_ON(1); | ||
82 | } | ||
83 | |||
84 | return ret; | ||
85 | } | ||
86 | |||
87 | static int ricoh583_rtc_valid_tm(struct device *dev, struct rtc_time *tm) | ||
88 | { | ||
89 | if (tm->tm_year >= (rtc_year_offset + 99) | ||
90 | || tm->tm_mon > 12 | ||
91 | || tm->tm_mday < 1 | ||
92 | || tm->tm_mday > rtc_month_days(tm->tm_mon, | ||
93 | tm->tm_year + os_ref_year) | ||
94 | || tm->tm_hour >= 24 | ||
95 | || tm->tm_min >= 60 | ||
96 | || tm->tm_sec >= 60) { | ||
97 | dev_err(dev->parent, "\n returning error due to time" | ||
98 | "%d/%d/%d %d:%d:%d", tm->tm_mon, tm->tm_mday, | ||
99 | tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
100 | return -EINVAL; | ||
101 | } | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static u8 dec2bcd(u8 dec) | ||
106 | { | ||
107 | return ((dec/10)<<4)+(dec%10); | ||
108 | } | ||
109 | |||
110 | static u8 bcd2dec(u8 bcd) | ||
111 | { | ||
112 | return (bcd >> 4)*10+(bcd & 0xf); | ||
113 | } | ||
114 | |||
115 | static void convert_bcd_to_decimal(u8 *buf, u8 len) | ||
116 | { | ||
117 | int i = 0; | ||
118 | for (i = 0; i < len; i++) | ||
119 | buf[i] = bcd2dec(buf[i]); | ||
120 | } | ||
121 | |||
122 | static void convert_decimal_to_bcd(u8 *buf, u8 len) | ||
123 | { | ||
124 | int i = 0; | ||
125 | for (i = 0; i < len; i++) | ||
126 | buf[i] = dec2bcd(buf[i]); | ||
127 | } | ||
128 | |||
129 | static void print_time(struct device *dev, struct rtc_time *tm) | ||
130 | { | ||
131 | dev_info(dev, "rtc-time : %d/%d/%d %d:%d\n", | ||
132 | (tm->tm_mon + 1), tm->tm_mday, (tm->tm_year + os_ref_year), | ||
133 | tm->tm_hour, tm->tm_min); | ||
134 | } | ||
135 | |||
136 | static int ricoh583_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
137 | { | ||
138 | u8 buff[7]; | ||
139 | int err; | ||
140 | err = ricoh583_read_regs(dev, rtc_seconds_reg, sizeof(buff), buff); | ||
141 | if (err < 0) { | ||
142 | dev_err(dev, "\n %s :: failed to read time\n", __FILE__); | ||
143 | return err; | ||
144 | } | ||
145 | convert_bcd_to_decimal(buff, sizeof(buff)); | ||
146 | tm->tm_sec = buff[0]; | ||
147 | tm->tm_min = buff[1]; | ||
148 | tm->tm_hour = buff[2]; | ||
149 | tm->tm_wday = buff[3]; | ||
150 | tm->tm_mday = buff[4]; | ||
151 | tm->tm_mon = buff[5] - 1; | ||
152 | tm->tm_year = buff[6] + rtc_year_offset; | ||
153 | print_time(dev, tm); | ||
154 | return ricoh583_rtc_valid_tm(dev, tm); | ||
155 | } | ||
156 | |||
157 | static int ricoh583_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
158 | { | ||
159 | u8 buff[7]; | ||
160 | int err; | ||
161 | |||
162 | print_time(dev, tm); | ||
163 | buff[0] = tm->tm_sec; | ||
164 | buff[1] = tm->tm_min; | ||
165 | buff[2] = tm->tm_hour; | ||
166 | buff[3] = tm->tm_wday; | ||
167 | buff[4] = tm->tm_mday; | ||
168 | buff[5] = tm->tm_mon + 1; | ||
169 | buff[6] = tm->tm_year - rtc_year_offset; | ||
170 | |||
171 | convert_decimal_to_bcd(buff, sizeof(buff)); | ||
172 | err = ricoh583_write_regs(dev, rtc_seconds_reg, sizeof(buff), buff); | ||
173 | if (err < 0) { | ||
174 | dev_err(dev->parent, "\n failed to program new time\n"); | ||
175 | return err; | ||
176 | } | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | static int ricoh583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm); | ||
181 | |||
182 | static int ricoh583_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
183 | { | ||
184 | struct ricoh583_rtc *rtc = dev_get_drvdata(dev); | ||
185 | unsigned long seconds; | ||
186 | u8 buff[5]; | ||
187 | int err; | ||
188 | struct rtc_time tm; | ||
189 | |||
190 | if (rtc->irq == -1) | ||
191 | return -EIO; | ||
192 | |||
193 | rtc_tm_to_time(&alrm->time, &seconds); | ||
194 | ricoh583_rtc_read_time(dev, &tm); | ||
195 | rtc_tm_to_time(&tm, &rtc->epoch_start); | ||
196 | /* | ||
197 | work around: As YAL does not provide the seconds register, | ||
198 | program minute register to next minute, in cases when alarm | ||
199 | is requested within a minute from the current time. | ||
200 | */ | ||
201 | if (seconds - rtc->epoch_start < 60) | ||
202 | alrm->time.tm_min += 1; | ||
203 | dev_info(dev->parent, "\n setting alarm to requested time::\n"); | ||
204 | print_time(dev->parent, &alrm->time); | ||
205 | |||
206 | if (WARN_ON(alrm->enabled && (seconds < rtc->epoch_start))) { | ||
207 | dev_err(dev->parent, "\n can't set alarm to requested time\n"); | ||
208 | return -EINVAL; | ||
209 | } | ||
210 | |||
211 | if (alrm->enabled && !rtc->irq_en) | ||
212 | rtc->irq_en = true; | ||
213 | else if (!alrm->enabled && rtc->irq_en) | ||
214 | rtc->irq_en = false; | ||
215 | |||
216 | buff[0] = alrm->time.tm_min; | ||
217 | buff[1] = alrm->time.tm_hour; | ||
218 | buff[2] = alrm->time.tm_mday; | ||
219 | buff[3] = alrm->time.tm_mon + 1; | ||
220 | buff[4] = alrm->time.tm_year - rtc_year_offset; | ||
221 | convert_decimal_to_bcd(buff, sizeof(buff)); | ||
222 | err = ricoh583_write_regs(dev, rtc_alarm_y, sizeof(buff), buff); | ||
223 | if (err) { | ||
224 | dev_err(dev->parent, "\n unable to set alarm\n"); | ||
225 | return -EBUSY; | ||
226 | } | ||
227 | buff[0] = 0x20; /* to enable alarm_y */ | ||
228 | buff[1] = 0x20; /* to enable 24-hour format */ | ||
229 | err = ricoh583_write_regs(dev, rtc_ctrl1, 2, buff); | ||
230 | if (err) { | ||
231 | dev_err(dev, "failed programming rtc ctrl regs\n"); | ||
232 | return -EBUSY; | ||
233 | } | ||
234 | return err; | ||
235 | } | ||
236 | |||
237 | static int ricoh583_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
238 | { | ||
239 | u8 buff[5]; | ||
240 | int err; | ||
241 | |||
242 | err = ricoh583_read_regs(dev, rtc_alarm_y, sizeof(buff), buff); | ||
243 | if (err) | ||
244 | return err; | ||
245 | convert_bcd_to_decimal(buff, sizeof(buff)); | ||
246 | |||
247 | alrm->time.tm_min = buff[0]; | ||
248 | alrm->time.tm_hour = buff[1]; | ||
249 | alrm->time.tm_mday = buff[2]; | ||
250 | alrm->time.tm_mon = buff[3] - 1; | ||
251 | alrm->time.tm_year = buff[4] + rtc_year_offset; | ||
252 | |||
253 | dev_info(dev->parent, "\n getting alarm time::\n"); | ||
254 | print_time(dev, &alrm->time); | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static const struct rtc_class_ops ricoh583_rtc_ops = { | ||
260 | .read_time = ricoh583_rtc_read_time, | ||
261 | .set_time = ricoh583_rtc_set_time, | ||
262 | .set_alarm = ricoh583_rtc_set_alarm, | ||
263 | .read_alarm = ricoh583_rtc_read_alarm, | ||
264 | }; | ||
265 | |||
266 | static irqreturn_t ricoh583_rtc_irq(int irq, void *data) | ||
267 | { | ||
268 | struct device *dev = data; | ||
269 | struct ricoh583_rtc *rtc = dev_get_drvdata(dev); | ||
270 | u8 reg; | ||
271 | int err; | ||
272 | |||
273 | /* clear alarm-Y status bits.*/ | ||
274 | err = ricoh583_read_regs(dev, rtc_ctrl2, 1, ®); | ||
275 | if (err) { | ||
276 | dev_err(dev->parent, "unable to read rtc_ctrl2 reg\n"); | ||
277 | return -EBUSY; | ||
278 | } | ||
279 | reg &= ~0x8; | ||
280 | err = ricoh583_write_regs(dev, rtc_ctrl2, 1, ®); | ||
281 | if (err) { | ||
282 | dev_err(dev->parent, "unable to program rtc_status reg\n"); | ||
283 | return -EBUSY; | ||
284 | } | ||
285 | |||
286 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
287 | return IRQ_HANDLED; | ||
288 | } | ||
289 | |||
290 | static int __devinit ricoh583_rtc_probe(struct platform_device *pdev) | ||
291 | { | ||
292 | struct ricoh583_rtc_platform_data *pdata = pdev->dev.platform_data; | ||
293 | struct ricoh583_rtc *rtc; | ||
294 | struct rtc_time tm; | ||
295 | int err; | ||
296 | u8 reg[2]; | ||
297 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); | ||
298 | |||
299 | if (!rtc) | ||
300 | return -ENOMEM; | ||
301 | |||
302 | rtc->irq = -1; | ||
303 | |||
304 | if (!pdata) { | ||
305 | dev_err(&pdev->dev, "no platform_data specified\n"); | ||
306 | return -EINVAL; | ||
307 | } | ||
308 | |||
309 | if (pdata->irq < 0) | ||
310 | dev_err(&pdev->dev, "\n no irq specified, wakeup is disabled\n"); | ||
311 | |||
312 | dev_set_drvdata(&pdev->dev, rtc); | ||
313 | device_init_wakeup(&pdev->dev, 1); | ||
314 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
315 | &ricoh583_rtc_ops, THIS_MODULE); | ||
316 | |||
317 | if (IS_ERR(rtc->rtc)) { | ||
318 | err = PTR_ERR(rtc->rtc); | ||
319 | goto fail; | ||
320 | } | ||
321 | reg[0] = 0; /* clearing RTC Adjust register */ | ||
322 | err = ricoh583_write_regs(&pdev->dev, rtc_adjust, 1, reg); | ||
323 | if (err) { | ||
324 | dev_err(&pdev->dev, "unable to program rtc_adjust reg\n"); | ||
325 | return -EBUSY; | ||
326 | } | ||
327 | |||
328 | reg[0] = 0x20; /* to enable alarm_y */ | ||
329 | reg[1] = 0x20; /* to enable 24-hour format */ | ||
330 | err = ricoh583_write_regs(&pdev->dev, rtc_ctrl1, 2, reg); | ||
331 | if (err) { | ||
332 | dev_err(&pdev->dev, "failed rtc setup\n"); | ||
333 | return -EBUSY; | ||
334 | } | ||
335 | |||
336 | ricoh583_rtc_read_time(&pdev->dev, &tm); | ||
337 | if (ricoh583_rtc_valid_tm(&pdev->dev, &tm)) { | ||
338 | if (pdata->time.tm_year < 2000 || pdata->time.tm_year > 2100) { | ||
339 | memset(&pdata->time, 0, sizeof(pdata->time)); | ||
340 | pdata->time.tm_year = rtc_year_offset; | ||
341 | pdata->time.tm_mday = 1; | ||
342 | } else | ||
343 | pdata->time.tm_year -= os_ref_year; | ||
344 | ricoh583_rtc_set_time(&pdev->dev, &pdata->time); | ||
345 | } | ||
346 | if (pdata && (pdata->irq >= 0)) { | ||
347 | rtc->irq = pdata->irq; | ||
348 | err = request_threaded_irq(pdata->irq, NULL, ricoh583_rtc_irq, | ||
349 | IRQF_ONESHOT, "rtc_ricoh583", | ||
350 | &pdev->dev); | ||
351 | if (err) { | ||
352 | dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq); | ||
353 | rtc->irq = -1; | ||
354 | } else { | ||
355 | device_init_wakeup(&pdev->dev, 1); | ||
356 | enable_irq_wake(rtc->irq); | ||
357 | } | ||
358 | } | ||
359 | return 0; | ||
360 | |||
361 | fail: | ||
362 | if (!IS_ERR_OR_NULL(rtc->rtc)) | ||
363 | rtc_device_unregister(rtc->rtc); | ||
364 | kfree(rtc); | ||
365 | return err; | ||
366 | } | ||
367 | |||
368 | static int __devexit ricoh583_rtc_remove(struct platform_device *pdev) | ||
369 | { | ||
370 | struct ricoh583_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
371 | |||
372 | if (rtc->irq != -1) | ||
373 | free_irq(rtc->irq, rtc); | ||
374 | rtc_device_unregister(rtc->rtc); | ||
375 | kfree(rtc); | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static struct platform_driver ricoh583_rtc_driver = { | ||
380 | .driver = { | ||
381 | .name = "rtc_ricoh583", | ||
382 | .owner = THIS_MODULE, | ||
383 | }, | ||
384 | .probe = ricoh583_rtc_probe, | ||
385 | .remove = __devexit_p(ricoh583_rtc_remove), | ||
386 | }; | ||
387 | |||
388 | static int __init ricoh583_rtc_init(void) | ||
389 | { | ||
390 | return platform_driver_register(&ricoh583_rtc_driver); | ||
391 | } | ||
392 | module_init(ricoh583_rtc_init); | ||
393 | |||
394 | static void __exit ricoh583_rtc_exit(void) | ||
395 | { | ||
396 | platform_driver_unregister(&ricoh583_rtc_driver); | ||
397 | } | ||
398 | module_exit(ricoh583_rtc_exit); | ||
399 | |||
400 | MODULE_DESCRIPTION("RICOH PMU ricoh583 RTC driver"); | ||
401 | MODULE_AUTHOR("NVIDIA Corporation"); | ||
402 | MODULE_LICENSE("GPL"); | ||
403 | MODULE_ALIAS("platform:rtc_ricoh583"); | ||
diff --git a/drivers/rtc/rtc-tps6591x.c b/drivers/rtc/rtc-tps6591x.c new file mode 100644 index 00000000000..cab3e8874df --- /dev/null +++ b/drivers/rtc/rtc-tps6591x.c | |||
@@ -0,0 +1,546 @@ | |||
1 | /* | ||
2 | * drivers/rtc/rtc_tps6591x.c | ||
3 | * | ||
4 | * RTC driver for TI TPS6591x | ||
5 | * | ||
6 | * Copyright (c) 2011, NVIDIA Corporation. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | /* #define DEBUG 1 */ | ||
24 | /* #define VERBOSE_DEBUG 1 */ | ||
25 | |||
26 | #include <linux/device.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/mfd/tps6591x.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/rtc.h> | ||
33 | #include <linux/slab.h> | ||
34 | |||
35 | #define RTC_CTRL 0x10 | ||
36 | #define RTC_STATUS 0x11 | ||
37 | #define RTC_SECONDS_REG 0x0 | ||
38 | #define RTC_ALARM 0x8 | ||
39 | #define RTC_INT 0x12 | ||
40 | #define RTC_RESET_STATUS 0x16 | ||
41 | #define RTC_BBCH_REG 0x39 | ||
42 | |||
43 | #define RTC_BBCH_SEL 0x02 | ||
44 | #define RTC_BBCH_EN 0x01 | ||
45 | #define ENABLE_ALARM_INT 0x8 | ||
46 | #define RTC_RESET_VALUE 0x80 | ||
47 | #define ALARM_INT_STATUS 0x40 | ||
48 | |||
49 | /* | ||
50 | Linux RTC driver refers 1900 as base year in many calculations. | ||
51 | (e.g. refer drivers/rtc/rtc-lib.c) | ||
52 | */ | ||
53 | #define OS_REF_YEAR 1900 | ||
54 | |||
55 | /* | ||
56 | PMU RTC have only 2 nibbles to store year information, so using an offset | ||
57 | of 100 to set the base year as 2000 for our driver. | ||
58 | */ | ||
59 | #define RTC_YEAR_OFFSET 100 | ||
60 | |||
61 | struct tps6591x_rtc { | ||
62 | unsigned long epoch_start; | ||
63 | int irq; | ||
64 | struct rtc_device *rtc; | ||
65 | bool irq_en; | ||
66 | }; | ||
67 | |||
68 | static int tps6591x_read_regs(struct device *dev, int reg, int len, | ||
69 | uint8_t *val) | ||
70 | { | ||
71 | int ret; | ||
72 | |||
73 | /* dummy read of STATUS_REG as per data sheet */ | ||
74 | ret = tps6591x_reads(dev->parent, RTC_STATUS, 1, val); | ||
75 | if (ret < 0) { | ||
76 | dev_err(dev->parent, "\n %s failed reading from RTC_STATUS\n", | ||
77 | __func__); | ||
78 | WARN_ON(1); | ||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | ret = tps6591x_reads(dev->parent, reg, len, val); | ||
83 | if (ret < 0) { | ||
84 | dev_err(dev->parent, "\n %s failed reading from 0x%02x\n", | ||
85 | __func__, reg); | ||
86 | WARN_ON(1); | ||
87 | return ret; | ||
88 | } | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int tps6591x_write_regs(struct device *dev, int reg, int len, | ||
93 | uint8_t *val) | ||
94 | { | ||
95 | int ret; | ||
96 | ret = tps6591x_writes(dev->parent, reg, len, val); | ||
97 | if (ret < 0) { | ||
98 | dev_err(dev->parent, "\n %s failed writing\n", __func__); | ||
99 | WARN_ON(1); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int tps6591x_rtc_valid_tm(struct rtc_time *tm) | ||
107 | { | ||
108 | if (tm->tm_year >= (RTC_YEAR_OFFSET + 99) | ||
109 | || tm->tm_mon >= 12 | ||
110 | || tm->tm_mday < 1 | ||
111 | || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + OS_REF_YEAR) | ||
112 | || tm->tm_hour >= 24 | ||
113 | || tm->tm_min >= 60 | ||
114 | || tm->tm_sec >= 60) | ||
115 | return -EINVAL; | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static u8 dec2bcd(u8 dec) | ||
120 | { | ||
121 | return ((dec/10)<<4)+(dec%10); | ||
122 | } | ||
123 | |||
124 | static u8 bcd2dec(u8 bcd) | ||
125 | { | ||
126 | return (bcd >> 4)*10+(bcd & 0xF); | ||
127 | } | ||
128 | |||
129 | static void convert_bcd_to_decimal(u8 *buf, u8 len) | ||
130 | { | ||
131 | int i = 0; | ||
132 | for (i = 0; i < len; i++) | ||
133 | buf[i] = bcd2dec(buf[i]); | ||
134 | } | ||
135 | |||
136 | static void convert_decimal_to_bcd(u8 *buf, u8 len) | ||
137 | { | ||
138 | int i = 0; | ||
139 | for (i = 0; i < len; i++) | ||
140 | buf[i] = dec2bcd(buf[i]); | ||
141 | } | ||
142 | |||
143 | static void print_time(struct device *dev, struct rtc_time *tm) | ||
144 | { | ||
145 | dev_info(dev, "RTC Time : %d/%d/%d %d:%d:%d\n", | ||
146 | (tm->tm_mon + 1), tm->tm_mday, (tm->tm_year + OS_REF_YEAR), | ||
147 | tm->tm_hour, tm->tm_min , tm->tm_sec); | ||
148 | } | ||
149 | |||
150 | static int tps6591x_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
151 | { | ||
152 | u8 buff[7]; | ||
153 | int err; | ||
154 | err = tps6591x_read_regs(dev, RTC_SECONDS_REG, sizeof(buff), buff); | ||
155 | if (err < 0) { | ||
156 | dev_err(dev, "\n %s :: failed to read time\n", __FILE__); | ||
157 | return err; | ||
158 | } | ||
159 | convert_bcd_to_decimal(buff, sizeof(buff)); | ||
160 | tm->tm_sec = buff[0]; | ||
161 | tm->tm_min = buff[1]; | ||
162 | tm->tm_hour = buff[2]; | ||
163 | tm->tm_mday = buff[3]; | ||
164 | tm->tm_mon = buff[4] - 1; | ||
165 | tm->tm_year = buff[5]; | ||
166 | tm->tm_wday = buff[6]; | ||
167 | print_time(dev, tm); | ||
168 | return tps6591x_rtc_valid_tm(tm); | ||
169 | } | ||
170 | |||
171 | static int tps6591x_rtc_stop(struct device *dev) | ||
172 | { | ||
173 | u8 reg = 0; | ||
174 | u8 retries = 0; | ||
175 | int err; | ||
176 | do { | ||
177 | err = tps6591x_read_regs(dev, RTC_CTRL, 1, ®); | ||
178 | if (err < 0) { | ||
179 | dev_err(dev->parent, "\n failed to read RTC_CTRL reg\n"); | ||
180 | return err; | ||
181 | } | ||
182 | |||
183 | /* clear STOP bit alone */ | ||
184 | reg &= ~0x1; | ||
185 | |||
186 | err = tps6591x_write_regs(dev, RTC_CTRL, 1, ®); | ||
187 | if (err < 0) { | ||
188 | dev_err(dev->parent, "\n failed to program RTC_CTRL reg\n"); | ||
189 | return err; | ||
190 | } | ||
191 | |||
192 | err = tps6591x_read_regs(dev, RTC_STATUS, 1, ®); | ||
193 | if (err < 0) { | ||
194 | dev_err(dev->parent, "\n failed to read RTC_CTRL reg\n"); | ||
195 | return err; | ||
196 | } | ||
197 | /* FixMe: Is allowing up to 5 retries sufficient?? */ | ||
198 | if (retries++ == 5) { | ||
199 | dev_err(dev->parent, "\n failed to stop RTC\n"); | ||
200 | return -EBUSY; | ||
201 | } | ||
202 | } while (reg & 2); | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static int tps6591x_rtc_start(struct device *dev) | ||
207 | { | ||
208 | u8 reg = 0; | ||
209 | u8 retries = 0; | ||
210 | int err; | ||
211 | |||
212 | do { | ||
213 | err = tps6591x_read_regs(dev, RTC_CTRL, 1, ®); | ||
214 | if (err < 0) { | ||
215 | dev_err(dev->parent, "\n failed to read RTC_CTRL reg\n"); | ||
216 | return err; | ||
217 | } | ||
218 | |||
219 | /* set STOP bit alone */ | ||
220 | reg |= 0x1; | ||
221 | |||
222 | err = tps6591x_write_regs(dev, RTC_CTRL, 1, ®); | ||
223 | if (err < 0) { | ||
224 | dev_err(dev->parent, "\n failed to program RTC_CTRL reg\n"); | ||
225 | return err; | ||
226 | } | ||
227 | |||
228 | err = tps6591x_read_regs(dev, RTC_STATUS, 1, ®); | ||
229 | if (err < 0) { | ||
230 | dev_err(dev->parent, "\n failed to read RTC_CTRL reg\n"); | ||
231 | return err; | ||
232 | } | ||
233 | /* FixMe: Is allowing up to 5 retries sufficient?? */ | ||
234 | if (retries++ == 5) { | ||
235 | dev_err(dev->parent, "\n failed to stop RTC\n"); | ||
236 | return -EBUSY; | ||
237 | } | ||
238 | } while (!(reg & 2)); | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | |||
243 | static int tps6591x_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
244 | { | ||
245 | u8 buff[7]; | ||
246 | int err; | ||
247 | |||
248 | buff[0] = tm->tm_sec; | ||
249 | buff[1] = tm->tm_min; | ||
250 | buff[2] = tm->tm_hour; | ||
251 | buff[3] = tm->tm_mday; | ||
252 | buff[4] = tm->tm_mon + 1; | ||
253 | buff[5] = tm->tm_year; | ||
254 | buff[6] = tm->tm_wday; | ||
255 | |||
256 | print_time(dev, tm); | ||
257 | convert_decimal_to_bcd(buff, sizeof(buff)); | ||
258 | err = tps6591x_rtc_stop(dev); | ||
259 | if (err < 0) { | ||
260 | dev_err(dev->parent, "\n failed to clear RTC_ENABLE\n"); | ||
261 | return err; | ||
262 | } | ||
263 | |||
264 | err = tps6591x_write_regs(dev, RTC_SECONDS_REG, sizeof(buff), buff); | ||
265 | if (err < 0) { | ||
266 | dev_err(dev->parent, "\n failed to program new time\n"); | ||
267 | return err; | ||
268 | } | ||
269 | |||
270 | err = tps6591x_rtc_start(dev); | ||
271 | if (err < 0) { | ||
272 | dev_err(dev->parent, "\n failed to set RTC_ENABLE\n"); | ||
273 | return err; | ||
274 | } | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int tps6591x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
280 | { | ||
281 | struct tps6591x_rtc *rtc = dev_get_drvdata(dev); | ||
282 | unsigned long seconds; | ||
283 | u8 buff[6]; | ||
284 | int err; | ||
285 | struct rtc_time tm; | ||
286 | |||
287 | if (rtc->irq == -1) | ||
288 | return -EIO; | ||
289 | |||
290 | dev_info(dev->parent, "\n setting alarm to requested time::\n"); | ||
291 | print_time(dev->parent, &alrm->time); | ||
292 | rtc_tm_to_time(&alrm->time, &seconds); | ||
293 | tps6591x_rtc_read_time(dev, &tm); | ||
294 | rtc_tm_to_time(&tm, &rtc->epoch_start); | ||
295 | |||
296 | if (WARN_ON(alrm->enabled && (seconds < rtc->epoch_start))) { | ||
297 | dev_err(dev->parent, "\n can't set alarm to requested time\n"); | ||
298 | return -EINVAL; | ||
299 | } | ||
300 | |||
301 | if (alrm->enabled && !rtc->irq_en) { | ||
302 | rtc->irq_en = true; | ||
303 | } else if (!alrm->enabled && rtc->irq_en) { | ||
304 | rtc->irq_en = false; | ||
305 | } | ||
306 | |||
307 | buff[0] = alrm->time.tm_sec; | ||
308 | buff[1] = alrm->time.tm_min; | ||
309 | buff[2] = alrm->time.tm_hour; | ||
310 | buff[3] = alrm->time.tm_mday; | ||
311 | buff[4] = alrm->time.tm_mon + 1; | ||
312 | buff[5] = alrm->time.tm_year; | ||
313 | convert_decimal_to_bcd(buff, sizeof(buff)); | ||
314 | err = tps6591x_write_regs(dev, RTC_ALARM, sizeof(buff), buff); | ||
315 | if (err) | ||
316 | dev_err(dev->parent, "\n unable to program alarm\n"); | ||
317 | |||
318 | return err; | ||
319 | } | ||
320 | |||
321 | static int tps6591x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
322 | { | ||
323 | u8 buff[6]; | ||
324 | int err; | ||
325 | |||
326 | err = tps6591x_read_regs(dev, RTC_ALARM, sizeof(buff), buff); | ||
327 | if (err) | ||
328 | return err; | ||
329 | convert_bcd_to_decimal(buff, sizeof(buff)); | ||
330 | |||
331 | alrm->time.tm_sec = buff[0]; | ||
332 | alrm->time.tm_min = buff[1]; | ||
333 | alrm->time.tm_hour = buff[2]; | ||
334 | alrm->time.tm_mday = buff[3]; | ||
335 | alrm->time.tm_mon = buff[4] - 1; | ||
336 | alrm->time.tm_year = buff[5]; | ||
337 | |||
338 | dev_info(dev->parent, "\n getting alarm time::\n"); | ||
339 | print_time(dev, &alrm->time); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static int tps6591x_rtc_alarm_irq_enable(struct device *dev, | ||
345 | unsigned int enable) | ||
346 | { | ||
347 | struct tps6591x_rtc *rtc = dev_get_drvdata(dev); | ||
348 | u8 reg; | ||
349 | int err; | ||
350 | |||
351 | if (rtc->irq == -1) | ||
352 | return -EIO; | ||
353 | |||
354 | if (enable) { | ||
355 | if (rtc->irq_en == true) | ||
356 | return 0; | ||
357 | err = tps6591x_read_regs(dev, RTC_INT, 1, ®); | ||
358 | if (err) | ||
359 | return err; | ||
360 | reg |= 0x8; | ||
361 | err = tps6591x_write_regs(dev, RTC_INT, 1, ®); | ||
362 | if (err) | ||
363 | return err; | ||
364 | rtc->irq_en = true; | ||
365 | } else { | ||
366 | if (rtc->irq_en == false) | ||
367 | return 0; | ||
368 | err = tps6591x_read_regs(dev, RTC_INT, 1, ®); | ||
369 | if (err) | ||
370 | return err; | ||
371 | reg &= ~0x8; | ||
372 | err = tps6591x_write_regs(dev, RTC_INT, 1, ®); | ||
373 | if (err) | ||
374 | return err; | ||
375 | rtc->irq_en = false; | ||
376 | } | ||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static const struct rtc_class_ops tps6591x_rtc_ops = { | ||
381 | .read_time = tps6591x_rtc_read_time, | ||
382 | .set_time = tps6591x_rtc_set_time, | ||
383 | .set_alarm = tps6591x_rtc_set_alarm, | ||
384 | .read_alarm = tps6591x_rtc_read_alarm, | ||
385 | .alarm_irq_enable = tps6591x_rtc_alarm_irq_enable, | ||
386 | }; | ||
387 | |||
388 | static irqreturn_t tps6591x_rtc_irq(int irq, void *data) | ||
389 | { | ||
390 | struct device *dev = data; | ||
391 | struct tps6591x_rtc *rtc = dev_get_drvdata(dev); | ||
392 | u8 reg; | ||
393 | int err; | ||
394 | |||
395 | /* clear Alarm status bits.*/ | ||
396 | err = tps6591x_read_regs(dev, RTC_STATUS, 1, ®); | ||
397 | if (err) { | ||
398 | dev_err(dev->parent, "unable to read RTC_STATUS reg\n"); | ||
399 | return -EBUSY; | ||
400 | } | ||
401 | |||
402 | reg = ALARM_INT_STATUS; | ||
403 | err = tps6591x_write_regs(dev, RTC_STATUS, 1, ®); | ||
404 | if (err) { | ||
405 | dev_err(dev->parent, "unable to program RTC_STATUS reg\n"); | ||
406 | return -EBUSY; | ||
407 | } | ||
408 | |||
409 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
410 | return IRQ_HANDLED; | ||
411 | } | ||
412 | |||
413 | static int __devinit tps6591x_rtc_probe(struct platform_device *pdev) | ||
414 | { | ||
415 | struct tps6591x_rtc_platform_data *pdata = pdev->dev.platform_data; | ||
416 | struct tps6591x_rtc *rtc; | ||
417 | struct rtc_time tm; | ||
418 | int err; | ||
419 | u8 reg; | ||
420 | |||
421 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); | ||
422 | |||
423 | if (!rtc) | ||
424 | return -ENOMEM; | ||
425 | |||
426 | rtc->irq = -1; | ||
427 | |||
428 | if (!pdata) { | ||
429 | dev_err(&pdev->dev, "no platform_data specified\n"); | ||
430 | return -EINVAL; | ||
431 | } | ||
432 | |||
433 | if (pdata->irq < 0) | ||
434 | dev_err(&pdev->dev, "\n no IRQ specified, wakeup is disabled\n"); | ||
435 | |||
436 | dev_set_drvdata(&pdev->dev, rtc); | ||
437 | device_init_wakeup(&pdev->dev, 1); | ||
438 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
439 | &tps6591x_rtc_ops, THIS_MODULE); | ||
440 | |||
441 | if (IS_ERR(rtc->rtc)) { | ||
442 | err = PTR_ERR(rtc->rtc); | ||
443 | goto fail; | ||
444 | } | ||
445 | |||
446 | if ((int)pdev && (int)&pdev->dev) | ||
447 | err = tps6591x_read_regs(&pdev->dev, RTC_STATUS, 1, ®); | ||
448 | else { | ||
449 | dev_err(&pdev->dev, "\n %s Input params incorrect\n", __func__); | ||
450 | return -EBUSY; | ||
451 | } | ||
452 | if (err) { | ||
453 | dev_err(&pdev->dev, "\n %s unable to read status\n", __func__); | ||
454 | return -EBUSY; | ||
455 | } | ||
456 | |||
457 | reg = RTC_BBCH_SEL | RTC_BBCH_EN; | ||
458 | tps6591x_write_regs(&pdev->dev, RTC_BBCH_REG, 1, ®); | ||
459 | if (err) { | ||
460 | dev_err(&pdev->dev, "unable to program Charger reg\n"); | ||
461 | return -EBUSY; | ||
462 | } | ||
463 | |||
464 | tps6591x_rtc_read_time(&pdev->dev, &tm); | ||
465 | if ((tm.tm_year < RTC_YEAR_OFFSET || tm.tm_year > (RTC_YEAR_OFFSET + 99))){ | ||
466 | if (pdata->time.tm_year < 2000 || pdata->time.tm_year > 2100) { | ||
467 | memset(&pdata->time, 0, sizeof(pdata->time)); | ||
468 | pdata->time.tm_year = RTC_YEAR_OFFSET; | ||
469 | pdata->time.tm_mday = 1; | ||
470 | } else | ||
471 | pdata->time.tm_year -= OS_REF_YEAR; | ||
472 | tps6591x_rtc_set_time(&pdev->dev, &pdata->time); | ||
473 | } | ||
474 | |||
475 | reg = ALARM_INT_STATUS; | ||
476 | err = tps6591x_write_regs(&pdev->dev, RTC_STATUS, 1, ®); | ||
477 | if (err) { | ||
478 | dev_err(&pdev->dev, "unable to program RTC_STATUS reg\n"); | ||
479 | return -EBUSY; | ||
480 | } | ||
481 | |||
482 | reg = ENABLE_ALARM_INT; | ||
483 | tps6591x_write_regs(&pdev->dev, RTC_INT, 1, ®); | ||
484 | if (err) { | ||
485 | dev_err(&pdev->dev, "unable to program Interrupt Mask reg\n"); | ||
486 | return -EBUSY; | ||
487 | } | ||
488 | |||
489 | if (pdata && (pdata->irq >= 0)) { | ||
490 | rtc->irq = pdata->irq; | ||
491 | err = request_threaded_irq(pdata->irq, NULL, tps6591x_rtc_irq, | ||
492 | IRQF_ONESHOT, "rtc_tps6591x", | ||
493 | &pdev->dev); | ||
494 | if (err) { | ||
495 | dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq); | ||
496 | rtc->irq = -1; | ||
497 | } else { | ||
498 | device_init_wakeup(&pdev->dev, 1); | ||
499 | enable_irq_wake(rtc->irq); | ||
500 | } | ||
501 | } | ||
502 | return 0; | ||
503 | |||
504 | fail: | ||
505 | if (!IS_ERR_OR_NULL(rtc->rtc)) | ||
506 | rtc_device_unregister(rtc->rtc); | ||
507 | kfree(rtc); | ||
508 | return err; | ||
509 | } | ||
510 | |||
511 | static int __devexit tps6591x_rtc_remove(struct platform_device *pdev) | ||
512 | { | ||
513 | struct tps6591x_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
514 | |||
515 | if (rtc->irq != -1) | ||
516 | free_irq(rtc->irq, rtc); | ||
517 | rtc_device_unregister(rtc->rtc); | ||
518 | kfree(rtc); | ||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static struct platform_driver tps6591x_rtc_driver = { | ||
523 | .driver = { | ||
524 | .name = "rtc_tps6591x", | ||
525 | .owner = THIS_MODULE, | ||
526 | }, | ||
527 | .probe = tps6591x_rtc_probe, | ||
528 | .remove = __devexit_p(tps6591x_rtc_remove), | ||
529 | }; | ||
530 | |||
531 | static int __init tps6591x_rtc_init(void) | ||
532 | { | ||
533 | return platform_driver_register(&tps6591x_rtc_driver); | ||
534 | } | ||
535 | module_init(tps6591x_rtc_init); | ||
536 | |||
537 | static void __exit tps6591x_rtc_exit(void) | ||
538 | { | ||
539 | platform_driver_unregister(&tps6591x_rtc_driver); | ||
540 | } | ||
541 | module_exit(tps6591x_rtc_exit); | ||
542 | |||
543 | MODULE_DESCRIPTION("TI TPS6591x RTC driver"); | ||
544 | MODULE_AUTHOR("NVIDIA Corporation"); | ||
545 | MODULE_LICENSE("GPL"); | ||
546 | MODULE_ALIAS("platform:rtc_tps6591x"); | ||
diff --git a/drivers/rtc/rtc-tps80031.c b/drivers/rtc/rtc-tps80031.c new file mode 100644 index 00000000000..70d6734a570 --- /dev/null +++ b/drivers/rtc/rtc-tps80031.c | |||
@@ -0,0 +1,449 @@ | |||
1 | /* | ||
2 | * drivers/rtc/rtc_tps80031.c | ||
3 | * | ||
4 | * RTC driver for TI TPS80031 | ||
5 | * | ||
6 | * Copyright (c) 2011, NVIDIA Corporation. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
21 | */ | ||
22 | |||
23 | /* #define DEBUG 1 */ | ||
24 | /* #define VERBOSE_DEBUG 1 */ | ||
25 | |||
26 | #include <linux/device.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/mfd/tps80031.h> | ||
31 | #include <linux/platform_device.h> | ||
32 | #include <linux/rtc.h> | ||
33 | #include <linux/slab.h> | ||
34 | |||
35 | #define RTC_CTRL 0x10 | ||
36 | #define RTC_STATUS 0x11 | ||
37 | #define RTC_SECONDS_REG 0x0 | ||
38 | #define RTC_ALARM 0x8 | ||
39 | #define RTC_INT 0x12 | ||
40 | #define RTC_RESET_STATUS 0x16 | ||
41 | |||
42 | #define ENABLE_ALARM_INT 0x8 | ||
43 | #define ALARM_INT_STATUS 0x40 | ||
44 | #define STOP_RTC 1 | ||
45 | |||
46 | /* Power on reset Values of RTC registers */ | ||
47 | #define RTC_POR_YEAR 0 | ||
48 | #define RTC_POR_MONTH 1 | ||
49 | #define RTC_POR_DAY 1 | ||
50 | |||
51 | /* | ||
52 | Linux RTC driver refers 19th centaury as base year in many | ||
53 | calculations. (e.g. refer drivers/rtc/rtc-lib.c) | ||
54 | */ | ||
55 | #define OS_REF_YEAR 1900 | ||
56 | |||
57 | /* | ||
58 | PMU RTC have only 2 nibbles to store year information, so using an | ||
59 | offset of 100 to set the base year as 2000 for our driver. | ||
60 | */ | ||
61 | #define RTC_YEAR_OFFSET 100 | ||
62 | |||
63 | struct tps80031_rtc { | ||
64 | unsigned long epoch_start; | ||
65 | int irq; | ||
66 | struct rtc_device *rtc; | ||
67 | u8 alarm_irq_enabled; | ||
68 | }; | ||
69 | |||
70 | static int tps80031_read_regs(struct device *dev, int reg, int len, | ||
71 | uint8_t *val) | ||
72 | { | ||
73 | int ret; | ||
74 | |||
75 | /* dummy read of STATUS_REG as per data sheet */ | ||
76 | ret = tps80031_reads(dev->parent, 1, RTC_STATUS, 1, val); | ||
77 | if (ret < 0) { | ||
78 | dev_err(dev->parent, "failed reading RTC_STATUS\n"); | ||
79 | WARN_ON(1); | ||
80 | return ret; | ||
81 | } | ||
82 | |||
83 | ret = tps80031_reads(dev->parent, 1, reg, len, val); | ||
84 | if (ret < 0) { | ||
85 | dev_err(dev->parent, "failed reading from reg %d\n", reg); | ||
86 | WARN_ON(1); | ||
87 | return ret; | ||
88 | } | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int tps80031_write_regs(struct device *dev, int reg, int len, | ||
93 | uint8_t *val) | ||
94 | { | ||
95 | int ret; | ||
96 | ret = tps80031_writes(dev->parent, 1, reg, len, val); | ||
97 | if (ret < 0) { | ||
98 | dev_err(dev->parent, "failed writing reg: %d\n", reg); | ||
99 | WARN_ON(1); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static u8 dec2bcd(u8 dec) | ||
107 | { | ||
108 | return ((dec/10)<<4)+(dec%10); | ||
109 | } | ||
110 | |||
111 | static u8 bcd2dec(u8 bcd) | ||
112 | { | ||
113 | return (bcd >> 4)*10+(bcd & 0xF); | ||
114 | } | ||
115 | |||
116 | static void convert_bcd_to_decimal(u8 *buf, u8 len) | ||
117 | { | ||
118 | int i = 0; | ||
119 | for (i = 0; i < len; i++) | ||
120 | buf[i] = bcd2dec(buf[i]); | ||
121 | } | ||
122 | |||
123 | static void convert_decimal_to_bcd(u8 *buf, u8 len) | ||
124 | { | ||
125 | int i = 0; | ||
126 | for (i = 0; i < len; i++) | ||
127 | buf[i] = dec2bcd(buf[i]); | ||
128 | } | ||
129 | |||
130 | static int tps80031_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
131 | { | ||
132 | u8 buff[7]; | ||
133 | int err; | ||
134 | err = tps80031_read_regs(dev, RTC_SECONDS_REG, sizeof(buff), buff); | ||
135 | if (err < 0) { | ||
136 | dev_err(dev->parent, "failed reading time\n"); | ||
137 | return err; | ||
138 | } | ||
139 | convert_bcd_to_decimal(buff, sizeof(buff)); | ||
140 | tm->tm_sec = buff[0]; | ||
141 | tm->tm_min = buff[1]; | ||
142 | tm->tm_hour = buff[2]; | ||
143 | tm->tm_mday = buff[3]; | ||
144 | tm->tm_mon = buff[4] - 1; | ||
145 | tm->tm_year = buff[5] + RTC_YEAR_OFFSET; | ||
146 | tm->tm_wday = buff[6]; | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int tps80031_rtc_stop(struct device *dev) | ||
151 | { | ||
152 | int err; | ||
153 | err = tps80031_clr_bits(dev->parent, 1, RTC_CTRL, STOP_RTC); | ||
154 | if (err < 0) | ||
155 | dev_err(dev->parent, "failed to stop RTC. err: %d\n", err); | ||
156 | return err; | ||
157 | } | ||
158 | |||
159 | static int tps80031_rtc_start(struct device *dev) | ||
160 | { | ||
161 | int err; | ||
162 | err = tps80031_set_bits(dev->parent, 1, RTC_CTRL, STOP_RTC); | ||
163 | if (err < 0) | ||
164 | dev_err(dev->parent, "failed to start RTC. err: %d\n", err); | ||
165 | return err; | ||
166 | } | ||
167 | |||
168 | |||
169 | static int tps80031_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
170 | { | ||
171 | u8 buff[7]; | ||
172 | int err; | ||
173 | |||
174 | buff[0] = tm->tm_sec; | ||
175 | buff[1] = tm->tm_min; | ||
176 | buff[2] = tm->tm_hour; | ||
177 | buff[3] = tm->tm_mday; | ||
178 | buff[4] = tm->tm_mon + 1; | ||
179 | buff[5] = tm->tm_year % RTC_YEAR_OFFSET; | ||
180 | buff[6] = tm->tm_wday; | ||
181 | |||
182 | convert_decimal_to_bcd(buff, sizeof(buff)); | ||
183 | err = tps80031_rtc_stop(dev); | ||
184 | if (err < 0) | ||
185 | return err; | ||
186 | |||
187 | err = tps80031_write_regs(dev, RTC_SECONDS_REG, sizeof(buff), buff); | ||
188 | if (err < 0) { | ||
189 | dev_err(dev->parent, "failed to program new time\n"); | ||
190 | return err; | ||
191 | } | ||
192 | |||
193 | err = tps80031_rtc_start(dev); | ||
194 | return err; | ||
195 | } | ||
196 | |||
197 | static int tps80031_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
198 | { | ||
199 | struct tps80031_rtc *rtc = dev_get_drvdata(dev); | ||
200 | unsigned long seconds; | ||
201 | u8 buff[6]; | ||
202 | int err; | ||
203 | struct rtc_time tm; | ||
204 | |||
205 | if (rtc->irq == -1) | ||
206 | return -EIO; | ||
207 | |||
208 | rtc_tm_to_time(&alrm->time, &seconds); | ||
209 | tps80031_rtc_read_time(dev, &tm); | ||
210 | rtc_tm_to_time(&tm, &rtc->epoch_start); | ||
211 | |||
212 | if (WARN_ON(alrm->enabled && (seconds < rtc->epoch_start))) { | ||
213 | dev_err(dev->parent, "can't set alarm to requested time\n"); | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | buff[0] = alrm->time.tm_sec; | ||
218 | buff[1] = alrm->time.tm_min; | ||
219 | buff[2] = alrm->time.tm_hour; | ||
220 | buff[3] = alrm->time.tm_mday; | ||
221 | buff[4] = alrm->time.tm_mon + 1; | ||
222 | buff[5] = alrm->time.tm_year % RTC_YEAR_OFFSET; | ||
223 | convert_decimal_to_bcd(buff, sizeof(buff)); | ||
224 | err = tps80031_write_regs(dev, RTC_ALARM, sizeof(buff), buff); | ||
225 | if (err) | ||
226 | dev_err(dev->parent, "unable to program alarm\n"); | ||
227 | |||
228 | return err; | ||
229 | } | ||
230 | |||
231 | static int tps80031_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
232 | { | ||
233 | u8 buff[6]; | ||
234 | int err; | ||
235 | |||
236 | err = tps80031_read_regs(dev, RTC_ALARM, sizeof(buff), buff); | ||
237 | if (err) | ||
238 | return err; | ||
239 | convert_bcd_to_decimal(buff, sizeof(buff)); | ||
240 | |||
241 | alrm->time.tm_sec = buff[0]; | ||
242 | alrm->time.tm_min = buff[1]; | ||
243 | alrm->time.tm_hour = buff[2]; | ||
244 | alrm->time.tm_mday = buff[3]; | ||
245 | alrm->time.tm_mon = buff[4] - 1; | ||
246 | alrm->time.tm_year = buff[5] + RTC_YEAR_OFFSET; | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static int tps80031_rtc_alarm_irq_enable(struct device *dev, | ||
252 | unsigned int enable) | ||
253 | { | ||
254 | struct tps80031_rtc *rtc = dev_get_drvdata(dev); | ||
255 | int err; | ||
256 | struct device *p = dev->parent; | ||
257 | |||
258 | if (rtc->irq == -1) | ||
259 | return -EIO; | ||
260 | |||
261 | if (enable) { | ||
262 | if (rtc->alarm_irq_enabled) | ||
263 | return 0; | ||
264 | |||
265 | err = tps80031_set_bits(p, 1, RTC_INT, ENABLE_ALARM_INT); | ||
266 | if (err < 0) { | ||
267 | dev_err(p, "failed to set ALRM int. err: %d\n", err); | ||
268 | return err; | ||
269 | } else | ||
270 | rtc->alarm_irq_enabled = 1; | ||
271 | } else { | ||
272 | if(!rtc->alarm_irq_enabled) | ||
273 | return 0; | ||
274 | err = tps80031_clr_bits(p, 1, RTC_INT, ENABLE_ALARM_INT); | ||
275 | if (err < 0) { | ||
276 | dev_err(p, "failed to clear ALRM int. err: %d\n", err); | ||
277 | return err; | ||
278 | } else | ||
279 | rtc->alarm_irq_enabled = 0; | ||
280 | } | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | static const struct rtc_class_ops tps80031_rtc_ops = { | ||
285 | .read_time = tps80031_rtc_read_time, | ||
286 | .set_time = tps80031_rtc_set_time, | ||
287 | .set_alarm = tps80031_rtc_set_alarm, | ||
288 | .read_alarm = tps80031_rtc_read_alarm, | ||
289 | .alarm_irq_enable = tps80031_rtc_alarm_irq_enable, | ||
290 | }; | ||
291 | |||
292 | static irqreturn_t tps80031_rtc_irq(int irq, void *data) | ||
293 | { | ||
294 | struct device *dev = data; | ||
295 | struct tps80031_rtc *rtc = dev_get_drvdata(dev); | ||
296 | u8 reg; | ||
297 | int err; | ||
298 | |||
299 | /* clear Alarm status bits.*/ | ||
300 | err = tps80031_read_regs(dev, RTC_STATUS, 1, ®); | ||
301 | if (err) { | ||
302 | dev_err(dev->parent, "unable to read RTC_STATUS reg\n"); | ||
303 | return -EBUSY; | ||
304 | } | ||
305 | |||
306 | err = tps80031_force_update(dev->parent, 1, RTC_STATUS, | ||
307 | ALARM_INT_STATUS, ALARM_INT_STATUS); | ||
308 | if (err) { | ||
309 | dev_err(dev->parent, "unable to set Alarm INT\n"); | ||
310 | return -EBUSY; | ||
311 | } | ||
312 | |||
313 | rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); | ||
314 | return IRQ_HANDLED; | ||
315 | } | ||
316 | |||
317 | static int __devinit tps80031_rtc_probe(struct platform_device *pdev) | ||
318 | { | ||
319 | struct tps80031_rtc_platform_data *pdata = pdev->dev.platform_data; | ||
320 | struct tps80031_rtc *rtc; | ||
321 | struct rtc_time tm; | ||
322 | int err; | ||
323 | u8 reg; | ||
324 | |||
325 | if (!pdata) { | ||
326 | dev_err(&pdev->dev, "no platform_data specified\n"); | ||
327 | return -EINVAL; | ||
328 | } | ||
329 | |||
330 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); | ||
331 | if (!rtc) | ||
332 | return -ENOMEM; | ||
333 | |||
334 | rtc->irq = -1; | ||
335 | if (pdata->irq < 0) | ||
336 | dev_err(&pdev->dev, "no IRQ specified, wakeup is disabled\n"); | ||
337 | |||
338 | rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
339 | &tps80031_rtc_ops, THIS_MODULE); | ||
340 | |||
341 | if (IS_ERR(rtc->rtc)) { | ||
342 | err = PTR_ERR(rtc->rtc); | ||
343 | goto fail; | ||
344 | } | ||
345 | |||
346 | if ((int)pdev && (int)&pdev->dev) | ||
347 | err = tps80031_read_regs(&pdev->dev, RTC_STATUS, 1, ®); | ||
348 | else { | ||
349 | dev_err(&pdev->dev, "%s Input params incorrect\n", __func__); | ||
350 | err = -EBUSY; | ||
351 | goto fail; | ||
352 | } | ||
353 | |||
354 | if (err) { | ||
355 | dev_err(&pdev->dev, "%s unable to read status\n", __func__); | ||
356 | err = -EBUSY; | ||
357 | goto fail; | ||
358 | } | ||
359 | |||
360 | /* If RTC have POR values, set time using platform data*/ | ||
361 | tps80031_rtc_read_time(&pdev->dev, &tm); | ||
362 | if ((tm.tm_year == RTC_YEAR_OFFSET + RTC_POR_YEAR) && | ||
363 | (tm.tm_mon == (RTC_POR_MONTH - 1)) && | ||
364 | (tm.tm_mday == RTC_POR_DAY)) { | ||
365 | if (pdata->time.tm_year < 2000 || | ||
366 | pdata->time.tm_year > 2100) { | ||
367 | dev_err(&pdev->dev, "Invalid platform data\n"); | ||
368 | memset(&pdata->time, 0, sizeof(pdata->time)); | ||
369 | pdata->time.tm_year = 2011; | ||
370 | pdata->time.tm_mday = 1; | ||
371 | } | ||
372 | tps80031_rtc_set_time(&pdev->dev, &pdata->time); | ||
373 | } | ||
374 | |||
375 | reg = ALARM_INT_STATUS; | ||
376 | err = tps80031_write_regs(&pdev->dev, RTC_STATUS, 1, ®); | ||
377 | if (err) { | ||
378 | dev_err(&pdev->dev, "unable to program RTC_STATUS reg\n"); | ||
379 | return -EBUSY; | ||
380 | } | ||
381 | |||
382 | err = tps80031_set_bits(pdev->dev.parent, 1, RTC_INT, ENABLE_ALARM_INT); | ||
383 | if (err) { | ||
384 | dev_err(&pdev->dev, "unable to program Interrupt Mask reg\n"); | ||
385 | err = -EBUSY; | ||
386 | rtc->alarm_irq_enabled = 0; | ||
387 | goto fail; | ||
388 | } else | ||
389 | rtc->alarm_irq_enabled = 1; | ||
390 | |||
391 | dev_set_drvdata(&pdev->dev, rtc); | ||
392 | if (pdata && (pdata->irq >= 0)) { | ||
393 | rtc->irq = pdata->irq; | ||
394 | err = request_threaded_irq(pdata->irq, NULL, tps80031_rtc_irq, | ||
395 | IRQF_ONESHOT, "rtc_tps80031", | ||
396 | &pdev->dev); | ||
397 | if (err) { | ||
398 | dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq); | ||
399 | rtc->irq = -1; | ||
400 | } else { | ||
401 | device_init_wakeup(&pdev->dev, 1); | ||
402 | enable_irq_wake(rtc->irq); | ||
403 | } | ||
404 | } | ||
405 | return 0; | ||
406 | |||
407 | fail: | ||
408 | if (!IS_ERR_OR_NULL(rtc->rtc)) | ||
409 | rtc_device_unregister(rtc->rtc); | ||
410 | kfree(rtc); | ||
411 | return err; | ||
412 | } | ||
413 | |||
414 | static int __devexit tps80031_rtc_remove(struct platform_device *pdev) | ||
415 | { | ||
416 | struct tps80031_rtc *rtc = dev_get_drvdata(&pdev->dev); | ||
417 | |||
418 | if (rtc->irq != -1) | ||
419 | free_irq(rtc->irq, rtc); | ||
420 | rtc_device_unregister(rtc->rtc); | ||
421 | kfree(rtc); | ||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static struct platform_driver tps80031_rtc_driver = { | ||
426 | .driver = { | ||
427 | .name = "rtc_tps80031", | ||
428 | .owner = THIS_MODULE, | ||
429 | }, | ||
430 | .probe = tps80031_rtc_probe, | ||
431 | .remove = __devexit_p(tps80031_rtc_remove), | ||
432 | }; | ||
433 | |||
434 | static int __init tps80031_rtc_init(void) | ||
435 | { | ||
436 | return platform_driver_register(&tps80031_rtc_driver); | ||
437 | } | ||
438 | module_init(tps80031_rtc_init); | ||
439 | |||
440 | static void __exit tps80031_rtc_exit(void) | ||
441 | { | ||
442 | platform_driver_unregister(&tps80031_rtc_driver); | ||
443 | } | ||
444 | module_exit(tps80031_rtc_exit); | ||
445 | |||
446 | MODULE_DESCRIPTION("TI TPS80031 RTC driver"); | ||
447 | MODULE_AUTHOR("NVIDIA Corporation"); | ||
448 | MODULE_LICENSE("GPL"); | ||
449 | MODULE_ALIAS("platform:rtc_tps80031"); | ||