xref: /linux/drivers/rtc/rtc-isl12022.c (revision 78885597b9ccf68d4ce554aec98db01ee3c2d3fc)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * An I2C driver for the Intersil ISL 12022
4  *
5  * Author: Roman Fietze <roman.fietze@telemotive.de>
6  *
7  * Based on the Philips PCF8563 RTC
8  * by Alessandro Zummo <a.zummo@towertech.it>.
9  */
10 
11 #include <linux/bcd.h>
12 #include <linux/err.h>
13 #include <linux/hwmon.h>
14 #include <linux/i2c.h>
15 #include <linux/module.h>
16 #include <linux/regmap.h>
17 #include <linux/rtc.h>
18 #include <linux/slab.h>
19 
20 #include <asm/byteorder.h>
21 
22 /* ISL register offsets */
23 #define ISL12022_REG_SC		0x00
24 #define ISL12022_REG_MN		0x01
25 #define ISL12022_REG_HR		0x02
26 #define ISL12022_REG_DT		0x03
27 #define ISL12022_REG_MO		0x04
28 #define ISL12022_REG_YR		0x05
29 #define ISL12022_REG_DW		0x06
30 
31 #define ISL12022_REG_SR		0x07
32 #define ISL12022_REG_INT	0x08
33 
34 #define ISL12022_REG_BETA	0x0d
35 #define ISL12022_REG_TEMP_L	0x28
36 
37 /* ISL register bits */
38 #define ISL12022_HR_MIL		(1 << 7)	/* military or 24 hour time */
39 
40 #define ISL12022_SR_LBAT85	(1 << 2)
41 #define ISL12022_SR_LBAT75	(1 << 1)
42 
43 #define ISL12022_INT_WRTC	(1 << 6)
44 
45 #define ISL12022_BETA_TSE	(1 << 7)
46 
47 static umode_t isl12022_hwmon_is_visible(const void *data,
48 					 enum hwmon_sensor_types type,
49 					 u32 attr, int channel)
50 {
51 	if (type == hwmon_temp && attr == hwmon_temp_input)
52 		return 0444;
53 
54 	return 0;
55 }
56 
57 /*
58  * A user-initiated temperature conversion is not started by this function,
59  * so the temperature is updated once every ~60 seconds.
60  */
61 static int isl12022_hwmon_read_temp(struct device *dev, long *mC)
62 {
63 	struct regmap *regmap = dev_get_drvdata(dev);
64 	int temp, ret;
65 	__le16 buf;
66 
67 	ret = regmap_bulk_read(regmap, ISL12022_REG_TEMP_L, &buf, sizeof(buf));
68 	if (ret)
69 		return ret;
70 	/*
71 	 * Temperature is represented as a 10-bit number, unit half-Kelvins.
72 	 */
73 	temp = le16_to_cpu(buf);
74 	temp *= 500;
75 	temp -= 273000;
76 
77 	*mC = temp;
78 
79 	return 0;
80 }
81 
82 static int isl12022_hwmon_read(struct device *dev,
83 			       enum hwmon_sensor_types type,
84 			       u32 attr, int channel, long *val)
85 {
86 	if (type == hwmon_temp && attr == hwmon_temp_input)
87 		return isl12022_hwmon_read_temp(dev, val);
88 
89 	return -EOPNOTSUPP;
90 }
91 
92 static const struct hwmon_channel_info *isl12022_hwmon_info[] = {
93 	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
94 	NULL
95 };
96 
97 static const struct hwmon_ops isl12022_hwmon_ops = {
98 	.is_visible = isl12022_hwmon_is_visible,
99 	.read = isl12022_hwmon_read,
100 };
101 
102 static const struct hwmon_chip_info isl12022_hwmon_chip_info = {
103 	.ops = &isl12022_hwmon_ops,
104 	.info = isl12022_hwmon_info,
105 };
106 
107 static void isl12022_hwmon_register(struct device *dev)
108 {
109 	struct regmap *regmap = dev_get_drvdata(dev);
110 	struct device *hwmon;
111 	int ret;
112 
113 	if (!IS_REACHABLE(CONFIG_HWMON))
114 		return;
115 
116 	ret = regmap_update_bits(regmap, ISL12022_REG_BETA,
117 				 ISL12022_BETA_TSE, ISL12022_BETA_TSE);
118 	if (ret) {
119 		dev_warn(dev, "unable to enable temperature sensor\n");
120 		return;
121 	}
122 
123 	hwmon = devm_hwmon_device_register_with_info(dev, "isl12022", regmap,
124 						     &isl12022_hwmon_chip_info,
125 						     NULL);
126 	if (IS_ERR(hwmon))
127 		dev_warn(dev, "unable to register hwmon device: %pe\n", hwmon);
128 }
129 
130 /*
131  * In the routines that deal directly with the isl12022 hardware, we use
132  * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
133  */
134 static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm)
135 {
136 	struct regmap *regmap = dev_get_drvdata(dev);
137 	uint8_t buf[ISL12022_REG_INT + 1];
138 	int ret;
139 
140 	ret = regmap_bulk_read(regmap, ISL12022_REG_SC, buf, sizeof(buf));
141 	if (ret)
142 		return ret;
143 
144 	if (buf[ISL12022_REG_SR] & (ISL12022_SR_LBAT85 | ISL12022_SR_LBAT75)) {
145 		dev_warn(dev,
146 			 "voltage dropped below %u%%, date and time is not reliable.\n",
147 			 buf[ISL12022_REG_SR] & ISL12022_SR_LBAT85 ? 85 : 75);
148 	}
149 
150 	dev_dbg(dev,
151 		"raw data is sec=%02x, min=%02x, hr=%02x, mday=%02x, mon=%02x, year=%02x, wday=%02x, sr=%02x, int=%02x",
152 		buf[ISL12022_REG_SC],
153 		buf[ISL12022_REG_MN],
154 		buf[ISL12022_REG_HR],
155 		buf[ISL12022_REG_DT],
156 		buf[ISL12022_REG_MO],
157 		buf[ISL12022_REG_YR],
158 		buf[ISL12022_REG_DW],
159 		buf[ISL12022_REG_SR],
160 		buf[ISL12022_REG_INT]);
161 
162 	tm->tm_sec = bcd2bin(buf[ISL12022_REG_SC] & 0x7F);
163 	tm->tm_min = bcd2bin(buf[ISL12022_REG_MN] & 0x7F);
164 	tm->tm_hour = bcd2bin(buf[ISL12022_REG_HR] & 0x3F);
165 	tm->tm_mday = bcd2bin(buf[ISL12022_REG_DT] & 0x3F);
166 	tm->tm_wday = buf[ISL12022_REG_DW] & 0x07;
167 	tm->tm_mon = bcd2bin(buf[ISL12022_REG_MO] & 0x1F) - 1;
168 	tm->tm_year = bcd2bin(buf[ISL12022_REG_YR]) + 100;
169 
170 	dev_dbg(dev, "%s: %ptR\n", __func__, tm);
171 
172 	return 0;
173 }
174 
175 static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
176 {
177 	struct regmap *regmap = dev_get_drvdata(dev);
178 	int ret;
179 	uint8_t buf[ISL12022_REG_DW + 1];
180 
181 	dev_dbg(dev, "%s: %ptR\n", __func__, tm);
182 
183 	/* Ensure the write enable bit is set. */
184 	ret = regmap_update_bits(regmap, ISL12022_REG_INT,
185 				 ISL12022_INT_WRTC, ISL12022_INT_WRTC);
186 	if (ret)
187 		return ret;
188 
189 	/* hours, minutes and seconds */
190 	buf[ISL12022_REG_SC] = bin2bcd(tm->tm_sec);
191 	buf[ISL12022_REG_MN] = bin2bcd(tm->tm_min);
192 	buf[ISL12022_REG_HR] = bin2bcd(tm->tm_hour) | ISL12022_HR_MIL;
193 
194 	buf[ISL12022_REG_DT] = bin2bcd(tm->tm_mday);
195 
196 	/* month, 1 - 12 */
197 	buf[ISL12022_REG_MO] = bin2bcd(tm->tm_mon + 1);
198 
199 	/* year and century */
200 	buf[ISL12022_REG_YR] = bin2bcd(tm->tm_year % 100);
201 
202 	buf[ISL12022_REG_DW] = tm->tm_wday & 0x07;
203 
204 	return regmap_bulk_write(regmap, ISL12022_REG_SC, buf, sizeof(buf));
205 }
206 
207 static const struct rtc_class_ops isl12022_rtc_ops = {
208 	.read_time	= isl12022_rtc_read_time,
209 	.set_time	= isl12022_rtc_set_time,
210 };
211 
212 static const struct regmap_config regmap_config = {
213 	.reg_bits = 8,
214 	.val_bits = 8,
215 	.use_single_write = true,
216 };
217 
218 static int isl12022_probe(struct i2c_client *client)
219 {
220 	struct rtc_device *rtc;
221 	struct regmap *regmap;
222 
223 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
224 		return -ENODEV;
225 
226 	regmap = devm_regmap_init_i2c(client, &regmap_config);
227 	if (IS_ERR(regmap)) {
228 		dev_err(&client->dev, "regmap allocation failed\n");
229 		return PTR_ERR(regmap);
230 	}
231 
232 	dev_set_drvdata(&client->dev, regmap);
233 
234 	isl12022_hwmon_register(&client->dev);
235 
236 	rtc = devm_rtc_allocate_device(&client->dev);
237 	if (IS_ERR(rtc))
238 		return PTR_ERR(rtc);
239 
240 	rtc->ops = &isl12022_rtc_ops;
241 	rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
242 	rtc->range_max = RTC_TIMESTAMP_END_2099;
243 
244 	return devm_rtc_register_device(rtc);
245 }
246 
247 static const struct of_device_id isl12022_dt_match[] = {
248 	{ .compatible = "isl,isl12022" }, /* for backward compat., don't use */
249 	{ .compatible = "isil,isl12022" },
250 	{ },
251 };
252 MODULE_DEVICE_TABLE(of, isl12022_dt_match);
253 
254 static const struct i2c_device_id isl12022_id[] = {
255 	{ "isl12022", 0 },
256 	{ }
257 };
258 MODULE_DEVICE_TABLE(i2c, isl12022_id);
259 
260 static struct i2c_driver isl12022_driver = {
261 	.driver		= {
262 		.name	= "rtc-isl12022",
263 		.of_match_table = isl12022_dt_match,
264 	},
265 	.probe_new	= isl12022_probe,
266 	.id_table	= isl12022_id,
267 };
268 
269 module_i2c_driver(isl12022_driver);
270 
271 MODULE_AUTHOR("roman.fietze@telemotive.de");
272 MODULE_DESCRIPTION("ISL 12022 RTC driver");
273 MODULE_LICENSE("GPL");
274