aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTorsten Ertbjerg Rasmussen <tr@newtec.dk>2006-12-06 23:39:41 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 11:39:43 -0500
commitf9231a0ca1afd05543d9f83539d6ecd5c018e8cf (patch)
tree4305db0c914b3789296b05774c48aec76c0b3d21
parent3908fd2ed920af818aa596672da68ba26173ff27 (diff)
[PATCH] rtc: ds1743 support
The real time clocks ds1742 and ds1743 differs only in the size of the nvram. This patch changes the existing ds1742 driver to support also ds1743. The main change is that the nvram size is determined from the resource attached to the device. The patch have benefitted from suggestions from Atsushi Nemeto, who is the author of the ds1742 driver. Signed-off-by: Torsten Rasmussen Rasmussen <tr@newtec.dk> Acked-by: Alessandro Zummo <a.zummo@towertech.it> Acked-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/rtc/Kconfig4
-rw-r--r--drivers/rtc/rtc-ds1742.c67
2 files changed, 41 insertions, 30 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 4d32bad79f1b..2a63ab2b47f4 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -154,11 +154,11 @@ config RTC_DRV_DS1672
154 will be called rtc-ds1672. 154 will be called rtc-ds1672.
155 155
156config RTC_DRV_DS1742 156config RTC_DRV_DS1742
157 tristate "Dallas DS1742" 157 tristate "Dallas DS1742/1743"
158 depends on RTC_CLASS 158 depends on RTC_CLASS
159 help 159 help
160 If you say yes here you get support for the 160 If you say yes here you get support for the
161 Dallas DS1742 timekeeping chip. 161 Dallas DS1742/1743 timekeeping chip.
162 162
163 This driver can also be built as a module. If so, the module 163 This driver can also be built as a module. If so, the module
164 will be called rtc-ds1742. 164 will be called rtc-ds1742.
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 6273a3d240a2..17633bfa8480 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -6,6 +6,10 @@
6 * This program is free software; you can redistribute it and/or modify 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 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 *
10 * Copyright (C) 2006 Torsten Ertbjerg Rasmussen <tr@newtec.dk>
11 * - nvram size determined from resource
12 * - this ds1742 driver now supports ds1743.
9 */ 13 */
10 14
11#include <linux/bcd.h> 15#include <linux/bcd.h>
@@ -17,20 +21,19 @@
17#include <linux/platform_device.h> 21#include <linux/platform_device.h>
18#include <linux/io.h> 22#include <linux/io.h>
19 23
20#define DRV_VERSION "0.2" 24#define DRV_VERSION "0.3"
21 25
22#define RTC_REG_SIZE 0x800 26#define RTC_SIZE 8
23#define RTC_OFFSET 0x7f8
24 27
25#define RTC_CONTROL (RTC_OFFSET + 0) 28#define RTC_CONTROL 0
26#define RTC_CENTURY (RTC_OFFSET + 0) 29#define RTC_CENTURY 0
27#define RTC_SECONDS (RTC_OFFSET + 1) 30#define RTC_SECONDS 1
28#define RTC_MINUTES (RTC_OFFSET + 2) 31#define RTC_MINUTES 2
29#define RTC_HOURS (RTC_OFFSET + 3) 32#define RTC_HOURS 3
30#define RTC_DAY (RTC_OFFSET + 4) 33#define RTC_DAY 4
31#define RTC_DATE (RTC_OFFSET + 5) 34#define RTC_DATE 5
32#define RTC_MONTH (RTC_OFFSET + 6) 35#define RTC_MONTH 6
33#define RTC_YEAR (RTC_OFFSET + 7) 36#define RTC_YEAR 7
34 37
35#define RTC_CENTURY_MASK 0x3f 38#define RTC_CENTURY_MASK 0x3f
36#define RTC_SECONDS_MASK 0x7f 39#define RTC_SECONDS_MASK 0x7f
@@ -48,7 +51,10 @@
48 51
49struct rtc_plat_data { 52struct rtc_plat_data {
50 struct rtc_device *rtc; 53 struct rtc_device *rtc;
51 void __iomem *ioaddr; 54 void __iomem *ioaddr_nvram;
55 void __iomem *ioaddr_rtc;
56 size_t size_nvram;
57 size_t size;
52 unsigned long baseaddr; 58 unsigned long baseaddr;
53 unsigned long last_jiffies; 59 unsigned long last_jiffies;
54}; 60};
@@ -57,7 +63,7 @@ static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
57{ 63{
58 struct platform_device *pdev = to_platform_device(dev); 64 struct platform_device *pdev = to_platform_device(dev);
59 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 65 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
60 void __iomem *ioaddr = pdata->ioaddr; 66 void __iomem *ioaddr = pdata->ioaddr_rtc;
61 u8 century; 67 u8 century;
62 68
63 century = BIN2BCD((tm->tm_year + 1900) / 100); 69 century = BIN2BCD((tm->tm_year + 1900) / 100);
@@ -82,7 +88,7 @@ static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm)
82{ 88{
83 struct platform_device *pdev = to_platform_device(dev); 89 struct platform_device *pdev = to_platform_device(dev);
84 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 90 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
85 void __iomem *ioaddr = pdata->ioaddr; 91 void __iomem *ioaddr = pdata->ioaddr_rtc;
86 unsigned int year, month, day, hour, minute, second, week; 92 unsigned int year, month, day, hour, minute, second, week;
87 unsigned int century; 93 unsigned int century;
88 94
@@ -127,10 +133,10 @@ static ssize_t ds1742_nvram_read(struct kobject *kobj, char *buf,
127 struct platform_device *pdev = 133 struct platform_device *pdev =
128 to_platform_device(container_of(kobj, struct device, kobj)); 134 to_platform_device(container_of(kobj, struct device, kobj));
129 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 135 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
130 void __iomem *ioaddr = pdata->ioaddr; 136 void __iomem *ioaddr = pdata->ioaddr_nvram;
131 ssize_t count; 137 ssize_t count;
132 138
133 for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) 139 for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--)
134 *buf++ = readb(ioaddr + pos++); 140 *buf++ = readb(ioaddr + pos++);
135 return count; 141 return count;
136} 142}
@@ -141,10 +147,10 @@ static ssize_t ds1742_nvram_write(struct kobject *kobj, char *buf,
141 struct platform_device *pdev = 147 struct platform_device *pdev =
142 to_platform_device(container_of(kobj, struct device, kobj)); 148 to_platform_device(container_of(kobj, struct device, kobj));
143 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 149 struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
144 void __iomem *ioaddr = pdata->ioaddr; 150 void __iomem *ioaddr = pdata->ioaddr_nvram;
145 ssize_t count; 151 ssize_t count;
146 152
147 for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--) 153 for (count = 0; size > 0 && pos < pdata->size_nvram; count++, size--)
148 writeb(*buf++, ioaddr + pos++); 154 writeb(*buf++, ioaddr + pos++);
149 return count; 155 return count;
150} 156}
@@ -155,7 +161,6 @@ static struct bin_attribute ds1742_nvram_attr = {
155 .mode = S_IRUGO | S_IWUGO, 161 .mode = S_IRUGO | S_IWUGO,
156 .owner = THIS_MODULE, 162 .owner = THIS_MODULE,
157 }, 163 },
158 .size = RTC_OFFSET,
159 .read = ds1742_nvram_read, 164 .read = ds1742_nvram_read,
160 .write = ds1742_nvram_write, 165 .write = ds1742_nvram_write,
161}; 166};
@@ -175,19 +180,23 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev)
175 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); 180 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
176 if (!pdata) 181 if (!pdata)
177 return -ENOMEM; 182 return -ENOMEM;
178 if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { 183 pdata->size = res->end - res->start + 1;
184 if (!request_mem_region(res->start, pdata->size, pdev->name)) {
179 ret = -EBUSY; 185 ret = -EBUSY;
180 goto out; 186 goto out;
181 } 187 }
182 pdata->baseaddr = res->start; 188 pdata->baseaddr = res->start;
183 ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE); 189 ioaddr = ioremap(pdata->baseaddr, pdata->size);
184 if (!ioaddr) { 190 if (!ioaddr) {
185 ret = -ENOMEM; 191 ret = -ENOMEM;
186 goto out; 192 goto out;
187 } 193 }
188 pdata->ioaddr = ioaddr; 194 pdata->ioaddr_nvram = ioaddr;
195 pdata->size_nvram = pdata->size - RTC_SIZE;
196 pdata->ioaddr_rtc = ioaddr + pdata->size_nvram;
189 197
190 /* turn RTC on if it was not on */ 198 /* turn RTC on if it was not on */
199 ioaddr = pdata->ioaddr_rtc;
191 sec = readb(ioaddr + RTC_SECONDS); 200 sec = readb(ioaddr + RTC_SECONDS);
192 if (sec & RTC_STOP) { 201 if (sec & RTC_STOP) {
193 sec &= RTC_SECONDS_MASK; 202 sec &= RTC_SECONDS_MASK;
@@ -208,6 +217,8 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev)
208 pdata->rtc = rtc; 217 pdata->rtc = rtc;
209 pdata->last_jiffies = jiffies; 218 pdata->last_jiffies = jiffies;
210 platform_set_drvdata(pdev, pdata); 219 platform_set_drvdata(pdev, pdata);
220 ds1742_nvram_attr.size = max(ds1742_nvram_attr.size,
221 pdata->size_nvram);
211 ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr); 222 ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr);
212 if (ret) 223 if (ret)
213 goto out; 224 goto out;
@@ -215,10 +226,10 @@ static int __init ds1742_rtc_probe(struct platform_device *pdev)
215 out: 226 out:
216 if (pdata->rtc) 227 if (pdata->rtc)
217 rtc_device_unregister(pdata->rtc); 228 rtc_device_unregister(pdata->rtc);
218 if (ioaddr) 229 if (pdata->ioaddr_nvram)
219 iounmap(ioaddr); 230 iounmap(pdata->ioaddr_nvram);
220 if (pdata->baseaddr) 231 if (pdata->baseaddr)
221 release_mem_region(pdata->baseaddr, RTC_REG_SIZE); 232 release_mem_region(pdata->baseaddr, pdata->size);
222 kfree(pdata); 233 kfree(pdata);
223 return ret; 234 return ret;
224} 235}
@@ -229,8 +240,8 @@ static int __devexit ds1742_rtc_remove(struct platform_device *pdev)
229 240
230 sysfs_remove_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr); 241 sysfs_remove_bin_file(&pdev->dev.kobj, &ds1742_nvram_attr);
231 rtc_device_unregister(pdata->rtc); 242 rtc_device_unregister(pdata->rtc);
232 iounmap(pdata->ioaddr); 243 iounmap(pdata->ioaddr_nvram);
233 release_mem_region(pdata->baseaddr, RTC_REG_SIZE); 244 release_mem_region(pdata->baseaddr, pdata->size);
234 kfree(pdata); 245 kfree(pdata);
235 return 0; 246 return 0;
236} 247}