aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-ds2404.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-ds2404.c')
-rw-r--r--drivers/rtc/rtc-ds2404.c73
1 files changed, 22 insertions, 51 deletions
diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c
index b886b6a5c178..1e9f429ada64 100644
--- a/drivers/rtc/rtc-ds2404.c
+++ b/drivers/rtc/rtc-ds2404.c
@@ -1,11 +1,5 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * Copyright (C) 2012 Sven Schnelle <svens@stackframe.org> 2// Copyright (C) 2012 Sven Schnelle <svens@stackframe.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 */
9 3
10#include <linux/platform_device.h> 4#include <linux/platform_device.h>
11#include <linux/module.h> 5#include <linux/module.h>
@@ -29,14 +23,6 @@
29#define DS2404_COPY_SCRATCHPAD_CMD 0x55 23#define DS2404_COPY_SCRATCHPAD_CMD 0x55
30#define DS2404_READ_MEMORY_CMD 0xf0 24#define DS2404_READ_MEMORY_CMD 0xf0
31 25
32struct ds2404;
33
34struct ds2404_chip_ops {
35 int (*map_io)(struct ds2404 *chip, struct platform_device *pdev,
36 struct ds2404_platform_data *pdata);
37 void (*unmap_io)(struct ds2404 *chip);
38};
39
40#define DS2404_RST 0 26#define DS2404_RST 0
41#define DS2404_CLK 1 27#define DS2404_CLK 1
42#define DS2404_DQ 2 28#define DS2404_DQ 2
@@ -48,7 +34,6 @@ struct ds2404_gpio {
48 34
49struct ds2404 { 35struct ds2404 {
50 struct ds2404_gpio *gpio; 36 struct ds2404_gpio *gpio;
51 const struct ds2404_chip_ops *ops;
52 struct rtc_device *rtc; 37 struct rtc_device *rtc;
53}; 38};
54 39
@@ -87,7 +72,7 @@ err_request:
87 return err; 72 return err;
88} 73}
89 74
90static void ds2404_gpio_unmap(struct ds2404 *chip) 75static void ds2404_gpio_unmap(void *data)
91{ 76{
92 int i; 77 int i;
93 78
@@ -95,11 +80,6 @@ static void ds2404_gpio_unmap(struct ds2404 *chip)
95 gpio_free(ds2404_gpio[i].gpio); 80 gpio_free(ds2404_gpio[i].gpio);
96} 81}
97 82
98static const struct ds2404_chip_ops ds2404_gpio_ops = {
99 .map_io = ds2404_gpio_map,
100 .unmap_io = ds2404_gpio_unmap,
101};
102
103static void ds2404_reset(struct device *dev) 83static void ds2404_reset(struct device *dev)
104{ 84{
105 gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 0); 85 gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 0);
@@ -206,20 +186,20 @@ static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
206 ds2404_read_memory(dev, 0x203, 4, (u8 *)&time); 186 ds2404_read_memory(dev, 0x203, 4, (u8 *)&time);
207 time = le32_to_cpu(time); 187 time = le32_to_cpu(time);
208 188
209 rtc_time_to_tm(time, dt); 189 rtc_time64_to_tm(time, dt);
210 return 0; 190 return 0;
211} 191}
212 192
213static int ds2404_set_mmss(struct device *dev, unsigned long secs) 193static int ds2404_set_time(struct device *dev, struct rtc_time *dt)
214{ 194{
215 u32 time = cpu_to_le32(secs); 195 u32 time = cpu_to_le32(rtc_tm_to_time64(dt));
216 ds2404_write_memory(dev, 0x203, 4, (u8 *)&time); 196 ds2404_write_memory(dev, 0x203, 4, (u8 *)&time);
217 return 0; 197 return 0;
218} 198}
219 199
220static const struct rtc_class_ops ds2404_rtc_ops = { 200static const struct rtc_class_ops ds2404_rtc_ops = {
221 .read_time = ds2404_read_time, 201 .read_time = ds2404_read_time,
222 .set_mmss = ds2404_set_mmss, 202 .set_time = ds2404_set_time,
223}; 203};
224 204
225static int rtc_probe(struct platform_device *pdev) 205static int rtc_probe(struct platform_device *pdev)
@@ -232,11 +212,17 @@ static int rtc_probe(struct platform_device *pdev)
232 if (!chip) 212 if (!chip)
233 return -ENOMEM; 213 return -ENOMEM;
234 214
235 chip->ops = &ds2404_gpio_ops; 215 chip->rtc = devm_rtc_allocate_device(&pdev->dev);
216 if (IS_ERR(chip->rtc))
217 return PTR_ERR(chip->rtc);
236 218
237 retval = chip->ops->map_io(chip, pdev, pdata); 219 retval = ds2404_gpio_map(chip, pdev, pdata);
238 if (retval) 220 if (retval)
239 goto err_chip; 221 return retval;
222
223 retval = devm_add_action_or_reset(&pdev->dev, ds2404_gpio_unmap, chip);
224 if (retval)
225 return retval;
240 226
241 dev_info(&pdev->dev, "using GPIOs RST:%d, CLK:%d, DQ:%d\n", 227 dev_info(&pdev->dev, "using GPIOs RST:%d, CLK:%d, DQ:%d\n",
242 chip->gpio[DS2404_RST].gpio, chip->gpio[DS2404_CLK].gpio, 228 chip->gpio[DS2404_RST].gpio, chip->gpio[DS2404_CLK].gpio,
@@ -244,34 +230,19 @@ static int rtc_probe(struct platform_device *pdev)
244 230
245 platform_set_drvdata(pdev, chip); 231 platform_set_drvdata(pdev, chip);
246 232
247 chip->rtc = devm_rtc_device_register(&pdev->dev, "ds2404", 233 chip->rtc->ops = &ds2404_rtc_ops;
248 &ds2404_rtc_ops, THIS_MODULE); 234 chip->rtc->range_max = U32_MAX;
249 if (IS_ERR(chip->rtc)) {
250 retval = PTR_ERR(chip->rtc);
251 goto err_io;
252 }
253 235
254 ds2404_enable_osc(&pdev->dev); 236 retval = rtc_register_device(chip->rtc);
255 return 0; 237 if (retval)
256 238 return retval;
257err_io:
258 chip->ops->unmap_io(chip);
259err_chip:
260 return retval;
261}
262
263static int rtc_remove(struct platform_device *dev)
264{
265 struct ds2404 *chip = platform_get_drvdata(dev);
266
267 chip->ops->unmap_io(chip);
268 239
240 ds2404_enable_osc(&pdev->dev);
269 return 0; 241 return 0;
270} 242}
271 243
272static struct platform_driver rtc_device_driver = { 244static struct platform_driver rtc_device_driver = {
273 .probe = rtc_probe, 245 .probe = rtc_probe,
274 .remove = rtc_remove,
275 .driver = { 246 .driver = {
276 .name = "ds2404", 247 .name = "ds2404",
277 }, 248 },