aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-ds1672.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-ds1672.c')
-rw-r--r--drivers/rtc/rtc-ds1672.c127
1 files changed, 36 insertions, 91 deletions
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index b1ebca099b0d..e9e8d02743ee 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -1,12 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * An rtc/i2c driver for the Dallas DS1672 3 * An rtc/i2c driver for the Dallas DS1672
3 * Copyright 2005-06 Tower Technologies 4 * Copyright 2005-06 Tower Technologies
4 * 5 *
5 * Author: Alessandro Zummo <a.zummo@towertech.it> 6 * Author: Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */ 7 */
11 8
12#include <linux/i2c.h> 9#include <linux/i2c.h>
@@ -21,17 +18,16 @@
21 18
22#define DS1672_REG_CONTROL_EOSC 0x80 19#define DS1672_REG_CONTROL_EOSC 0x80
23 20
24static struct i2c_driver ds1672_driver;
25
26/* 21/*
27 * In the routines that deal directly with the ds1672 hardware, we use 22 * In the routines that deal directly with the ds1672 hardware, we use
28 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch 23 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
29 * Epoch is initialized as 2000. Time is set to UTC. 24 * Time is set to UTC.
30 */ 25 */
31static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) 26static int ds1672_read_time(struct device *dev, struct rtc_time *tm)
32{ 27{
28 struct i2c_client *client = to_i2c_client(dev);
33 unsigned long time; 29 unsigned long time;
34 unsigned char addr = DS1672_REG_CNT_BASE; 30 unsigned char addr = DS1672_REG_CONTROL;
35 unsigned char buf[4]; 31 unsigned char buf[4];
36 32
37 struct i2c_msg msgs[] = { 33 struct i2c_msg msgs[] = {
@@ -43,11 +39,25 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
43 {/* read date */ 39 {/* read date */
44 .addr = client->addr, 40 .addr = client->addr,
45 .flags = I2C_M_RD, 41 .flags = I2C_M_RD,
46 .len = 4, 42 .len = 1,
47 .buf = buf 43 .buf = buf
48 }, 44 },
49 }; 45 };
50 46
47 /* read control register */
48 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
49 dev_warn(&client->dev, "Unable to read the control register\n");
50 return -EIO;
51 }
52
53 if (buf[0] & DS1672_REG_CONTROL_EOSC) {
54 dev_warn(&client->dev, "Oscillator not enabled. Set time to enable.\n");
55 return -EINVAL;
56 }
57
58 addr = DS1672_REG_CNT_BASE;
59 msgs[1].len = 4;
60
51 /* read date registers */ 61 /* read date registers */
52 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { 62 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
53 dev_err(&client->dev, "%s: read error\n", __func__); 63 dev_err(&client->dev, "%s: read error\n", __func__);
@@ -61,20 +71,19 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
61 time = ((unsigned long)buf[3] << 24) | (buf[2] << 16) | 71 time = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
62 (buf[1] << 8) | buf[0]; 72 (buf[1] << 8) | buf[0];
63 73
64 rtc_time_to_tm(time, tm); 74 rtc_time64_to_tm(time, tm);
65 75
66 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " 76 dev_dbg(&client->dev, "%s: tm is %ptR\n", __func__, tm);
67 "mday=%d, mon=%d, year=%d, wday=%d\n",
68 __func__, tm->tm_sec, tm->tm_min, tm->tm_hour,
69 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
70 77
71 return 0; 78 return 0;
72} 79}
73 80
74static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) 81static int ds1672_set_time(struct device *dev, struct rtc_time *tm)
75{ 82{
83 struct i2c_client *client = to_i2c_client(dev);
76 int xfer; 84 int xfer;
77 unsigned char buf[6]; 85 unsigned char buf[6];
86 unsigned long secs = rtc_tm_to_time64(tm);
78 87
79 buf[0] = DS1672_REG_CNT_BASE; 88 buf[0] = DS1672_REG_CNT_BASE;
80 buf[1] = secs & 0x000000FF; 89 buf[1] = secs & 0x000000FF;
@@ -92,71 +101,15 @@ static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs)
92 return 0; 101 return 0;
93} 102}
94 103
95static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm)
96{
97 return ds1672_get_datetime(to_i2c_client(dev), tm);
98}
99
100static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs)
101{
102 return ds1672_set_mmss(to_i2c_client(dev), secs);
103}
104
105static int ds1672_get_control(struct i2c_client *client, u8 *status)
106{
107 unsigned char addr = DS1672_REG_CONTROL;
108
109 struct i2c_msg msgs[] = {
110 {/* setup read ptr */
111 .addr = client->addr,
112 .len = 1,
113 .buf = &addr
114 },
115 {/* read control */
116 .addr = client->addr,
117 .flags = I2C_M_RD,
118 .len = 1,
119 .buf = status
120 },
121 };
122
123 /* read control register */
124 if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
125 dev_err(&client->dev, "%s: read error\n", __func__);
126 return -EIO;
127 }
128
129 return 0;
130}
131
132/* following are the sysfs callback functions */
133static ssize_t show_control(struct device *dev, struct device_attribute *attr,
134 char *buf)
135{
136 struct i2c_client *client = to_i2c_client(dev);
137 u8 control;
138 int err;
139
140 err = ds1672_get_control(client, &control);
141 if (err)
142 return err;
143
144 return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC)
145 ? "disabled" : "enabled");
146}
147
148static DEVICE_ATTR(control, S_IRUGO, show_control, NULL);
149
150static const struct rtc_class_ops ds1672_rtc_ops = { 104static const struct rtc_class_ops ds1672_rtc_ops = {
151 .read_time = ds1672_rtc_read_time, 105 .read_time = ds1672_read_time,
152 .set_mmss = ds1672_rtc_set_mmss, 106 .set_time = ds1672_set_time,
153}; 107};
154 108
155static int ds1672_probe(struct i2c_client *client, 109static int ds1672_probe(struct i2c_client *client,
156 const struct i2c_device_id *id) 110 const struct i2c_device_id *id)
157{ 111{
158 int err = 0; 112 int err = 0;
159 u8 control;
160 struct rtc_device *rtc; 113 struct rtc_device *rtc;
161 114
162 dev_dbg(&client->dev, "%s\n", __func__); 115 dev_dbg(&client->dev, "%s\n", __func__);
@@ -164,29 +117,21 @@ static int ds1672_probe(struct i2c_client *client,
164 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 117 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
165 return -ENODEV; 118 return -ENODEV;
166 119
167 rtc = devm_rtc_device_register(&client->dev, ds1672_driver.driver.name, 120 rtc = devm_rtc_allocate_device(&client->dev);
168 &ds1672_rtc_ops, THIS_MODULE);
169
170 if (IS_ERR(rtc)) 121 if (IS_ERR(rtc))
171 return PTR_ERR(rtc); 122 return PTR_ERR(rtc);
172 123
173 i2c_set_clientdata(client, rtc); 124 rtc->ops = &ds1672_rtc_ops;
125 rtc->range_max = U32_MAX;
174 126
175 /* read control register */ 127 err = rtc_register_device(rtc);
176 err = ds1672_get_control(client, &control); 128 if (err)
177 if (err) { 129 return err;
178 dev_warn(&client->dev, "Unable to read the control register\n");
179 }
180 130
181 if (control & DS1672_REG_CONTROL_EOSC) 131 if (IS_ERR(rtc))
182 dev_warn(&client->dev, "Oscillator not enabled. " 132 return PTR_ERR(rtc);
183 "Set time to enable.\n");
184 133
185 /* Register sysfs hooks */ 134 i2c_set_clientdata(client, rtc);
186 err = device_create_file(&client->dev, &dev_attr_control);
187 if (err)
188 dev_err(&client->dev, "Unable to create sysfs entry: %s\n",
189 dev_attr_control.attr.name);
190 135
191 return 0; 136 return 0;
192} 137}