]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/rtc/rtc-pcf2127.c
netfilter: remove nf_ct_is_untracked
[mirror_ubuntu-artful-kernel.git] / drivers / rtc / rtc-pcf2127.c
CommitLineData
18cb6368 1/*
cee2cc21 2 * An I2C and SPI driver for the NXP PCF2127/29 RTC
18cb6368
RC
3 * Copyright 2013 Til-Technologies
4 *
5 * Author: Renaud Cerrato <r.cerrato@til-technologies.fr>
6 *
7 * based on the other drivers in this same directory.
8 *
cee2cc21 9 * Datasheet: http://cache.nxp.com/documents/data_sheet/PCF2127.pdf
18cb6368
RC
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/i2c.h>
9408ec1a 17#include <linux/spi/spi.h>
18cb6368
RC
18#include <linux/bcd.h>
19#include <linux/rtc.h>
20#include <linux/slab.h>
21#include <linux/module.h>
22#include <linux/of.h>
907b3262 23#include <linux/regmap.h>
18cb6368 24
18cb6368
RC
25#define PCF2127_REG_CTRL1 (0x00) /* Control Register 1 */
26#define PCF2127_REG_CTRL2 (0x01) /* Control Register 2 */
f97cfddc 27
18cb6368 28#define PCF2127_REG_CTRL3 (0x02) /* Control Register 3 */
f97cfddc
UKK
29#define PCF2127_REG_CTRL3_BLF BIT(2)
30
18cb6368
RC
31#define PCF2127_REG_SC (0x03) /* datetime */
32#define PCF2127_REG_MN (0x04)
33#define PCF2127_REG_HR (0x05)
34#define PCF2127_REG_DM (0x06)
35#define PCF2127_REG_DW (0x07)
36#define PCF2127_REG_MO (0x08)
37#define PCF2127_REG_YR (0x09)
38
653ebd75
AS
39#define PCF2127_OSF BIT(7) /* Oscillator Fail flag */
40
18cb6368
RC
41struct pcf2127 {
42 struct rtc_device *rtc;
907b3262 43 struct regmap *regmap;
18cb6368
RC
44};
45
46/*
47 * In the routines that deal directly with the pcf2127 hardware, we use
48 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
49 */
907b3262 50static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm)
18cb6368 51{
907b3262
AM
52 struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
53 unsigned char buf[10];
54 int ret;
3769a375 55 int i;
18cb6368 56
3769a375
SN
57 for (i = 0; i <= PCF2127_REG_CTRL3; i++) {
58 ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL1 + i,
59 (unsigned int *)(buf + i));
60 if (ret) {
61 dev_err(dev, "%s: read error\n", __func__);
62 return ret;
63 }
64 }
65
66 ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_SC,
67 (buf + PCF2127_REG_SC),
68 ARRAY_SIZE(buf) - PCF2127_REG_SC);
907b3262
AM
69 if (ret) {
70 dev_err(dev, "%s: read error\n", __func__);
71 return ret;
18cb6368
RC
72 }
73
f97cfddc 74 if (buf[PCF2127_REG_CTRL3] & PCF2127_REG_CTRL3_BLF)
907b3262 75 dev_info(dev,
653ebd75 76 "low voltage detected, check/replace RTC battery.\n");
653ebd75
AS
77
78 if (buf[PCF2127_REG_SC] & PCF2127_OSF) {
79 /*
80 * no need clear the flag here,
81 * it will be cleared once the new date is saved
82 */
907b3262 83 dev_warn(dev,
653ebd75
AS
84 "oscillator stop detected, date/time is not reliable\n");
85 return -EINVAL;
18cb6368
RC
86 }
87
907b3262 88 dev_dbg(dev,
18cb6368
RC
89 "%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, "
90 "sec=%02x, min=%02x, hr=%02x, "
91 "mday=%02x, wday=%02x, mon=%02x, year=%02x\n",
92 __func__,
93 buf[0], buf[1], buf[2],
94 buf[3], buf[4], buf[5],
95 buf[6], buf[7], buf[8], buf[9]);
96
97
98 tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F);
99 tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F);
100 tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F); /* rtc hr 0-23 */
101 tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F);
102 tm->tm_wday = buf[PCF2127_REG_DW] & 0x07;
103 tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
104 tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]);
105 if (tm->tm_year < 70)
106 tm->tm_year += 100; /* assume we are in 1970...2069 */
107
907b3262 108 dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
18cb6368
RC
109 "mday=%d, mon=%d, year=%d, wday=%d\n",
110 __func__,
111 tm->tm_sec, tm->tm_min, tm->tm_hour,
112 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
113
821f51c4 114 return rtc_valid_tm(tm);
18cb6368
RC
115}
116
907b3262 117static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm)
18cb6368 118{
907b3262
AM
119 struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
120 unsigned char buf[7];
18cb6368
RC
121 int i = 0, err;
122
907b3262 123 dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
18cb6368
RC
124 "mday=%d, mon=%d, year=%d, wday=%d\n",
125 __func__,
126 tm->tm_sec, tm->tm_min, tm->tm_hour,
127 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
128
18cb6368 129 /* hours, minutes and seconds */
653ebd75 130 buf[i++] = bin2bcd(tm->tm_sec); /* this will also clear OSF flag */
18cb6368
RC
131 buf[i++] = bin2bcd(tm->tm_min);
132 buf[i++] = bin2bcd(tm->tm_hour);
133 buf[i++] = bin2bcd(tm->tm_mday);
134 buf[i++] = tm->tm_wday & 0x07;
135
136 /* month, 1 - 12 */
137 buf[i++] = bin2bcd(tm->tm_mon + 1);
138
139 /* year */
140 buf[i++] = bin2bcd(tm->tm_year % 100);
141
142 /* write register's data */
907b3262
AM
143 err = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_SC, buf, i);
144 if (err) {
145 dev_err(dev,
18cb6368 146 "%s: err=%d", __func__, err);
907b3262 147 return err;
18cb6368
RC
148 }
149
150 return 0;
151}
152
153#ifdef CONFIG_RTC_INTF_DEV
154static int pcf2127_rtc_ioctl(struct device *dev,
155 unsigned int cmd, unsigned long arg)
156{
907b3262 157 struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
f97cfddc
UKK
158 int touser;
159 int ret;
18cb6368
RC
160
161 switch (cmd) {
162 case RTC_VL_READ:
907b3262
AM
163 ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &touser);
164 if (ret)
f97cfddc
UKK
165 return ret;
166
907b3262 167 touser = touser & PCF2127_REG_CTRL3_BLF ? 1 : 0;
18cb6368 168
f97cfddc 169 if (copy_to_user((void __user *)arg, &touser, sizeof(int)))
18cb6368
RC
170 return -EFAULT;
171 return 0;
172 default:
173 return -ENOIOCTLCMD;
174 }
175}
176#else
177#define pcf2127_rtc_ioctl NULL
178#endif
179
18cb6368
RC
180static const struct rtc_class_ops pcf2127_rtc_ops = {
181 .ioctl = pcf2127_rtc_ioctl,
182 .read_time = pcf2127_rtc_read_time,
183 .set_time = pcf2127_rtc_set_time,
184};
185
907b3262
AM
186static int pcf2127_probe(struct device *dev, struct regmap *regmap,
187 const char *name)
18cb6368
RC
188{
189 struct pcf2127 *pcf2127;
190
907b3262 191 dev_dbg(dev, "%s\n", __func__);
18cb6368 192
907b3262 193 pcf2127 = devm_kzalloc(dev, sizeof(*pcf2127), GFP_KERNEL);
18cb6368
RC
194 if (!pcf2127)
195 return -ENOMEM;
196
907b3262 197 pcf2127->regmap = regmap;
18cb6368 198
907b3262
AM
199 dev_set_drvdata(dev, pcf2127);
200
201 pcf2127->rtc = devm_rtc_device_register(dev, name, &pcf2127_rtc_ops,
202 THIS_MODULE);
18cb6368 203
7ab26cd1 204 return PTR_ERR_OR_ZERO(pcf2127->rtc);
18cb6368
RC
205}
206
18cb6368
RC
207#ifdef CONFIG_OF
208static const struct of_device_id pcf2127_of_match[] = {
209 { .compatible = "nxp,pcf2127" },
cee2cc21 210 { .compatible = "nxp,pcf2129" },
18cb6368
RC
211 {}
212};
213MODULE_DEVICE_TABLE(of, pcf2127_of_match);
214#endif
215
9408ec1a
AM
216#if IS_ENABLED(CONFIG_I2C)
217
907b3262
AM
218static int pcf2127_i2c_write(void *context, const void *data, size_t count)
219{
220 struct device *dev = context;
221 struct i2c_client *client = to_i2c_client(dev);
222 int ret;
223
224 ret = i2c_master_send(client, data, count);
225 if (ret != count)
226 return ret < 0 ? ret : -EIO;
227
228 return 0;
229}
230
231static int pcf2127_i2c_gather_write(void *context,
232 const void *reg, size_t reg_size,
233 const void *val, size_t val_size)
234{
235 struct device *dev = context;
236 struct i2c_client *client = to_i2c_client(dev);
237 int ret;
238 void *buf;
239
240 if (WARN_ON(reg_size != 1))
241 return -EINVAL;
242
243 buf = kmalloc(val_size + 1, GFP_KERNEL);
244 if (!buf)
245 return -ENOMEM;
246
247 memcpy(buf, reg, 1);
248 memcpy(buf + 1, val, val_size);
249
250 ret = i2c_master_send(client, buf, val_size + 1);
251 if (ret != val_size + 1)
252 return ret < 0 ? ret : -EIO;
253
254 return 0;
255}
256
257static int pcf2127_i2c_read(void *context, const void *reg, size_t reg_size,
258 void *val, size_t val_size)
259{
260 struct device *dev = context;
261 struct i2c_client *client = to_i2c_client(dev);
262 int ret;
263
264 if (WARN_ON(reg_size != 1))
265 return -EINVAL;
266
267 ret = i2c_master_send(client, reg, 1);
268 if (ret != 1)
269 return ret < 0 ? ret : -EIO;
270
271 ret = i2c_master_recv(client, val, val_size);
272 if (ret != val_size)
273 return ret < 0 ? ret : -EIO;
274
275 return 0;
276}
277
278/*
279 * The reason we need this custom regmap_bus instead of using regmap_init_i2c()
280 * is that the STOP condition is required between set register address and
281 * read register data when reading from registers.
282 */
283static const struct regmap_bus pcf2127_i2c_regmap = {
284 .write = pcf2127_i2c_write,
285 .gather_write = pcf2127_i2c_gather_write,
286 .read = pcf2127_i2c_read,
287};
288
289static struct i2c_driver pcf2127_i2c_driver;
290
291static int pcf2127_i2c_probe(struct i2c_client *client,
292 const struct i2c_device_id *id)
293{
294 struct regmap *regmap;
295 static const struct regmap_config config = {
296 .reg_bits = 8,
297 .val_bits = 8,
298 };
299
300 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
301 return -ENODEV;
302
303 regmap = devm_regmap_init(&client->dev, &pcf2127_i2c_regmap,
304 &client->dev, &config);
305 if (IS_ERR(regmap)) {
306 dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
307 __func__, PTR_ERR(regmap));
308 return PTR_ERR(regmap);
309 }
310
311 return pcf2127_probe(&client->dev, regmap,
312 pcf2127_i2c_driver.driver.name);
313}
314
315static const struct i2c_device_id pcf2127_i2c_id[] = {
316 { "pcf2127", 0 },
cee2cc21 317 { "pcf2129", 0 },
907b3262
AM
318 { }
319};
320MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id);
321
322static struct i2c_driver pcf2127_i2c_driver = {
18cb6368 323 .driver = {
907b3262 324 .name = "rtc-pcf2127-i2c",
18cb6368
RC
325 .of_match_table = of_match_ptr(pcf2127_of_match),
326 },
907b3262
AM
327 .probe = pcf2127_i2c_probe,
328 .id_table = pcf2127_i2c_id,
18cb6368 329};
9408ec1a
AM
330
331static int pcf2127_i2c_register_driver(void)
332{
333 return i2c_add_driver(&pcf2127_i2c_driver);
334}
335
336static void pcf2127_i2c_unregister_driver(void)
337{
338 i2c_del_driver(&pcf2127_i2c_driver);
339}
340
341#else
342
343static int pcf2127_i2c_register_driver(void)
344{
345 return 0;
346}
347
348static void pcf2127_i2c_unregister_driver(void)
349{
350}
351
352#endif
353
354#if IS_ENABLED(CONFIG_SPI_MASTER)
355
356static struct spi_driver pcf2127_spi_driver;
357
358static int pcf2127_spi_probe(struct spi_device *spi)
359{
360 static const struct regmap_config config = {
361 .reg_bits = 8,
362 .val_bits = 8,
363 .read_flag_mask = 0xa0,
364 .write_flag_mask = 0x20,
365 };
366 struct regmap *regmap;
367
368 regmap = devm_regmap_init_spi(spi, &config);
369 if (IS_ERR(regmap)) {
370 dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
371 __func__, PTR_ERR(regmap));
372 return PTR_ERR(regmap);
373 }
374
375 return pcf2127_probe(&spi->dev, regmap, pcf2127_spi_driver.driver.name);
376}
377
378static const struct spi_device_id pcf2127_spi_id[] = {
379 { "pcf2127", 0 },
cee2cc21 380 { "pcf2129", 0 },
9408ec1a
AM
381 { }
382};
383MODULE_DEVICE_TABLE(spi, pcf2127_spi_id);
384
385static struct spi_driver pcf2127_spi_driver = {
386 .driver = {
387 .name = "rtc-pcf2127-spi",
388 .of_match_table = of_match_ptr(pcf2127_of_match),
389 },
390 .probe = pcf2127_spi_probe,
391 .id_table = pcf2127_spi_id,
392};
393
394static int pcf2127_spi_register_driver(void)
395{
396 return spi_register_driver(&pcf2127_spi_driver);
397}
398
399static void pcf2127_spi_unregister_driver(void)
400{
401 spi_unregister_driver(&pcf2127_spi_driver);
402}
403
404#else
405
406static int pcf2127_spi_register_driver(void)
407{
408 return 0;
409}
410
411static void pcf2127_spi_unregister_driver(void)
412{
413}
414
415#endif
416
417static int __init pcf2127_init(void)
418{
419 int ret;
420
421 ret = pcf2127_i2c_register_driver();
422 if (ret) {
423 pr_err("Failed to register pcf2127 i2c driver: %d\n", ret);
424 return ret;
425 }
426
427 ret = pcf2127_spi_register_driver();
428 if (ret) {
429 pr_err("Failed to register pcf2127 spi driver: %d\n", ret);
430 pcf2127_i2c_unregister_driver();
431 }
432
433 return ret;
434}
435module_init(pcf2127_init)
436
437static void __exit pcf2127_exit(void)
438{
439 pcf2127_spi_unregister_driver();
440 pcf2127_i2c_unregister_driver();
441}
442module_exit(pcf2127_exit)
18cb6368
RC
443
444MODULE_AUTHOR("Renaud Cerrato <r.cerrato@til-technologies.fr>");
cee2cc21 445MODULE_DESCRIPTION("NXP PCF2127/29 RTC driver");
4d8318bc 446MODULE_LICENSE("GPL v2");