Merge branch 'agp-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[sfrench/cifs-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         struct rtc_device *rtc;
308         int retval = -EBUSY;
309         int i;
310         int temp;
311
312         chip = kzalloc(sizeof *chip, GFP_KERNEL);
313         if (!chip)
314                 return -ENOMEM;
315
316         if (pdata->use_gpio)
317                 chip->ops = &v3020_gpio_ops;
318         else
319                 chip->ops = &v3020_mmio_ops;
320
321         retval = chip->ops->map_io(chip, pdev, pdata);
322         if (retval)
323                 goto err_chip;
324
325         /* Make sure the v3020 expects a communication cycle
326          * by reading 8 times */
327         for (i = 0; i < 8; i++)
328                 temp = chip->ops->read_bit(chip);
329
330         /* Test chip by doing a write/read sequence
331          * to the chip ram */
332         v3020_set_reg(chip, V3020_SECONDS, 0x33);
333         if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
334                 retval = -ENODEV;
335                 goto err_io;
336         }
337
338         /* Make sure frequency measurment mode, test modes, and lock
339          * are all disabled */
340         v3020_set_reg(chip, V3020_STATUS_0, 0x0);
341
342         if (pdata->use_gpio)
343                 dev_info(&pdev->dev, "Chip available at GPIOs "
344                          "%d, %d, %d, %d\n",
345                          chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio,
346                          chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio);
347         else
348                 dev_info(&pdev->dev, "Chip available at "
349                          "physical address 0x%llx,"
350                          "data connected to D%d\n",
351                          (unsigned long long)pdev->resource[0].start,
352                          chip->leftshift);
353
354         platform_set_drvdata(pdev, chip);
355
356         rtc = rtc_device_register("v3020",
357                                 &pdev->dev, &v3020_rtc_ops, THIS_MODULE);
358         if (IS_ERR(rtc)) {
359                 retval = PTR_ERR(rtc);
360                 goto err_io;
361         }
362         chip->rtc = rtc;
363
364         return 0;
365
366 err_io:
367         chip->ops->unmap_io(chip);
368 err_chip:
369         kfree(chip);
370
371         return retval;
372 }
373
374 static int rtc_remove(struct platform_device *dev)
375 {
376         struct v3020 *chip = platform_get_drvdata(dev);
377         struct rtc_device *rtc = chip->rtc;
378
379         if (rtc)
380                 rtc_device_unregister(rtc);
381
382         chip->ops->unmap_io(chip);
383         kfree(chip);
384
385         return 0;
386 }
387
388 static struct platform_driver rtc_device_driver = {
389         .probe  = rtc_probe,
390         .remove = rtc_remove,
391         .driver = {
392                 .name   = "v3020",
393                 .owner  = THIS_MODULE,
394         },
395 };
396
397 static __init int v3020_init(void)
398 {
399         return platform_driver_register(&rtc_device_driver);
400 }
401
402 static __exit void v3020_exit(void)
403 {
404         platform_driver_unregister(&rtc_device_driver);
405 }
406
407 module_init(v3020_init);
408 module_exit(v3020_exit);
409
410 MODULE_DESCRIPTION("V3020 RTC");
411 MODULE_AUTHOR("Raphael Assenat");
412 MODULE_LICENSE("GPL");
413 MODULE_ALIAS("platform:v3020");