drivers: power: report battery voltage in AOSP compatible format
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / android / alarm-dev.c
CommitLineData
841cb11c
AH
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
6fa3eb70
S
16#ifdef pr_fmt
17#undef pr_fmt
18#endif
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
d47908b2 20#include <linux/time.h>
bf647ea7 21#include <linux/module.h>
841cb11c
AH
22#include <linux/device.h>
23#include <linux/miscdevice.h>
24#include <linux/fs.h>
25#include <linux/platform_device.h>
26#include <linux/sched.h>
27#include <linux/spinlock.h>
841cb11c 28#include <linux/uaccess.h>
b8793260 29#include <linux/alarmtimer.h>
841cb11c 30#include "android_alarm.h"
6fa3eb70
S
31#include <linux/xlog.h>
32#include <linux/ioctl.h>
33#define LOG_MYTAG "Power/Alarm"
841cb11c
AH
34
35#define ANDROID_ALARM_PRINT_INFO (1U << 0)
36#define ANDROID_ALARM_PRINT_IO (1U << 1)
37#define ANDROID_ALARM_PRINT_INT (1U << 2)
38
39static int debug_mask = ANDROID_ALARM_PRINT_INFO;
40module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
41
6fa3eb70 42#define alarm_dbg(debug_level_mask, fmt, args...) \
8a7245ea
JP
43do { \
44 if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask) \
6fa3eb70 45 xlog_printk(ANDROID_LOG_INFO, LOG_MYTAG, fmt, ##args); \
8a7245ea 46} while (0)
841cb11c
AH
47
48#define ANDROID_ALARM_WAKEUP_MASK ( \
49 ANDROID_ALARM_RTC_WAKEUP_MASK | \
50 ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
51
841cb11c
AH
52static int alarm_opened;
53static DEFINE_SPINLOCK(alarm_slock);
a180c0d6 54static struct wakeup_source alarm_wake_lock;
841cb11c
AH
55static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue);
56static uint32_t alarm_pending;
57static uint32_t alarm_enabled;
58static uint32_t wait_pending;
59
b8793260
JS
60struct devalarm {
61 union {
62 struct hrtimer hrt;
63 struct alarm alrm;
64 } u;
65 enum android_alarm_type type;
66};
67
68static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT];
69
70
71static int is_wakeup(enum android_alarm_type type)
72{
147cd165
DK
73 return (type == ANDROID_ALARM_RTC_WAKEUP ||
74 type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP);
b8793260
JS
75}
76
77
78static void devalarm_start(struct devalarm *alrm, ktime_t exp)
79{
80 if (is_wakeup(alrm->type))
81 alarm_start(&alrm->u.alrm, exp);
82 else
83 hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS);
84}
85
86
87static int devalarm_try_to_cancel(struct devalarm *alrm)
88{
b8793260 89 if (is_wakeup(alrm->type))
147cd165
DK
90 return alarm_try_to_cancel(&alrm->u.alrm);
91 return hrtimer_try_to_cancel(&alrm->u.hrt);
b8793260
JS
92}
93
94static void devalarm_cancel(struct devalarm *alrm)
95{
96 if (is_wakeup(alrm->type))
97 alarm_cancel(&alrm->u.alrm);
98 else
99 hrtimer_cancel(&alrm->u.hrt);
100}
101
6fa3eb70
S
102static void alarm_clear(enum android_alarm_type alarm_type,
103 struct timespec *ts)
cec8bb73
JS
104{
105 uint32_t alarm_type_mask = 1U << alarm_type;
106 unsigned long flags;
6fa3eb70
S
107
108
cec8bb73 109 alarm_dbg(IO, "alarm %d clear\n", alarm_type);
6fa3eb70
S
110 if (alarm_type == ANDROID_ALARM_POWER_ON ||
111 alarm_type == ANDROID_ALARM_POWER_ON_LOGO) {
112 ts->tv_sec = 0;
113 alarm_set_power_on(*ts, false);
114 return;
115 }
116 spin_lock_irqsave(&alarm_slock, flags);
cec8bb73
JS
117 devalarm_try_to_cancel(&alarms[alarm_type]);
118 if (alarm_pending) {
119 alarm_pending &= ~alarm_type_mask;
120 if (!alarm_pending && !wait_pending)
121 __pm_relax(&alarm_wake_lock);
122 }
123 alarm_enabled &= ~alarm_type_mask;
124 spin_unlock_irqrestore(&alarm_slock, flags);
125
126}
127
128static void alarm_set(enum android_alarm_type alarm_type,
129 struct timespec *ts)
841cb11c 130{
cec8bb73 131 uint32_t alarm_type_mask = 1U << alarm_type;
841cb11c 132 unsigned long flags;
cec8bb73 133
6fa3eb70 134 alarm_dbg(INFO, "alarm %d set %ld.%09ld\n",
cec8bb73 135 alarm_type, ts->tv_sec, ts->tv_nsec);
6fa3eb70
S
136 if (alarm_type == ANDROID_ALARM_POWER_ON) {
137 alarm_set_power_on(*ts, false);
138 return;
139 }
140 if (alarm_type == ANDROID_ALARM_POWER_ON_LOGO) {
141 alarm_set_power_on(*ts, true);
142 return;
143 }
144
145 spin_lock_irqsave(&alarm_slock, flags);
cec8bb73
JS
146 alarm_enabled |= alarm_type_mask;
147 devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts));
148 spin_unlock_irqrestore(&alarm_slock, flags);
149}
150
151static int alarm_wait(void)
152{
153 unsigned long flags;
154 int rv = 0;
155
156 spin_lock_irqsave(&alarm_slock, flags);
157 alarm_dbg(IO, "alarm wait\n");
158 if (!alarm_pending && wait_pending) {
159 __pm_relax(&alarm_wake_lock);
160 wait_pending = 0;
161 }
162 spin_unlock_irqrestore(&alarm_slock, flags);
163
164 rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
165 if (rv)
166 return rv;
167
168 spin_lock_irqsave(&alarm_slock, flags);
169 rv = alarm_pending;
170 wait_pending = 1;
171 alarm_pending = 0;
172 spin_unlock_irqrestore(&alarm_slock, flags);
173
174 return rv;
175}
176
177static int alarm_set_rtc(struct timespec *ts)
178{
b8793260
JS
179 struct rtc_time new_rtc_tm;
180 struct rtc_device *rtc_dev;
cec8bb73
JS
181 unsigned long flags;
182 int rv = 0;
183
184 rtc_time_to_tm(ts->tv_sec, &new_rtc_tm);
6fa3eb70
S
185 alarm_dbg(INFO, "set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d\n",
186 ts->tv_sec, ts->tv_nsec,
187 new_rtc_tm.tm_hour, new_rtc_tm.tm_min,
188 new_rtc_tm.tm_sec, new_rtc_tm.tm_mon + 1,
189 new_rtc_tm.tm_mday,
190 new_rtc_tm.tm_year + 1900);
cec8bb73
JS
191 rtc_dev = alarmtimer_get_rtcdev();
192 rv = do_settimeofday(ts);
193 if (rv < 0)
194 return rv;
195 if (rtc_dev)
196 rv = rtc_set_time(rtc_dev, &new_rtc_tm);
197
198 spin_lock_irqsave(&alarm_slock, flags);
199 alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
200 wake_up(&alarm_wait_queue);
201 spin_unlock_irqrestore(&alarm_slock, flags);
202
203 return rv;
204}
205
206static int alarm_get_time(enum android_alarm_type alarm_type,
207 struct timespec *ts)
208{
209 int rv = 0;
210
211 switch (alarm_type) {
212 case ANDROID_ALARM_RTC_WAKEUP:
213 case ANDROID_ALARM_RTC:
214 getnstimeofday(ts);
215 break;
216 case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
217 case ANDROID_ALARM_ELAPSED_REALTIME:
218 get_monotonic_boottime(ts);
219 break;
220 case ANDROID_ALARM_SYSTEMTIME:
221 ktime_get_ts(ts);
222 break;
6fa3eb70
S
223 case ANDROID_ALARM_POWER_ON:
224 case ANDROID_ALARM_POWER_ON_LOGO:
225 break;
cec8bb73
JS
226 default:
227 rv = -EINVAL;
228 }
229 return rv;
230}
231
232static long alarm_do_ioctl(struct file *file, unsigned int cmd,
6fa3eb70 233 struct timespec *ts, struct rtc_wkalrm *alm)
cec8bb73
JS
234{
235 int rv = 0;
236 unsigned long flags;
841cb11c 237 enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
841cb11c 238
6fa3eb70
S
239 if (alarm_type >= ANDROID_ALARM_TYPE_COUNT &&
240 alarm_type != ANDROID_ALARM_POWER_ON &&
241 alarm_type != ANDROID_ALARM_POWER_ON_LOGO) {
841cb11c 242 return -EINVAL;
6fa3eb70
S
243 }
244 if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)
245 && ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_IPO(0)
246 && ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_POWER_ON_IPO) {
841cb11c
AH
247 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
248 return -EPERM;
249 if (file->private_data == NULL &&
250 cmd != ANDROID_ALARM_SET_RTC) {
251 spin_lock_irqsave(&alarm_slock, flags);
252 if (alarm_opened) {
253 spin_unlock_irqrestore(&alarm_slock, flags);
254 return -EBUSY;
255 }
256 alarm_opened = 1;
257 file->private_data = (void *)1;
258 spin_unlock_irqrestore(&alarm_slock, flags);
259 }
260 }
261
262 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
263 case ANDROID_ALARM_CLEAR(0):
6fa3eb70 264 alarm_clear(alarm_type, ts);
841cb11c 265 break;
841cb11c 266 case ANDROID_ALARM_SET(0):
cec8bb73
JS
267 alarm_set(alarm_type, ts);
268 break;
269 case ANDROID_ALARM_SET_AND_WAIT(0):
270 alarm_set(alarm_type, ts);
841cb11c
AH
271 /* fall though */
272 case ANDROID_ALARM_WAIT:
cec8bb73 273 rv = alarm_wait();
841cb11c 274 break;
6fa3eb70
S
275 case ANDROID_ALARM_SET_IPO(0):
276 alarm_set(alarm_type, ts);
277 break;
278 case ANDROID_ALARM_SET_AND_WAIT_IPO(0):
279 alarm_set(alarm_type, ts);
280 /* fall though */
281 case ANDROID_ALARM_WAIT_IPO:
282 rv = alarm_wait();
283 break;
841cb11c 284 case ANDROID_ALARM_SET_RTC:
cec8bb73 285 rv = alarm_set_rtc(ts);
841cb11c
AH
286 break;
287 case ANDROID_ALARM_GET_TIME(0):
cec8bb73 288 rv = alarm_get_time(alarm_type, ts);
841cb11c 289 break;
6fa3eb70
S
290 case ANDROID_ALARM_GET_POWER_ON:
291 alarm_get_power_on(alm);
292 break;
293 case ANDROID_ALARM_GET_POWER_ON_IPO:
294 alarm_get_power_on(alm);
295 break;
296
841cb11c
AH
297 default:
298 rv = -EINVAL;
841cb11c 299 }
cec8bb73
JS
300 return rv;
301}
302
303static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
304{
305
306 struct timespec ts;
6fa3eb70
S
307 struct rtc_wkalrm pwron_alm;
308
cec8bb73
JS
309 int rv;
310
311 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
312 case ANDROID_ALARM_SET_AND_WAIT(0):
313 case ANDROID_ALARM_SET(0):
314 case ANDROID_ALARM_SET_RTC:
6fa3eb70 315 case ANDROID_ALARM_SET_IPO(0):
cec8bb73
JS
316 if (copy_from_user(&ts, (void __user *)arg, sizeof(ts)))
317 return -EFAULT;
318 break;
319 }
320
6fa3eb70 321 rv = alarm_do_ioctl(file, cmd, &ts, &pwron_alm);
e919b86c
DC
322 if (rv)
323 return rv;
cec8bb73
JS
324
325 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
326 case ANDROID_ALARM_GET_TIME(0):
327 if (copy_to_user((void __user *)arg, &ts, sizeof(ts)))
328 return -EFAULT;
329 break;
6fa3eb70
S
330 case ANDROID_ALARM_GET_POWER_ON:
331 case ANDROID_ALARM_GET_POWER_ON_IPO:
332 if (copy_to_user((void __user *)arg, &pwron_alm,
333 sizeof(struct rtc_wkalrm))) {
334 rv = -EFAULT;
335 return rv;
336 }
337 break;
338 default :
339 break;
cec8bb73
JS
340 }
341
e919b86c 342 return 0;
841cb11c 343}
532572b9
JS
344#ifdef CONFIG_COMPAT
345static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
346 unsigned long arg)
347{
348
349 struct timespec ts;
6fa3eb70 350 struct rtc_wkalrm pwron_alm;
532572b9
JS
351 int rv;
352
353 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
354 case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0):
355 case ANDROID_ALARM_SET_COMPAT(0):
356 case ANDROID_ALARM_SET_RTC_COMPAT:
6fa3eb70 357 case ANDROID_ALARM_SET_IPO_COMPAT(0):
532572b9
JS
358 if (compat_get_timespec(&ts, (void __user *)arg))
359 return -EFAULT;
360 /* fall through */
361 case ANDROID_ALARM_GET_TIME_COMPAT(0):
362 cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd);
363 break;
364 }
365
6fa3eb70 366 rv = alarm_do_ioctl(file, cmd, &ts, &pwron_alm);
60bba385
DC
367 if (rv)
368 return rv;
532572b9
JS
369
370 switch (ANDROID_ALARM_BASE_CMD(cmd)) {
371 case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */
372 if (compat_put_timespec(&ts, (void __user *)arg))
373 return -EFAULT;
374 break;
6fa3eb70
S
375
376 case ANDROID_ALARM_GET_POWER_ON:
377 case ANDROID_ALARM_GET_POWER_ON_IPO:
378 if (copy_to_user((void __user *)arg, &pwron_alm,
379 sizeof(struct rtc_wkalrm))) {
380 rv = -EFAULT;
381 return rv;
382 }
383 break;
532572b9 384
6fa3eb70 385 }
60bba385 386 return 0;
532572b9
JS
387}
388#endif
841cb11c
AH
389
390static int alarm_open(struct inode *inode, struct file *file)
391{
392 file->private_data = NULL;
6fa3eb70 393 alarm_dbg(INFO, "alarm_open (%d:%d)\n", current->tgid, current->pid);
841cb11c
AH
394 return 0;
395}
396
397static int alarm_release(struct inode *inode, struct file *file)
398{
399 int i;
400 unsigned long flags;
401
402 spin_lock_irqsave(&alarm_slock, flags);
592314e9 403 if (file->private_data) {
841cb11c
AH
404 for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
405 uint32_t alarm_type_mask = 1U << i;
406 if (alarm_enabled & alarm_type_mask) {
8a7245ea
JP
407 alarm_dbg(INFO,
408 "%s: clear alarm, pending %d\n",
409 __func__,
410 !!(alarm_pending & alarm_type_mask));
841cb11c
AH
411 alarm_enabled &= ~alarm_type_mask;
412 }
413 spin_unlock_irqrestore(&alarm_slock, flags);
b8793260 414 devalarm_cancel(&alarms[i]);
841cb11c
AH
415 spin_lock_irqsave(&alarm_slock, flags);
416 }
417 if (alarm_pending | wait_pending) {
418 if (alarm_pending)
8a7245ea
JP
419 alarm_dbg(INFO, "%s: clear pending alarms %x\n",
420 __func__, alarm_pending);
a180c0d6 421 __pm_relax(&alarm_wake_lock);
841cb11c
AH
422 wait_pending = 0;
423 alarm_pending = 0;
424 }
425 alarm_opened = 0;
426 }
427 spin_unlock_irqrestore(&alarm_slock, flags);
6fa3eb70
S
428 alarm_dbg(INFO, "alarm_release (%d:%d)(%lu)\n",
429 current->tgid, current->pid, (uintptr_t)file->private_data);
841cb11c
AH
430 return 0;
431}
432
b8793260 433static void devalarm_triggered(struct devalarm *alarm)
841cb11c
AH
434{
435 unsigned long flags;
436 uint32_t alarm_type_mask = 1U << alarm->type;
437
8a7245ea 438 alarm_dbg(INT, "%s: type %d\n", __func__, alarm->type);
841cb11c
AH
439 spin_lock_irqsave(&alarm_slock, flags);
440 if (alarm_enabled & alarm_type_mask) {
a180c0d6 441 __pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */
841cb11c
AH
442 alarm_enabled &= ~alarm_type_mask;
443 alarm_pending |= alarm_type_mask;
444 wake_up(&alarm_wait_queue);
445 }
446 spin_unlock_irqrestore(&alarm_slock, flags);
447}
448
b8793260
JS
449
450static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt)
451{
452 struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt);
453
6fa3eb70 454 alarm_dbg(INT, "devalarm_hrthandler\n");
b8793260
JS
455 devalarm_triggered(devalrm);
456 return HRTIMER_NORESTART;
457}
458
459static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm,
460 ktime_t now)
461{
462 struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm);
463
6fa3eb70 464 alarm_dbg(INT, "devalarm_alarmhandler\n");
b8793260
JS
465 devalarm_triggered(devalrm);
466 return ALARMTIMER_NORESTART;
467}
468
469
841cb11c
AH
470static const struct file_operations alarm_fops = {
471 .owner = THIS_MODULE,
472 .unlocked_ioctl = alarm_ioctl,
473 .open = alarm_open,
474 .release = alarm_release,
532572b9
JS
475#ifdef CONFIG_COMPAT
476 .compat_ioctl = alarm_compat_ioctl,
477#endif
841cb11c
AH
478};
479
480static struct miscdevice alarm_device = {
481 .minor = MISC_DYNAMIC_MINOR,
482 .name = "alarm",
483 .fops = &alarm_fops,
484};
485
486static int __init alarm_dev_init(void)
487{
488 int err;
489 int i;
490
491 err = misc_register(&alarm_device);
492 if (err)
493 return err;
494
b8793260
JS
495 alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm,
496 ALARM_REALTIME, devalarm_alarmhandler);
497 hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt,
498 CLOCK_REALTIME, HRTIMER_MODE_ABS);
499 alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm,
500 ALARM_BOOTTIME, devalarm_alarmhandler);
501 hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt,
502 CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
503 hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt,
504 CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
505
506 for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
507 alarms[i].type = i;
508 if (!is_wakeup(i))
509 alarms[i].u.hrt.function = devalarm_hrthandler;
510 }
511
a180c0d6 512 wakeup_source_init(&alarm_wake_lock, "alarm");
841cb11c
AH
513 return 0;
514}
515
516static void __exit alarm_dev_exit(void)
517{
518 misc_deregister(&alarm_device);
a180c0d6 519 wakeup_source_trash(&alarm_wake_lock);
841cb11c
AH
520}
521
522module_init(alarm_dev_init);
523module_exit(alarm_dev_exit);
524