aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/Kconfig4
-rw-r--r--drivers/rtc/rtc-m41t80.c18
-rw-r--r--drivers/rtc/rtc-v3020.c190
3 files changed, 185 insertions, 27 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 09d5cd33a3f6..56002f7d26bd 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -225,11 +225,11 @@ config RTC_DRV_PCF8583
225 will be called rtc-pcf8583. 225 will be called rtc-pcf8583.
226 226
227config RTC_DRV_M41T80 227config RTC_DRV_M41T80
228 tristate "ST M41T65/M41T80/81/82/83/84/85/87" 228 tristate "ST M41T62/65/M41T80/81/82/83/84/85/87"
229 help 229 help
230 If you say Y here you will get support for the ST M41T60 230 If you say Y here you will get support for the ST M41T60
231 and M41T80 RTC chips series. Currently, the following chips are 231 and M41T80 RTC chips series. Currently, the following chips are
232 supported: M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84, 232 supported: M41T62, M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
233 M41ST85, and M41ST87. 233 M41ST85, and M41ST87.
234 234
235 This driver can also be built as a module. If so, the module 235 This driver can also be built as a module. If so, the module
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 893f7dece239..60fe266f0f49 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -64,10 +64,12 @@
64#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */ 64#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */
65#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */ 65#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */
66#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */ 66#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
67#define M41T80_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */
67 68
68#define DRV_VERSION "0.05" 69#define DRV_VERSION "0.05"
69 70
70static const struct i2c_device_id m41t80_id[] = { 71static const struct i2c_device_id m41t80_id[] = {
72 { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT },
71 { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD }, 73 { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
72 { "m41t80", M41T80_FEATURE_SQ }, 74 { "m41t80", M41T80_FEATURE_SQ },
73 { "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ}, 75 { "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ},
@@ -393,12 +395,15 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
393{ 395{
394 struct i2c_client *client = to_i2c_client(dev); 396 struct i2c_client *client = to_i2c_client(dev);
395 struct m41t80_data *clientdata = i2c_get_clientdata(client); 397 struct m41t80_data *clientdata = i2c_get_clientdata(client);
396 int val; 398 int val, reg_sqw;
397 399
398 if (!(clientdata->features & M41T80_FEATURE_SQ)) 400 if (!(clientdata->features & M41T80_FEATURE_SQ))
399 return -EINVAL; 401 return -EINVAL;
400 402
401 val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW); 403 reg_sqw = M41T80_REG_SQW;
404 if (clientdata->features & M41T80_FEATURE_SQ_ALT)
405 reg_sqw = M41T80_REG_WDAY;
406 val = i2c_smbus_read_byte_data(client, reg_sqw);
402 if (val < 0) 407 if (val < 0)
403 return -EIO; 408 return -EIO;
404 val = (val >> 4) & 0xf; 409 val = (val >> 4) & 0xf;
@@ -419,7 +424,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
419{ 424{
420 struct i2c_client *client = to_i2c_client(dev); 425 struct i2c_client *client = to_i2c_client(dev);
421 struct m41t80_data *clientdata = i2c_get_clientdata(client); 426 struct m41t80_data *clientdata = i2c_get_clientdata(client);
422 int almon, sqw; 427 int almon, sqw, reg_sqw;
423 int val = simple_strtoul(buf, NULL, 0); 428 int val = simple_strtoul(buf, NULL, 0);
424 429
425 if (!(clientdata->features & M41T80_FEATURE_SQ)) 430 if (!(clientdata->features & M41T80_FEATURE_SQ))
@@ -440,13 +445,16 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
440 almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); 445 almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
441 if (almon < 0) 446 if (almon < 0)
442 return -EIO; 447 return -EIO;
443 sqw = i2c_smbus_read_byte_data(client, M41T80_REG_SQW); 448 reg_sqw = M41T80_REG_SQW;
449 if (clientdata->features & M41T80_FEATURE_SQ_ALT)
450 reg_sqw = M41T80_REG_WDAY;
451 sqw = i2c_smbus_read_byte_data(client, reg_sqw);
444 if (sqw < 0) 452 if (sqw < 0)
445 return -EIO; 453 return -EIO;
446 sqw = (sqw & 0x0f) | (val << 4); 454 sqw = (sqw & 0x0f) | (val << 4);
447 if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, 455 if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
448 almon & ~M41T80_ALMON_SQWE) < 0 || 456 almon & ~M41T80_ALMON_SQWE) < 0 ||
449 i2c_smbus_write_byte_data(client, M41T80_REG_SQW, sqw) < 0) 457 i2c_smbus_write_byte_data(client, reg_sqw, sqw) < 0)
450 return -EIO; 458 return -EIO;
451 if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, 459 if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
452 almon | M41T80_ALMON_SQWE) < 0) 460 almon | M41T80_ALMON_SQWE) < 0)
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index 66955cc9c746..ad164056feb6 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -27,17 +27,162 @@
27#include <linux/bcd.h> 27#include <linux/bcd.h>
28#include <linux/rtc-v3020.h> 28#include <linux/rtc-v3020.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/gpio.h>
30 31
31#include <linux/io.h> 32#include <linux/io.h>
32 33
33#undef DEBUG 34#undef DEBUG
34 35
36struct v3020;
37
38struct 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
51struct v3020_gpio {
52 const char *name;
53 unsigned int gpio;
54};
55
35struct v3020 { 56struct v3020 {
57 /* MMIO access */
36 void __iomem *ioaddress; 58 void __iomem *ioaddress;
37 int leftshift; 59 int leftshift;
60
61 /* GPIO access */
62 struct v3020_gpio *gpio;
63
64 struct v3020_chip_ops *ops;
65
38 struct rtc_device *rtc; 66 struct rtc_device *rtc;
39}; 67};
40 68
69
70static 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
87static void v3020_mmio_unmap(struct v3020 *chip)
88{
89 iounmap(chip->ioaddress);
90}
91
92static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit)
93{
94 writel(bit << chip->leftshift, chip->ioaddress);
95}
96
97static unsigned char v3020_mmio_read_bit(struct v3020 *chip)
98{
99 return readl(chip->ioaddress) & (1 << chip->leftshift);
100}
101
102static 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
109static struct v3020_gpio v3020_gpio[] = {
110 { "RTC CS", 0 },
111 { "RTC WR", 0 },
112 { "RTC RD", 0 },
113 { "RTC IO", 0 },
114};
115
116static 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
138err_request:
139 while (--i >= 0)
140 gpio_free(v3020_gpio[i].gpio);
141
142 return err;
143}
144
145static 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
153static 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
163static 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
179static 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
41static void v3020_set_reg(struct v3020 *chip, unsigned char address, 186static void v3020_set_reg(struct v3020 *chip, unsigned char address,
42 unsigned char data) 187 unsigned char data)
43{ 188{
@@ -46,7 +191,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address,
46 191
47 tmp = address; 192 tmp = address;
48 for (i = 0; i < 4; i++) { 193 for (i = 0; i < 4; i++) {
49 writel((tmp & 1) << chip->leftshift, chip->ioaddress); 194 chip->ops->write_bit(chip, (tmp & 1));
50 tmp >>= 1; 195 tmp >>= 1;
51 udelay(1); 196 udelay(1);
52 } 197 }
@@ -54,7 +199,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address,
54 /* Commands dont have data */ 199 /* Commands dont have data */
55 if (!V3020_IS_COMMAND(address)) { 200 if (!V3020_IS_COMMAND(address)) {
56 for (i = 0; i < 8; i++) { 201 for (i = 0; i < 8; i++) {
57 writel((data & 1) << chip->leftshift, chip->ioaddress); 202 chip->ops->write_bit(chip, (data & 1));
58 data >>= 1; 203 data >>= 1;
59 udelay(1); 204 udelay(1);
60 } 205 }
@@ -67,14 +212,14 @@ static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address)
67 int i; 212 int i;
68 213
69 for (i = 0; i < 4; i++) { 214 for (i = 0; i < 4; i++) {
70 writel((address & 1) << chip->leftshift, chip->ioaddress); 215 chip->ops->write_bit(chip, (address & 1));
71 address >>= 1; 216 address >>= 1;
72 udelay(1); 217 udelay(1);
73 } 218 }
74 219
75 for (i = 0; i < 8; i++) { 220 for (i = 0; i < 8; i++) {
76 data >>= 1; 221 data >>= 1;
77 if (readl(chip->ioaddress) & (1 << chip->leftshift)) 222 if (chip->ops->read_bit(chip))
78 data |= 0x80; 223 data |= 0x80;
79 udelay(1); 224 udelay(1);
80 } 225 }
@@ -164,25 +309,23 @@ static int rtc_probe(struct platform_device *pdev)
164 int i; 309 int i;
165 int temp; 310 int temp;
166 311
167 if (pdev->num_resources != 1)
168 return -EBUSY;
169
170 if (pdev->resource[0].flags != IORESOURCE_MEM)
171 return -EBUSY;
172
173 chip = kzalloc(sizeof *chip, GFP_KERNEL); 312 chip = kzalloc(sizeof *chip, GFP_KERNEL);
174 if (!chip) 313 if (!chip)
175 return -ENOMEM; 314 return -ENOMEM;
176 315
177 chip->leftshift = pdata->leftshift; 316 if (pdata->use_gpio)
178 chip->ioaddress = ioremap(pdev->resource[0].start, 1); 317 chip->ops = &v3020_gpio_ops;
179 if (chip->ioaddress == NULL) 318 else
319 chip->ops = &v3020_mmio_ops;
320
321 retval = chip->ops->map_io(chip, pdev, pdata);
322 if (retval)
180 goto err_chip; 323 goto err_chip;
181 324
182 /* Make sure the v3020 expects a communication cycle 325 /* Make sure the v3020 expects a communication cycle
183 * by reading 8 times */ 326 * by reading 8 times */
184 for (i = 0; i < 8; i++) 327 for (i = 0; i < 8; i++)
185 temp = readl(chip->ioaddress); 328 temp = chip->ops->read_bit(chip);
186 329
187 /* Test chip by doing a write/read sequence 330 /* Test chip by doing a write/read sequence
188 * to the chip ram */ 331 * to the chip ram */
@@ -196,10 +339,17 @@ static int rtc_probe(struct platform_device *pdev)
196 * are all disabled */ 339 * are all disabled */
197 v3020_set_reg(chip, V3020_STATUS_0, 0x0); 340 v3020_set_reg(chip, V3020_STATUS_0, 0x0);
198 341
199 dev_info(&pdev->dev, "Chip available at physical address 0x%llx," 342 if (pdata->use_gpio)
200 "data connected to D%d\n", 343 dev_info(&pdev->dev, "Chip available at GPIOs "
201 (unsigned long long)pdev->resource[0].start, 344 "%d, %d, %d, %d\n",
202 chip->leftshift); 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);
203 353
204 platform_set_drvdata(pdev, chip); 354 platform_set_drvdata(pdev, chip);
205 355
@@ -214,7 +364,7 @@ static int rtc_probe(struct platform_device *pdev)
214 return 0; 364 return 0;
215 365
216err_io: 366err_io:
217 iounmap(chip->ioaddress); 367 chip->ops->unmap_io(chip);
218err_chip: 368err_chip:
219 kfree(chip); 369 kfree(chip);
220 370
@@ -229,7 +379,7 @@ static int rtc_remove(struct platform_device *dev)
229 if (rtc) 379 if (rtc)
230 rtc_device_unregister(rtc); 380 rtc_device_unregister(rtc);
231 381
232 iounmap(chip->ioaddress); 382 chip->ops->unmap_io(chip);
233 kfree(chip); 383 kfree(chip);
234 384
235 return 0; 385 return 0;