aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlessandro Zummo <a.zummo@towertech.it>2009-01-06 17:42:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 18:59:24 -0500
commitf60091575d43e5a27b26f4d6fa4251cdd6b9ae8a (patch)
tree2f8435632ae5be00fb4ced024a7490e56094403c /drivers
parenta5771c6c42826556a73b16b66f93a0936ff87d4e (diff)
rtc: rtc-ds3234 fixes
- no changelogs in code - no banners - use local buffers - fix probe sequence - do not init .driver.bus Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Cc: Dennis Aberilla <denzzzhome@yahoo.com> Acked-by: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rtc/rtc-ds3234.c172
1 files changed, 36 insertions, 136 deletions
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c
index 45e5b106af73..c51589ede5b7 100644
--- a/drivers/rtc/rtc-ds3234.c
+++ b/drivers/rtc/rtc-ds3234.c
@@ -1,4 +1,4 @@
1/* drivers/rtc/rtc-ds3234.c 1/* rtc-ds3234.c
2 * 2 *
3 * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal 3 * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal
4 * and SRAM. 4 * and SRAM.
@@ -9,13 +9,10 @@
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 * 11 *
12 * Changelog:
13 *
14 * 07-May-2008: Dennis Aberilla <denzzzhome@yahoo.com>
15 * - Created based on the max6902 code. Only implements the
16 * date/time keeping functions; no SRAM yet.
17 */ 12 */
18 13
14#include <linux/init.h>
15#include <linux/module.h>
19#include <linux/device.h> 16#include <linux/device.h>
20#include <linux/platform_device.h> 17#include <linux/platform_device.h>
21#include <linux/rtc.h> 18#include <linux/rtc.h>
@@ -34,16 +31,7 @@
34#define DS3234_REG_CONTROL 0x0E 31#define DS3234_REG_CONTROL 0x0E
35#define DS3234_REG_CONT_STAT 0x0F 32#define DS3234_REG_CONT_STAT 0x0F
36 33
37#undef DS3234_DEBUG 34static int ds3234_set_reg(struct device *dev, unsigned char address,
38
39struct ds3234 {
40 struct rtc_device *rtc;
41 u8 buf[8]; /* Burst read: addr + 7 regs */
42 u8 tx_buf[2];
43 u8 rx_buf[2];
44};
45
46static void ds3234_set_reg(struct device *dev, unsigned char address,
47 unsigned char data) 35 unsigned char data)
48{ 36{
49 struct spi_device *spi = to_spi_device(dev); 37 struct spi_device *spi = to_spi_device(dev);
@@ -53,107 +41,45 @@ static void ds3234_set_reg(struct device *dev, unsigned char address,
53 buf[0] = address | 0x80; 41 buf[0] = address | 0x80;
54 buf[1] = data; 42 buf[1] = data;
55 43
56 spi_write(spi, buf, 2); 44 return spi_write_then_read(spi, buf, 2, NULL, 0);
57} 45}
58 46
59static int ds3234_get_reg(struct device *dev, unsigned char address, 47static int ds3234_get_reg(struct device *dev, unsigned char address,
60 unsigned char *data) 48 unsigned char *data)
61{ 49{
62 struct spi_device *spi = to_spi_device(dev); 50 struct spi_device *spi = to_spi_device(dev);
63 struct ds3234 *chip = dev_get_drvdata(dev);
64 struct spi_message message;
65 struct spi_transfer xfer;
66 int status;
67
68 if (!data)
69 return -EINVAL;
70
71 /* Build our spi message */
72 spi_message_init(&message);
73 memset(&xfer, 0, sizeof(xfer));
74
75 /* Address + dummy tx byte */
76 xfer.len = 2;
77 xfer.tx_buf = chip->tx_buf;
78 xfer.rx_buf = chip->rx_buf;
79
80 chip->tx_buf[0] = address;
81 chip->tx_buf[1] = 0xff;
82 51
83 spi_message_add_tail(&xfer, &message); 52 *data = address & 0x7f;
84 53
85 /* do the i/o */ 54 return spi_write_then_read(spi, data, 1, data, 1);
86 status = spi_sync(spi, &message);
87 if (status == 0)
88 status = message.status;
89 else
90 return status;
91
92 *data = chip->rx_buf[1];
93
94 return status;
95} 55}
96 56
97static int ds3234_get_datetime(struct device *dev, struct rtc_time *dt) 57static int ds3234_read_time(struct device *dev, struct rtc_time *dt)
98{ 58{
59 int err;
60 unsigned char buf[8];
99 struct spi_device *spi = to_spi_device(dev); 61 struct spi_device *spi = to_spi_device(dev);
100 struct ds3234 *chip = dev_get_drvdata(dev);
101 struct spi_message message;
102 struct spi_transfer xfer;
103 int status;
104
105 /* build the message */
106 spi_message_init(&message);
107 memset(&xfer, 0, sizeof(xfer));
108 xfer.len = 1 + 7; /* Addr + 7 registers */
109 xfer.tx_buf = chip->buf;
110 xfer.rx_buf = chip->buf;
111 chip->buf[0] = 0x00; /* Start address */
112 spi_message_add_tail(&xfer, &message);
113
114 /* do the i/o */
115 status = spi_sync(spi, &message);
116 if (status == 0)
117 status = message.status;
118 else
119 return status;
120 62
121 /* Seconds, Minutes, Hours, Day, Date, Month, Year */ 63 buf[0] = 0x00; /* Start address */
122 dt->tm_sec = bcd2bin(chip->buf[1]);
123 dt->tm_min = bcd2bin(chip->buf[2]);
124 dt->tm_hour = bcd2bin(chip->buf[3] & 0x3f);
125 dt->tm_wday = bcd2bin(chip->buf[4]) - 1; /* 0 = Sun */
126 dt->tm_mday = bcd2bin(chip->buf[5]);
127 dt->tm_mon = bcd2bin(chip->buf[6] & 0x1f) - 1; /* 0 = Jan */
128 dt->tm_year = bcd2bin(chip->buf[7] & 0xff) + 100; /* Assume 20YY */
129
130#ifdef DS3234_DEBUG
131 dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
132 dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
133 dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
134 dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
135 dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
136 dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
137 dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
138 dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
139#endif
140 64
141 return 0; 65 err = spi_write_then_read(spi, buf, 1, buf, 8);
66 if (err != 0)
67 return err;
68
69 /* Seconds, Minutes, Hours, Day, Date, Month, Year */
70 dt->tm_sec = bcd2bin(buf[0]);
71 dt->tm_min = bcd2bin(buf[1]);
72 dt->tm_hour = bcd2bin(buf[2] & 0x3f);
73 dt->tm_wday = bcd2bin(buf[3]) - 1; /* 0 = Sun */
74 dt->tm_mday = bcd2bin(buf[4]);
75 dt->tm_mon = bcd2bin(buf[5] & 0x1f) - 1; /* 0 = Jan */
76 dt->tm_year = bcd2bin(buf[6] & 0xff) + 100; /* Assume 20YY */
77
78 return rtc_valid_tm(dt);
142} 79}
143 80
144static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt) 81static int ds3234_set_time(struct device *dev, struct rtc_time *dt)
145{ 82{
146#ifdef DS3234_DEBUG
147 dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
148 dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
149 dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
150 dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
151 dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
152 dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
153 dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
154 dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
155#endif
156
157 ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec)); 83 ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec));
158 ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min)); 84 ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min));
159 ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f); 85 ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f);
@@ -174,16 +100,6 @@ static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt)
174 return 0; 100 return 0;
175} 101}
176 102
177static int ds3234_read_time(struct device *dev, struct rtc_time *tm)
178{
179 return ds3234_get_datetime(dev, tm);
180}
181
182static int ds3234_set_time(struct device *dev, struct rtc_time *tm)
183{
184 return ds3234_set_datetime(dev, tm);
185}
186
187static const struct rtc_class_ops ds3234_rtc_ops = { 103static const struct rtc_class_ops ds3234_rtc_ops = {
188 .read_time = ds3234_read_time, 104 .read_time = ds3234_read_time,
189 .set_time = ds3234_set_time, 105 .set_time = ds3234_set_time,
@@ -193,31 +109,15 @@ static int __devinit ds3234_probe(struct spi_device *spi)
193{ 109{
194 struct rtc_device *rtc; 110 struct rtc_device *rtc;
195 unsigned char tmp; 111 unsigned char tmp;
196 struct ds3234 *chip;
197 int res; 112 int res;
198 113
199 rtc = rtc_device_register("ds3234",
200 &spi->dev, &ds3234_rtc_ops, THIS_MODULE);
201 if (IS_ERR(rtc))
202 return PTR_ERR(rtc);
203
204 spi->mode = SPI_MODE_3; 114 spi->mode = SPI_MODE_3;
205 spi->bits_per_word = 8; 115 spi->bits_per_word = 8;
206 spi_setup(spi); 116 spi_setup(spi);
207 117
208 chip = kzalloc(sizeof(struct ds3234), GFP_KERNEL);
209 if (!chip) {
210 rtc_device_unregister(rtc);
211 return -ENOMEM;
212 }
213 chip->rtc = rtc;
214 dev_set_drvdata(&spi->dev, chip);
215
216 res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp); 118 res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp);
217 if (res) { 119 if (res != 0)
218 rtc_device_unregister(rtc);
219 return res; 120 return res;
220 }
221 121
222 /* Control settings 122 /* Control settings
223 * 123 *
@@ -246,26 +146,27 @@ static int __devinit ds3234_probe(struct spi_device *spi)
246 ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp); 146 ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
247 dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp); 147 dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
248 148
149 rtc = rtc_device_register("ds3234",
150 &spi->dev, &ds3234_rtc_ops, THIS_MODULE);
151 if (IS_ERR(rtc))
152 return PTR_ERR(rtc);
153
154 dev_set_drvdata(&spi->dev, rtc);
155
249 return 0; 156 return 0;
250} 157}
251 158
252static int __devexit ds3234_remove(struct spi_device *spi) 159static int __devexit ds3234_remove(struct spi_device *spi)
253{ 160{
254 struct ds3234 *chip = platform_get_drvdata(spi); 161 struct rtc_device *rtc = platform_get_drvdata(spi);
255 struct rtc_device *rtc = chip->rtc;
256
257 if (rtc)
258 rtc_device_unregister(rtc);
259
260 kfree(chip);
261 162
163 rtc_device_unregister(rtc);
262 return 0; 164 return 0;
263} 165}
264 166
265static struct spi_driver ds3234_driver = { 167static struct spi_driver ds3234_driver = {
266 .driver = { 168 .driver = {
267 .name = "ds3234", 169 .name = "ds3234",
268 .bus = &spi_bus_type,
269 .owner = THIS_MODULE, 170 .owner = THIS_MODULE,
270 }, 171 },
271 .probe = ds3234_probe, 172 .probe = ds3234_probe,
@@ -274,7 +175,6 @@ static struct spi_driver ds3234_driver = {
274 175
275static __init int ds3234_init(void) 176static __init int ds3234_init(void)
276{ 177{
277 printk(KERN_INFO "DS3234 SPI RTC Driver\n");
278 return spi_register_driver(&ds3234_driver); 178 return spi_register_driver(&ds3234_driver);
279} 179}
280module_init(ds3234_init); 180module_init(ds3234_init);