rtc.h 9.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6
/*
 * Generic RTC interface.
 * This version contains the part of the user interface to the Real Time Clock
 * service. It is used with both the legacy mc146818 and also  EFI
 * Struct rtc_time and first 12 ioctl by Paul Gortmaker, 1996 - separated out
 * from <linux/mc146818rtc.h> to this file for 2.4 kernels.
7
 *
L
Linus Torvalds 已提交
8 9 10 11 12 13 14 15
 * Copyright (C) 1999 Hewlett-Packard Co.
 * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
 */
#ifndef _LINUX_RTC_H_
#define _LINUX_RTC_H_

/*
 * The struct used to pass data via the following ioctl. Similar to the
16
 * struct tm in <time.h>, but it needs to be here so that the kernel
L
Linus Torvalds 已提交
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
 * source is self contained, allowing cross-compiles, etc. etc.
 */

struct rtc_time {
	int tm_sec;
	int tm_min;
	int tm_hour;
	int tm_mday;
	int tm_mon;
	int tm_year;
	int tm_wday;
	int tm_yday;
	int tm_isdst;
};

/*
 * This data structure is inspired by the EFI (v0.92) wakeup
 * alarm API.
 */
struct rtc_wkalrm {
37 38
	unsigned char enabled;	/* 0 = alarm disabled, 1 = alarm enabled */
	unsigned char pending;  /* 0 = alarm not pending, 1 = alarm pending */
L
Linus Torvalds 已提交
39 40 41 42 43 44 45 46 47 48 49 50 51 52
	struct rtc_time time;	/* time the alarm is set to */
};

/*
 * Data structure to control PLL correction some better RTC feature
 * pll_value is used to get or set current value of correction,
 * the rest of the struct is used to query HW capabilities.
 * This is modeled after the RTC used in Q40/Q60 computers but
 * should be sufficiently flexible for other devices
 *
 * +ve pll_value means clock will run faster by
 *   pll_value*pll_posmult/pll_clock
 * -ve pll_value means clock will run slower by
 *   pll_value*pll_negmult/pll_clock
53
 */
L
Linus Torvalds 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

struct rtc_pll_info {
	int pll_ctrl;       /* placeholder for fancier control */
	int pll_value;      /* get/set correction value */
	int pll_max;        /* max +ve (faster) adjustment value */
	int pll_min;        /* max -ve (slower) adjustment value */
	int pll_posmult;    /* factor for +ve correction */
	int pll_negmult;    /* factor for -ve correction */
	long pll_clock;     /* base PLL frequency */
};

/*
 * ioctl calls that are permitted to the /dev/rtc interface, if
 * any of the RTC drivers are enabled.
 */

#define RTC_AIE_ON	_IO('p', 0x01)	/* Alarm int. enable on		*/
#define RTC_AIE_OFF	_IO('p', 0x02)	/* ... off			*/
#define RTC_UIE_ON	_IO('p', 0x03)	/* Update int. enable on	*/
#define RTC_UIE_OFF	_IO('p', 0x04)	/* ... off			*/
#define RTC_PIE_ON	_IO('p', 0x05)	/* Periodic int. enable on	*/
#define RTC_PIE_OFF	_IO('p', 0x06)	/* ... off			*/
#define RTC_WIE_ON	_IO('p', 0x0f)  /* Watchdog int. enable on	*/
#define RTC_WIE_OFF	_IO('p', 0x10)  /* ... off			*/

#define RTC_ALM_SET	_IOW('p', 0x07, struct rtc_time) /* Set alarm time  */
#define RTC_ALM_READ	_IOR('p', 0x08, struct rtc_time) /* Read alarm time */
#define RTC_RD_TIME	_IOR('p', 0x09, struct rtc_time) /* Read RTC time   */
#define RTC_SET_TIME	_IOW('p', 0x0a, struct rtc_time) /* Set RTC time    */
#define RTC_IRQP_READ	_IOR('p', 0x0b, unsigned long)	 /* Read IRQ rate   */
#define RTC_IRQP_SET	_IOW('p', 0x0c, unsigned long)	 /* Set IRQ rate    */
#define RTC_EPOCH_READ	_IOR('p', 0x0d, unsigned long)	 /* Read epoch      */
#define RTC_EPOCH_SET	_IOW('p', 0x0e, unsigned long)	 /* Set epoch       */

#define RTC_WKALM_SET	_IOW('p', 0x0f, struct rtc_wkalrm)/* Set wakeup alarm*/
#define RTC_WKALM_RD	_IOR('p', 0x10, struct rtc_wkalrm)/* Get wakeup alarm*/

#define RTC_PLL_GET	_IOR('p', 0x11, struct rtc_pll_info)  /* Get PLL correction */
#define RTC_PLL_SET	_IOW('p', 0x12, struct rtc_pll_info)  /* Set PLL correction */

A
Alessandro Zummo 已提交
94
/* interrupt flags */
95 96 97 98
#define RTC_IRQF 0x80	/* Any of the following is active */
#define RTC_PF 0x40	/* Periodic interrupt */
#define RTC_AF 0x20	/* Alarm interrupt */
#define RTC_UF 0x10	/* Update interrupt for 1Hz RTC */
A
Alessandro Zummo 已提交
99

J
John Stultz 已提交
100 101 102

#define RTC_MAX_FREQ	8192

L
Linus Torvalds 已提交
103 104
#ifdef __KERNEL__

105
#include <linux/types.h>
J
Joe Korty 已提交
106 107
#include <linux/interrupt.h>

108
extern int rtc_month_days(unsigned int month, unsigned int year);
109
extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int year);
110 111 112
extern int rtc_valid_tm(struct rtc_time *tm);
extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time);
extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm);
113 114 115
ktime_t rtc_tm_to_ktime(struct rtc_time tm);
struct rtc_time rtc_ktime_to_tm(ktime_t kt);

116

A
Alessandro Zummo 已提交
117 118 119 120 121
#include <linux/device.h>
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/mutex.h>
122 123
#include <linux/timerqueue.h>
#include <linux/workqueue.h>
A
Alessandro Zummo 已提交
124 125 126

extern struct class *rtc_class;

D
David Brownell 已提交
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/*
 * For these RTC methods the device parameter is the physical device
 * on whatever bus holds the hardware (I2C, Platform, SPI, etc), which
 * was passed to rtc_device_register().  Its driver_data normally holds
 * device state, including the rtc_device pointer for the RTC.
 *
 * Most of these methods are called with rtc_device.ops_lock held,
 * through the rtc_*(struct rtc_device *, ...) calls.
 *
 * The (current) exceptions are mostly filesystem hooks:
 *   - the proc() hook for procfs
 *   - non-ioctl() chardev hooks:  open(), release(), read_callback()
 *
 * REVISIT those periodic irq calls *do* have ops_lock when they're
 * issued through ioctl() ...
 */
A
Alessandro Zummo 已提交
143 144 145 146 147 148 149 150 151 152 153
struct rtc_class_ops {
	int (*open)(struct device *);
	void (*release)(struct device *);
	int (*ioctl)(struct device *, unsigned int, unsigned long);
	int (*read_time)(struct device *, struct rtc_time *);
	int (*set_time)(struct device *, struct rtc_time *);
	int (*read_alarm)(struct device *, struct rtc_wkalrm *);
	int (*set_alarm)(struct device *, struct rtc_wkalrm *);
	int (*proc)(struct device *, struct seq_file *);
	int (*set_mmss)(struct device *, unsigned long secs);
	int (*read_callback)(struct device *, int data);
154
	int (*alarm_irq_enable)(struct device *, unsigned int enabled);
A
Alessandro Zummo 已提交
155 156 157
};

#define RTC_DEVICE_NAME_SIZE 20
158 159 160 161 162 163 164 165 166 167 168 169 170
typedef struct rtc_task {
	void (*func)(void *private_data);
	void *private_data;
} rtc_task_t;


struct rtc_timer {
	struct rtc_task	task;
	struct timerqueue_node node;
	ktime_t period;
	int enabled;
};

A
Alessandro Zummo 已提交
171

J
Jiri Kosina 已提交
172 173 174
/* flags */
#define RTC_DEV_BUSY 0

A
Alessandro Zummo 已提交
175 176
struct rtc_device
{
177
	struct device dev;
A
Alessandro Zummo 已提交
178 179 180 181 182
	struct module *owner;

	int id;
	char name[RTC_DEVICE_NAME_SIZE];

183
	const struct rtc_class_ops *ops;
A
Alessandro Zummo 已提交
184 185 186
	struct mutex ops_lock;

	struct cdev char_dev;
J
Jiri Kosina 已提交
187
	unsigned long flags;
A
Alessandro Zummo 已提交
188 189 190 191 192 193 194 195 196

	unsigned long irq_data;
	spinlock_t irq_lock;
	wait_queue_head_t irq_queue;
	struct fasync_struct *async_queue;

	struct rtc_task *irq_task;
	spinlock_t irq_task_lock;
	int irq_freq;
197
	int max_user_freq;
198 199 200 201 202 203 204

	struct timerqueue_head timerqueue;
	struct rtc_timer aie_timer;
	struct rtc_timer uie_rtctimer;
	struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */
	int pie_enabled;
	struct work_struct irqwork;
J
John Stultz 已提交
205 206 207 208 209 210 211 212 213 214 215 216


#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
	struct work_struct uie_task;
	struct timer_list uie_timer;
	/* Those fields are protected by rtc->irq_lock */
	unsigned int oldsecs;
	unsigned int uie_irq_active:1;
	unsigned int stop_uie_polling:1;
	unsigned int uie_task_active:1;
	unsigned int uie_timer_active:1;
#endif
A
Alessandro Zummo 已提交
217
};
218
#define to_rtc_device(d) container_of(d, struct rtc_device, dev)
A
Alessandro Zummo 已提交
219 220 221

extern struct rtc_device *rtc_device_register(const char *name,
					struct device *dev,
222
					const struct rtc_class_ops *ops,
A
Alessandro Zummo 已提交
223
					struct module *owner);
224
extern void rtc_device_unregister(struct rtc_device *rtc);
A
Alessandro Zummo 已提交
225

226 227 228
extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs);
229
int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);
230
extern int rtc_read_alarm(struct rtc_device *rtc,
A
Alessandro Zummo 已提交
231
			struct rtc_wkalrm *alrm);
232
extern int rtc_set_alarm(struct rtc_device *rtc,
A
Alessandro Zummo 已提交
233
				struct rtc_wkalrm *alrm);
234 235
extern int rtc_initialize_alarm(struct rtc_device *rtc,
				struct rtc_wkalrm *alrm);
236
extern void rtc_update_irq(struct rtc_device *rtc,
A
Alessandro Zummo 已提交
237 238
			unsigned long num, unsigned long events);

239 240
extern struct rtc_device *rtc_class_open(char *name);
extern void rtc_class_close(struct rtc_device *rtc);
A
Alessandro Zummo 已提交
241

242
extern int rtc_irq_register(struct rtc_device *rtc,
A
Alessandro Zummo 已提交
243
				struct rtc_task *task);
244
extern void rtc_irq_unregister(struct rtc_device *rtc,
A
Alessandro Zummo 已提交
245
				struct rtc_task *task);
246
extern int rtc_irq_set_state(struct rtc_device *rtc,
A
Alessandro Zummo 已提交
247
				struct rtc_task *task, int enabled);
248
extern int rtc_irq_set_freq(struct rtc_device *rtc,
A
Alessandro Zummo 已提交
249
				struct rtc_task *task, int freq);
250 251
extern int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled);
extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled);
J
John Stultz 已提交
252 253
extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc,
						unsigned int enabled);
A
Alessandro Zummo 已提交
254

255
void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode);
256 257 258
void rtc_aie_update_irq(void *private);
void rtc_uie_update_irq(void *private);
enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer);
L
Linus Torvalds 已提交
259 260 261 262 263

int rtc_register(rtc_task_t *task);
int rtc_unregister(rtc_task_t *task);
int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg);

T
Thomas Gleixner 已提交
264 265
void rtc_timer_init(struct rtc_timer *timer, void (*f)(void* p), void* data);
int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer,
266
			ktime_t expires, ktime_t period);
T
Thomas Gleixner 已提交
267 268
int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer);
void rtc_timer_do_work(struct work_struct *work);
269

270 271 272 273 274
static inline bool is_leap_year(unsigned int year)
{
	return (!(year % 4) && (year % 100)) || !(year % 400);
}

275 276 277 278 279 280
#ifdef CONFIG_RTC_HCTOSYS
extern int rtc_hctosys_ret;
#else
#define rtc_hctosys_ret -ENODEV
#endif

L
Linus Torvalds 已提交
281 282 283
#endif /* __KERNEL__ */

#endif /* _LINUX_RTC_H_ */