xref: /openbmc/linux/drivers/rtc/rtc-test.c (revision a95579cd)
1a95579cdSAlessandro Zummo /*
2a95579cdSAlessandro Zummo  * An RTC test device/driver
3a95579cdSAlessandro Zummo  * Copyright (C) 2005 Tower Technologies
4a95579cdSAlessandro Zummo  * Author: Alessandro Zummo <a.zummo@towertech.it>
5a95579cdSAlessandro Zummo  *
6a95579cdSAlessandro Zummo  * This program is free software; you can redistribute it and/or modify
7a95579cdSAlessandro Zummo  * it under the terms of the GNU General Public License version 2 as
8a95579cdSAlessandro Zummo  * published by the Free Software Foundation.
9a95579cdSAlessandro Zummo  */
10a95579cdSAlessandro Zummo 
11a95579cdSAlessandro Zummo #include <linux/module.h>
12a95579cdSAlessandro Zummo #include <linux/err.h>
13a95579cdSAlessandro Zummo #include <linux/rtc.h>
14a95579cdSAlessandro Zummo #include <linux/platform_device.h>
15a95579cdSAlessandro Zummo 
16a95579cdSAlessandro Zummo static struct platform_device *test0 = NULL, *test1 = NULL;
17a95579cdSAlessandro Zummo 
18a95579cdSAlessandro Zummo static int test_rtc_read_alarm(struct device *dev,
19a95579cdSAlessandro Zummo 	struct rtc_wkalrm *alrm)
20a95579cdSAlessandro Zummo {
21a95579cdSAlessandro Zummo 	return 0;
22a95579cdSAlessandro Zummo }
23a95579cdSAlessandro Zummo 
24a95579cdSAlessandro Zummo static int test_rtc_set_alarm(struct device *dev,
25a95579cdSAlessandro Zummo 	struct rtc_wkalrm *alrm)
26a95579cdSAlessandro Zummo {
27a95579cdSAlessandro Zummo 	return 0;
28a95579cdSAlessandro Zummo }
29a95579cdSAlessandro Zummo 
30a95579cdSAlessandro Zummo static int test_rtc_read_time(struct device *dev,
31a95579cdSAlessandro Zummo 	struct rtc_time *tm)
32a95579cdSAlessandro Zummo {
33a95579cdSAlessandro Zummo 	rtc_time_to_tm(get_seconds(), tm);
34a95579cdSAlessandro Zummo 	return 0;
35a95579cdSAlessandro Zummo }
36a95579cdSAlessandro Zummo 
37a95579cdSAlessandro Zummo static int test_rtc_set_time(struct device *dev,
38a95579cdSAlessandro Zummo 	struct rtc_time *tm)
39a95579cdSAlessandro Zummo {
40a95579cdSAlessandro Zummo 	return 0;
41a95579cdSAlessandro Zummo }
42a95579cdSAlessandro Zummo 
43a95579cdSAlessandro Zummo static int test_rtc_set_mmss(struct device *dev, unsigned long secs)
44a95579cdSAlessandro Zummo {
45a95579cdSAlessandro Zummo 	return 0;
46a95579cdSAlessandro Zummo }
47a95579cdSAlessandro Zummo 
48a95579cdSAlessandro Zummo static int test_rtc_proc(struct device *dev, struct seq_file *seq)
49a95579cdSAlessandro Zummo {
50a95579cdSAlessandro Zummo 	struct platform_device *plat_dev = to_platform_device(dev);
51a95579cdSAlessandro Zummo 
52a95579cdSAlessandro Zummo 	seq_printf(seq, "24hr\t\t: yes\n");
53a95579cdSAlessandro Zummo 	seq_printf(seq, "test\t\t: yes\n");
54a95579cdSAlessandro Zummo 	seq_printf(seq, "id\t\t: %d\n", plat_dev->id);
55a95579cdSAlessandro Zummo 
56a95579cdSAlessandro Zummo 	return 0;
57a95579cdSAlessandro Zummo }
58a95579cdSAlessandro Zummo 
59a95579cdSAlessandro Zummo static int test_rtc_ioctl(struct device *dev, unsigned int cmd,
60a95579cdSAlessandro Zummo 	unsigned long arg)
61a95579cdSAlessandro Zummo {
62a95579cdSAlessandro Zummo 	/* We do support interrupts, they're generated
63a95579cdSAlessandro Zummo 	 * using the sysfs interface.
64a95579cdSAlessandro Zummo 	 */
65a95579cdSAlessandro Zummo 	switch (cmd) {
66a95579cdSAlessandro Zummo 	case RTC_PIE_ON:
67a95579cdSAlessandro Zummo 	case RTC_PIE_OFF:
68a95579cdSAlessandro Zummo 	case RTC_UIE_ON:
69a95579cdSAlessandro Zummo 	case RTC_UIE_OFF:
70a95579cdSAlessandro Zummo 	case RTC_AIE_ON:
71a95579cdSAlessandro Zummo 	case RTC_AIE_OFF:
72a95579cdSAlessandro Zummo 		return 0;
73a95579cdSAlessandro Zummo 
74a95579cdSAlessandro Zummo 	default:
75a95579cdSAlessandro Zummo 		return -EINVAL;
76a95579cdSAlessandro Zummo 	}
77a95579cdSAlessandro Zummo }
78a95579cdSAlessandro Zummo 
79a95579cdSAlessandro Zummo static struct rtc_class_ops test_rtc_ops = {
80a95579cdSAlessandro Zummo 	.proc = test_rtc_proc,
81a95579cdSAlessandro Zummo 	.read_time = test_rtc_read_time,
82a95579cdSAlessandro Zummo 	.set_time = test_rtc_set_time,
83a95579cdSAlessandro Zummo 	.read_alarm = test_rtc_read_alarm,
84a95579cdSAlessandro Zummo 	.set_alarm = test_rtc_set_alarm,
85a95579cdSAlessandro Zummo 	.set_mmss = test_rtc_set_mmss,
86a95579cdSAlessandro Zummo 	.ioctl = test_rtc_ioctl,
87a95579cdSAlessandro Zummo };
88a95579cdSAlessandro Zummo 
89a95579cdSAlessandro Zummo static ssize_t test_irq_show(struct device *dev,
90a95579cdSAlessandro Zummo 				struct device_attribute *attr, char *buf)
91a95579cdSAlessandro Zummo {
92a95579cdSAlessandro Zummo 	return sprintf(buf, "%d\n", 42);
93a95579cdSAlessandro Zummo }
94a95579cdSAlessandro Zummo static ssize_t test_irq_store(struct device *dev,
95a95579cdSAlessandro Zummo 				struct device_attribute *attr,
96a95579cdSAlessandro Zummo 				const char *buf, size_t count)
97a95579cdSAlessandro Zummo {
98a95579cdSAlessandro Zummo 	int retval;
99a95579cdSAlessandro Zummo 	struct platform_device *plat_dev = to_platform_device(dev);
100a95579cdSAlessandro Zummo 	struct rtc_device *rtc = platform_get_drvdata(plat_dev);
101a95579cdSAlessandro Zummo 
102a95579cdSAlessandro Zummo 	retval = count;
103a95579cdSAlessandro Zummo 	if (strncmp(buf, "tick", 4) == 0)
104a95579cdSAlessandro Zummo 		rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF);
105a95579cdSAlessandro Zummo 	else if (strncmp(buf, "alarm", 5) == 0)
106a95579cdSAlessandro Zummo 		rtc_update_irq(&rtc->class_dev, 1, RTC_AF | RTC_IRQF);
107a95579cdSAlessandro Zummo 	else if (strncmp(buf, "update", 6) == 0)
108a95579cdSAlessandro Zummo 		rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF);
109a95579cdSAlessandro Zummo 	else
110a95579cdSAlessandro Zummo 		retval = -EINVAL;
111a95579cdSAlessandro Zummo 
112a95579cdSAlessandro Zummo 	return retval;
113a95579cdSAlessandro Zummo }
114a95579cdSAlessandro Zummo static DEVICE_ATTR(irq, S_IRUGO | S_IWUSR, test_irq_show, test_irq_store);
115a95579cdSAlessandro Zummo 
116a95579cdSAlessandro Zummo static int test_probe(struct platform_device *plat_dev)
117a95579cdSAlessandro Zummo {
118a95579cdSAlessandro Zummo 	int err;
119a95579cdSAlessandro Zummo 	struct rtc_device *rtc = rtc_device_register("test", &plat_dev->dev,
120a95579cdSAlessandro Zummo 						&test_rtc_ops, THIS_MODULE);
121a95579cdSAlessandro Zummo 	if (IS_ERR(rtc)) {
122a95579cdSAlessandro Zummo 		err = PTR_ERR(rtc);
123a95579cdSAlessandro Zummo 		dev_err(&plat_dev->dev,
124a95579cdSAlessandro Zummo 			"unable to register the class device\n");
125a95579cdSAlessandro Zummo 		return err;
126a95579cdSAlessandro Zummo 	}
127a95579cdSAlessandro Zummo 	device_create_file(&plat_dev->dev, &dev_attr_irq);
128a95579cdSAlessandro Zummo 
129a95579cdSAlessandro Zummo 	platform_set_drvdata(plat_dev, rtc);
130a95579cdSAlessandro Zummo 
131a95579cdSAlessandro Zummo 	return 0;
132a95579cdSAlessandro Zummo }
133a95579cdSAlessandro Zummo 
134a95579cdSAlessandro Zummo static int __devexit test_remove(struct platform_device *plat_dev)
135a95579cdSAlessandro Zummo {
136a95579cdSAlessandro Zummo 	struct rtc_device *rtc = platform_get_drvdata(plat_dev);
137a95579cdSAlessandro Zummo 
138a95579cdSAlessandro Zummo 	rtc_device_unregister(rtc);
139a95579cdSAlessandro Zummo 	device_remove_file(&plat_dev->dev, &dev_attr_irq);
140a95579cdSAlessandro Zummo 
141a95579cdSAlessandro Zummo 	return 0;
142a95579cdSAlessandro Zummo }
143a95579cdSAlessandro Zummo 
144a95579cdSAlessandro Zummo static struct platform_driver test_drv = {
145a95579cdSAlessandro Zummo 	.probe	= test_probe,
146a95579cdSAlessandro Zummo 	.remove = __devexit_p(test_remove),
147a95579cdSAlessandro Zummo 	.driver = {
148a95579cdSAlessandro Zummo 		.name = "rtc-test",
149a95579cdSAlessandro Zummo 		.owner = THIS_MODULE,
150a95579cdSAlessandro Zummo 	},
151a95579cdSAlessandro Zummo };
152a95579cdSAlessandro Zummo 
153a95579cdSAlessandro Zummo static int __init test_init(void)
154a95579cdSAlessandro Zummo {
155a95579cdSAlessandro Zummo 	int err;
156a95579cdSAlessandro Zummo 
157a95579cdSAlessandro Zummo 	if ((err = platform_driver_register(&test_drv)))
158a95579cdSAlessandro Zummo 		return err;
159a95579cdSAlessandro Zummo 
160a95579cdSAlessandro Zummo 	if ((test0 = platform_device_alloc("rtc-test", 0)) == NULL) {
161a95579cdSAlessandro Zummo 		err = -ENOMEM;
162a95579cdSAlessandro Zummo 		goto exit_driver_unregister;
163a95579cdSAlessandro Zummo 	}
164a95579cdSAlessandro Zummo 
165a95579cdSAlessandro Zummo 	if ((test1 = platform_device_alloc("rtc-test", 1)) == NULL) {
166a95579cdSAlessandro Zummo 		err = -ENOMEM;
167a95579cdSAlessandro Zummo 		goto exit_free_test0;
168a95579cdSAlessandro Zummo 	}
169a95579cdSAlessandro Zummo 
170a95579cdSAlessandro Zummo 	if ((err = platform_device_add(test0)))
171a95579cdSAlessandro Zummo 		goto exit_free_test1;
172a95579cdSAlessandro Zummo 
173a95579cdSAlessandro Zummo 	if ((err = platform_device_add(test1)))
174a95579cdSAlessandro Zummo 		goto exit_device_unregister;
175a95579cdSAlessandro Zummo 
176a95579cdSAlessandro Zummo 	return 0;
177a95579cdSAlessandro Zummo 
178a95579cdSAlessandro Zummo exit_device_unregister:
179a95579cdSAlessandro Zummo 	platform_device_unregister(test0);
180a95579cdSAlessandro Zummo 
181a95579cdSAlessandro Zummo exit_free_test1:
182a95579cdSAlessandro Zummo 	platform_device_put(test1);
183a95579cdSAlessandro Zummo 
184a95579cdSAlessandro Zummo exit_free_test0:
185a95579cdSAlessandro Zummo 	platform_device_put(test0);
186a95579cdSAlessandro Zummo 
187a95579cdSAlessandro Zummo exit_driver_unregister:
188a95579cdSAlessandro Zummo 	platform_driver_unregister(&test_drv);
189a95579cdSAlessandro Zummo 	return err;
190a95579cdSAlessandro Zummo }
191a95579cdSAlessandro Zummo 
192a95579cdSAlessandro Zummo static void __exit test_exit(void)
193a95579cdSAlessandro Zummo {
194a95579cdSAlessandro Zummo 	platform_device_unregister(test0);
195a95579cdSAlessandro Zummo 	platform_device_unregister(test1);
196a95579cdSAlessandro Zummo 	platform_driver_unregister(&test_drv);
197a95579cdSAlessandro Zummo }
198a95579cdSAlessandro Zummo 
199a95579cdSAlessandro Zummo MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
200a95579cdSAlessandro Zummo MODULE_DESCRIPTION("RTC test driver/device");
201a95579cdSAlessandro Zummo MODULE_LICENSE("GPL");
202a95579cdSAlessandro Zummo 
203a95579cdSAlessandro Zummo module_init(test_init);
204a95579cdSAlessandro Zummo module_exit(test_exit);
205