Merge branch 'omap-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6.git] / drivers / rtc / rtc-v3020.c
1 /* drivers/rtc/rtc-v3020.c
2  *
3  * Copyright (C) 2006 8D Technologies inc.
4  * Copyright (C) 2004 Compulab Ltd.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * Driver for the V3020 RTC
11  *
12  * Changelog:
13  *
14  *  10-May-2006: Raphael Assenat <raph@8d.com>
15  *                              - Converted to platform driver
16  *                              - Use the generic rtc class
17  *
18  *  ??-???-2004: Someone at Compulab
19  *                      - Initial driver creation.
20  *
21  */
22 #include <linux/platform_device.h>
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/rtc.h>
26 #include <linux/types.h>
27 #include <linux/bcd.h>
28 #include <linux/rtc-v3020.h>
29 #include <linux/delay.h>
30 #include <linux/gpio.h>
31
32 #include <linux/io.h>
33
34 #undef DEBUG
35
36 struct v3020;
37
38 struct v3020_chip_ops {
39         int (*map_io)(struct v3020 *chip, struct platform_device *pdev,
40                       struct v3020_platform_data *pdata);
41         void (*unmap_io)(struct v3020 *chip);
42         unsigned char (*read_bit)(struct v3020 *chip);
43         void (*write_bit)(struct v3020 *chip, unsigned char bit);
44 };
45
46 #define V3020_CS        0
47 #define V3020_WR        1
48 #define V3020_RD        2
49 #define V3020_IO        3
50
51 struct v3020_gpio {
52         const char *name;
53         unsigned int gpio;
54 };
55
56 struct v3020 {
57         /* MMIO access */
58         void __iomem *ioaddress;
59         int leftshift;
60
61         /* GPIO access */
62         struct v3020_gpio *gpio;
63
64         struct v3020_chip_ops *ops;
65
66         struct rtc_device *rtc;
67 };
68
69
70 static int v3020_mmio_map(struct v3020 *chip, struct platform_device *pdev,
71                           struct v3020_platform_data *pdata)
72 {
73         if (pdev->num_resources != 1)
74                 return -EBUSY;
75
76         if (pdev->resource[0].flags != IORESOURCE_MEM)
77                 return -EBUSY;
78
79         chip->leftshift = pdata->leftshift;
80         chip->ioaddress = ioremap(pdev->resource[0].start, 1);
81         if (chip->ioaddress == NULL)
82                 return -EBUSY;
83
84         return 0;
85 }
86
87 static void v3020_mmio_unmap(struct v3020 *chip)
88 {
89         iounmap(chip->ioaddress);
90 }
91
92 static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit)
93 {
94         writel(bit << chip->leftshift, chip->ioaddress);
95 }
96
97 static unsigned char v3020_mmio_read_bit(struct v3020 *chip)
98 {
99         return !!(readl(chip->ioaddress) & (1 << chip->leftshift));
100 }
101
102 static struct v3020_chip_ops v3020_mmio_ops = {
103         .map_io         = v3020_mmio_map,
104         .unmap_io       = v3020_mmio_unmap,
105         .read_bit       = v3020_mmio_read_bit,
106         .write_bit      = v3020_mmio_write_bit,
107 };
108
109 static struct v3020_gpio v3020_gpio[] = {
110         { "RTC CS", 0 },
111         { "RTC WR", 0 },
112         { "RTC RD", 0 },
113         { "RTC IO", 0 },
114 };
115
116 static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev,
117                           struct v3020_platform_data *pdata)
118 {
119         int i, err;
120
121         v3020_gpio[V3020_CS].gpio = pdata->gpio_cs;
122         v3020_gpio[V3020_WR].gpio = pdata->gpio_wr;
123         v3020_gpio[V3020_RD].gpio = pdata->gpio_rd;
124         v3020_gpio[V3020_IO].gpio = pdata->gpio_io;
125
126         for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++) {
127                 err = gpio_request(v3020_gpio[i].gpio, v3020_gpio[i].name);
128                 if (err)
129                         goto err_request;
130
131                 gpio_direction_output(v3020_gpio[i].gpio, 1);
132         }
133
134         chip->gpio = v3020_gpio;
135
136         return 0;
137
138 err_request:
139         while (--i >= 0)
140                 gpio_free(v3020_gpio[i].gpio);
141
142         return err;
143 }
144
145 static void v3020_gpio_unmap(struct v3020 *chip)
146 {
147         int i;
148
149         for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++)
150                 gpio_free(v3020_gpio[i].gpio);
151 }
152
153 static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit)
154 {
155         gpio_direction_output(chip->gpio[V3020_IO].gpio, bit);
156         gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
157         gpio_set_value(chip->gpio[V3020_WR].gpio, 0);
158         udelay(1);
159         gpio_set_value(chip->gpio[V3020_WR].gpio, 1);
160         gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
161 }
162
163 static unsigned char v3020_gpio_read_bit(struct v3020 *chip)
164 {
165         int bit;
166
167         gpio_direction_input(chip->gpio[V3020_IO].gpio);
168         gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
169         gpio_set_value(chip->gpio[V3020_RD].gpio, 0);
170         udelay(1);
171         bit = !!gpio_get_value(chip->gpio[V3020_IO].gpio);
172         udelay(1);
173         gpio_set_value(chip->gpio[V3020_RD].gpio, 1);
174         gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
175
176         return bit;
177 }
178
179 static struct v3020_chip_ops v3020_gpio_ops = {
180         .map_io         = v3020_gpio_map,
181         .unmap_io       = v3020_gpio_unmap,
182         .read_bit       = v3020_gpio_read_bit,
183         .write_bit      = v3020_gpio_write_bit,
184 };
185
186 static void v3020_set_reg(struct v3020 *chip, unsigned char address,
187                         unsigned char data)
188 {
189         int i;
190         unsigned char tmp;
191
192         tmp = address;
193         for (i = 0; i < 4; i++) {
194                 chip->ops->write_bit(chip, (tmp & 1));
195                 tmp >>= 1;
196                 udelay(1);
197         }
198
199         /* Commands dont have data */
200         if (!V3020_IS_COMMAND(address)) {
201                 for (i = 0; i < 8; i++) {
202                         chip->ops->write_bit(chip, (data & 1));
203                         data >>= 1;
204                         udelay(1);
205                 }
206         }
207 }
208
209 static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address)
210 {
211         unsigned int data = 0;
212         int i;
213
214         for (i = 0; i < 4; i++) {
215                 chip->ops->write_bit(chip, (address & 1));
216                 address >>= 1;
217                 udelay(1);
218         }
219
220         for (i = 0; i < 8; i++) {
221                 data >>= 1;
222                 if (chip->ops->read_bit(chip))
223                         data |= 0x80;
224                 udelay(1);
225         }
226
227         return data;
228 }
229
230 static int v3020_read_time(struct device *dev, struct rtc_time *dt)
231 {
232         struct v3020 *chip = dev_get_drvdata(dev);
233         int tmp;
234
235         /* Copy the current time to ram... */
236         v3020_set_reg(chip, V3020_CMD_CLOCK2RAM, 0);
237
238         /* ...and then read constant values. */
239         tmp = v3020_get_reg(chip, V3020_SECONDS);
240         dt->tm_sec      = bcd2bin(tmp);
241         tmp = v3020_get_reg(chip, V3020_MINUTES);
242         dt->tm_min      = bcd2bin(tmp);
243         tmp = v3020_get_reg(chip, V3020_HOURS);
244         dt->tm_hour     = bcd2bin(tmp);
245         tmp = v3020_get_reg(chip, V3020_MONTH_DAY);
246         dt->tm_mday     = bcd2bin(tmp);
247         tmp = v3020_get_reg(chip, V3020_MONTH);
248         dt->tm_mon    = bcd2bin(tmp) - 1;
249         tmp = v3020_get_reg(chip, V3020_WEEK_DAY);
250         dt->tm_wday     = bcd2bin(tmp);
251         tmp = v3020_get_reg(chip, V3020_YEAR);
252         dt->tm_year = bcd2bin(tmp)+100;
253
254         dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
255         dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
256         dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
257         dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
258         dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
259         dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
260         dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
261         dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
262
263         return 0;
264 }
265
266
267 static int v3020_set_time(struct device *dev, struct rtc_time *dt)
268 {
269         struct v3020 *chip = dev_get_drvdata(dev);
270
271         dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
272         dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
273         dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
274         dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
275         dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
276         dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
277         dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
278
279         /* Write all the values to ram... */
280         v3020_set_reg(chip, V3020_SECONDS,      bin2bcd(dt->tm_sec));
281         v3020_set_reg(chip, V3020_MINUTES,      bin2bcd(dt->tm_min));
282         v3020_set_reg(chip, V3020_HOURS,        bin2bcd(dt->tm_hour));
283         v3020_set_reg(chip, V3020_MONTH_DAY,    bin2bcd(dt->tm_mday));
284         v3020_set_reg(chip, V3020_MONTH,     bin2bcd(dt->tm_mon + 1));
285         v3020_set_reg(chip, V3020_WEEK_DAY,     bin2bcd(dt->tm_wday));
286         v3020_set_reg(chip, V3020_YEAR,         bin2bcd(dt->tm_year % 100));
287
288         /* ...and set the clock. */
289         v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0);
290
291         /* Compulab used this delay here. I dont know why,
292          * the datasheet does not specify a delay. */
293         /*mdelay(5);*/
294
295         return 0;
296 }
297
298 static const struct rtc_class_ops v3020_rtc_ops = {
299         .read_time      = v3020_read_time,
300         .set_time       = v3020_set_time,
301 };
302
303 static int rtc_probe(struct platform_device *pdev)
304 {
305         struct v3020_platform_data *pdata = pdev->dev.platform_data;
306         struct v3020 *chip;
307         int retval = -EBUSY;
308         int i;
309         int temp;
310
311         chip = kzalloc(sizeof *chip, GFP_KERNEL);
312         if (!chip)
313                 return -ENOMEM;
314
315         if (pdata->use_gpio)
316                 chip->ops = &v3020_gpio_ops;
317         else
318                 chip->ops = &v3020_mmio_ops;
319
320         retval = chip->ops->map_io(chip, pdev, pdata);
321         if (retval)
322                 goto err_chip;
323
324         /* Make sure the v3020 expects a communication cycle
325          * by reading 8 times */
326         for (i = 0; i < 8; i++)
327                 temp = chip->ops->read_bit(chip);
328
329         /* Test chip by doing a write/read sequence
330          * to the chip ram */
331         v3020_set_reg(chip, V3020_SECONDS, 0x33);
332         if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
333                 retval = -ENODEV;
334                 goto err_io;
335         }
336
337         /* Make sure frequency measurement mode, test modes, and lock
338          * are all disabled */
339         v3020_set_reg(chip, V3020_STATUS_0, 0x0);
340
341         if (pdata->use_gpio)
342                 dev_info(&pdev->dev, "Chip available at GPIOs "
343                          "%d, %d, %d, %d\n",
344                          chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio,
345                          chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio);
346         else
347                 dev_info(&pdev->dev, "Chip available at "
348                          "physical address 0x%llx,"
349                          "data connected to D%d\n",
350                          (unsigned long long)pdev->resource[0].start,
351                          chip->leftshift);
352
353         platform_set_drvdata(pdev, chip);
354
355         chip->rtc = rtc_device_register("v3020",
356                                 &pdev->dev, &v3020_rtc_ops, THIS_MODULE);
357         if (IS_ERR(chip->rtc)) {
358                 retval = PTR_ERR(chip->rtc);
359                 goto err_io;
360         }
361
362         return 0;
363
364 err_io:
365         chip->ops->unmap_io(chip);
366 err_chip:
367         kfree(chip);
368
369         return retval;
370 }
371
372 static int rtc_remove(struct platform_device *dev)
373 {
374         struct v3020 *chip = platform_get_drvdata(dev);
375         struct rtc_device *rtc = chip->rtc;
376
377         if (rtc)
378                 rtc_device_unregister(rtc);
379
380         chip->ops->unmap_io(chip);
381         kfree(chip);
382
383         return 0;
384 }
385
386 static struct platform_driver rtc_device_driver = {
387         .probe  = rtc_probe,
388         .remove = rtc_remove,
389         .driver = {
390                 .name   = "v3020",
391                 .owner  = THIS_MODULE,
392         },
393 };
394
395 static __init int v3020_init(void)
396 {
397         return platform_driver_register(&rtc_device_driver);
398 }
399
400 static __exit void v3020_exit(void)
401 {
402         platform_driver_unregister(&rtc_device_driver);
403 }
404
405 module_init(v3020_init);
406 module_exit(v3020_exit);
407
408 MODULE_DESCRIPTION("V3020 RTC");
409 MODULE_AUTHOR("Raphael Assenat");
410 MODULE_LICENSE("GPL");
411 MODULE_ALIAS("platform:v3020");