.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * An I2C driver for the Philips PCF8563 RTC |
---|
3 | 4 | * Copyright 2005-06 Tower Technologies |
---|
.. | .. |
---|
8 | 9 | * based on the other drivers in this same directory. |
---|
9 | 10 | * |
---|
10 | 11 | * http://www.semiconductors.philips.com/acrobat/datasheets/PCF8563-04.pdf |
---|
11 | | - * |
---|
12 | | - * This program is free software; you can redistribute it and/or modify |
---|
13 | | - * it under the terms of the GNU General Public License version 2 as |
---|
14 | | - * published by the Free Software Foundation. |
---|
15 | 12 | */ |
---|
16 | 13 | |
---|
17 | 14 | #include <linux/clk-provider.h> |
---|
.. | .. |
---|
25 | 22 | |
---|
26 | 23 | #define PCF8563_REG_ST1 0x00 /* status */ |
---|
27 | 24 | #define PCF8563_REG_ST2 0x01 |
---|
28 | | -#define PCF8563_BIT_AIE (1 << 1) |
---|
29 | | -#define PCF8563_BIT_AF (1 << 3) |
---|
| 25 | +#define PCF8563_BIT_AIE BIT(1) |
---|
| 26 | +#define PCF8563_BIT_AF BIT(3) |
---|
30 | 27 | #define PCF8563_BITS_ST2_N (7 << 5) |
---|
31 | 28 | |
---|
32 | 29 | #define PCF8563_REG_SC 0x02 /* datetime */ |
---|
.. | .. |
---|
79 | 76 | * 1970...2069. |
---|
80 | 77 | */ |
---|
81 | 78 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ |
---|
82 | | - int voltage_low; /* incicates if a low_voltage was detected */ |
---|
83 | 79 | |
---|
84 | 80 | struct i2c_client *client; |
---|
85 | 81 | #ifdef CONFIG_COMMON_CLK |
---|
.. | .. |
---|
199 | 195 | * In the routines that deal directly with the pcf8563 hardware, we use |
---|
200 | 196 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. |
---|
201 | 197 | */ |
---|
202 | | -static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) |
---|
| 198 | +static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) |
---|
203 | 199 | { |
---|
| 200 | + struct i2c_client *client = to_i2c_client(dev); |
---|
204 | 201 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); |
---|
205 | 202 | unsigned char buf[9]; |
---|
206 | 203 | int err; |
---|
.. | .. |
---|
210 | 207 | return err; |
---|
211 | 208 | |
---|
212 | 209 | if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) { |
---|
213 | | - pcf8563->voltage_low = 1; |
---|
214 | 210 | dev_err(&client->dev, |
---|
215 | 211 | "low voltage detected, date/time is not reliable.\n"); |
---|
216 | 212 | return -EINVAL; |
---|
.. | .. |
---|
231 | 227 | tm->tm_mday = bcd2bin(buf[PCF8563_REG_DM] & 0x3F); |
---|
232 | 228 | tm->tm_wday = buf[PCF8563_REG_DW] & 0x07; |
---|
233 | 229 | tm->tm_mon = bcd2bin(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ |
---|
234 | | - tm->tm_year = bcd2bin(buf[PCF8563_REG_YR]); |
---|
235 | | - if (tm->tm_year < 70) |
---|
236 | | - tm->tm_year += 100; /* assume we are in 1970...2069 */ |
---|
| 230 | + tm->tm_year = bcd2bin(buf[PCF8563_REG_YR]) + 100; |
---|
237 | 231 | /* detect the polarity heuristically. see note above. */ |
---|
238 | 232 | pcf8563->c_polarity = (buf[PCF8563_REG_MO] & PCF8563_MO_C) ? |
---|
239 | 233 | (tm->tm_year >= 100) : (tm->tm_year < 100); |
---|
.. | .. |
---|
247 | 241 | return 0; |
---|
248 | 242 | } |
---|
249 | 243 | |
---|
250 | | -static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
---|
| 244 | +static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) |
---|
251 | 245 | { |
---|
| 246 | + struct i2c_client *client = to_i2c_client(dev); |
---|
252 | 247 | struct pcf8563 *pcf8563 = i2c_get_clientdata(client); |
---|
253 | 248 | unsigned char buf[9]; |
---|
254 | 249 | |
---|
.. | .. |
---|
269 | 264 | buf[PCF8563_REG_MO] = bin2bcd(tm->tm_mon + 1); |
---|
270 | 265 | |
---|
271 | 266 | /* year and century */ |
---|
272 | | - buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year % 100); |
---|
| 267 | + buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year - 100); |
---|
273 | 268 | if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100)) |
---|
274 | 269 | buf[PCF8563_REG_MO] |= PCF8563_MO_C; |
---|
275 | 270 | |
---|
.. | .. |
---|
279 | 274 | 9 - PCF8563_REG_SC, buf + PCF8563_REG_SC); |
---|
280 | 275 | } |
---|
281 | 276 | |
---|
282 | | -#ifdef CONFIG_RTC_INTF_DEV |
---|
283 | 277 | static int pcf8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
---|
284 | 278 | { |
---|
285 | | - struct pcf8563 *pcf8563 = i2c_get_clientdata(to_i2c_client(dev)); |
---|
286 | | - struct rtc_time tm; |
---|
| 279 | + struct i2c_client *client = to_i2c_client(dev); |
---|
| 280 | + int ret; |
---|
287 | 281 | |
---|
288 | 282 | switch (cmd) { |
---|
289 | 283 | case RTC_VL_READ: |
---|
290 | | - if (pcf8563->voltage_low) |
---|
291 | | - dev_info(dev, "low voltage detected, date/time is not reliable.\n"); |
---|
| 284 | + ret = i2c_smbus_read_byte_data(client, PCF8563_REG_SC); |
---|
| 285 | + if (ret < 0) |
---|
| 286 | + return ret; |
---|
292 | 287 | |
---|
293 | | - if (copy_to_user((void __user *)arg, &pcf8563->voltage_low, |
---|
294 | | - sizeof(int))) |
---|
295 | | - return -EFAULT; |
---|
296 | | - return 0; |
---|
297 | | - case RTC_VL_CLR: |
---|
298 | | - /* |
---|
299 | | - * Clear the VL bit in the seconds register in case |
---|
300 | | - * the time has not been set already (which would |
---|
301 | | - * have cleared it). This does not really matter |
---|
302 | | - * because of the cached voltage_low value but do it |
---|
303 | | - * anyway for consistency. |
---|
304 | | - */ |
---|
305 | | - if (pcf8563_get_datetime(to_i2c_client(dev), &tm)) |
---|
306 | | - pcf8563_set_datetime(to_i2c_client(dev), &tm); |
---|
307 | | - |
---|
308 | | - /* Clear the cached value. */ |
---|
309 | | - pcf8563->voltage_low = 0; |
---|
310 | | - |
---|
311 | | - return 0; |
---|
| 288 | + return put_user(ret & PCF8563_SC_LV ? RTC_VL_DATA_INVALID : 0, |
---|
| 289 | + (unsigned int __user *)arg); |
---|
312 | 290 | default: |
---|
313 | 291 | return -ENOIOCTLCMD; |
---|
314 | 292 | } |
---|
315 | | -} |
---|
316 | | -#else |
---|
317 | | -#define pcf8563_rtc_ioctl NULL |
---|
318 | | -#endif |
---|
319 | | - |
---|
320 | | -static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) |
---|
321 | | -{ |
---|
322 | | - return pcf8563_get_datetime(to_i2c_client(dev), tm); |
---|
323 | | -} |
---|
324 | | - |
---|
325 | | -static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) |
---|
326 | | -{ |
---|
327 | | - return pcf8563_set_datetime(to_i2c_client(dev), tm); |
---|
328 | 293 | } |
---|
329 | 294 | |
---|
330 | 295 | static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) |
---|
.. | .. |
---|
403 | 368 | |
---|
404 | 369 | #define clkout_hw_to_pcf8563(_hw) container_of(_hw, struct pcf8563, clkout_hw) |
---|
405 | 370 | |
---|
406 | | -static int clkout_rates[] = { |
---|
| 371 | +static const int clkout_rates[] = { |
---|
407 | 372 | 32768, |
---|
408 | 373 | 1024, |
---|
409 | 374 | 32, |
---|
.. | .. |
---|
513 | 478 | .set_rate = pcf8563_clkout_set_rate, |
---|
514 | 479 | }; |
---|
515 | 480 | |
---|
516 | | -static __maybe_unused struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563) |
---|
| 481 | +static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563) |
---|
517 | 482 | { |
---|
518 | 483 | struct i2c_client *client = pcf8563->client; |
---|
519 | 484 | struct device_node *node = client->dev.of_node; |
---|
.. | .. |
---|
594 | 559 | return err; |
---|
595 | 560 | } |
---|
596 | 561 | |
---|
597 | | - pcf8563->rtc = devm_rtc_device_register(&client->dev, |
---|
598 | | - pcf8563_driver.driver.name, |
---|
599 | | - &pcf8563_rtc_ops, THIS_MODULE); |
---|
600 | | - |
---|
| 562 | + pcf8563->rtc = devm_rtc_allocate_device(&client->dev); |
---|
601 | 563 | if (IS_ERR(pcf8563->rtc)) |
---|
602 | 564 | return PTR_ERR(pcf8563->rtc); |
---|
| 565 | + |
---|
| 566 | + pcf8563->rtc->ops = &pcf8563_rtc_ops; |
---|
| 567 | + /* the pcf8563 alarm only supports a minute accuracy */ |
---|
| 568 | + pcf8563->rtc->uie_unsupported = 1; |
---|
| 569 | + pcf8563->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; |
---|
| 570 | + pcf8563->rtc->range_max = RTC_TIMESTAMP_END_2099; |
---|
| 571 | + pcf8563->rtc->set_start_time = true; |
---|
603 | 572 | |
---|
604 | 573 | if (client->irq > 0) { |
---|
605 | 574 | err = devm_request_threaded_irq(&client->dev, client->irq, |
---|
.. | .. |
---|
611 | 580 | client->irq); |
---|
612 | 581 | return err; |
---|
613 | 582 | } |
---|
614 | | - |
---|
615 | 583 | } |
---|
616 | 584 | |
---|
617 | | -#if defined(CONFIG_COMMON_CLK) && !defined(CONFIG_ROCKCHIP_THUNDER_BOOT) |
---|
| 585 | + err = rtc_register_device(pcf8563->rtc); |
---|
| 586 | + if (err) |
---|
| 587 | + return err; |
---|
| 588 | + |
---|
| 589 | +#ifdef CONFIG_COMMON_CLK |
---|
618 | 590 | /* register clk in common clk framework */ |
---|
619 | 591 | pcf8563_clkout_register_clk(pcf8563); |
---|
620 | 592 | #endif |
---|
621 | | - |
---|
622 | | - /* the pcf8563 alarm only supports a minute accuracy */ |
---|
623 | | - pcf8563->rtc->uie_unsupported = 1; |
---|
624 | 593 | |
---|
625 | 594 | return 0; |
---|
626 | 595 | } |
---|
.. | .. |
---|
635 | 604 | #ifdef CONFIG_OF |
---|
636 | 605 | static const struct of_device_id pcf8563_of_match[] = { |
---|
637 | 606 | { .compatible = "nxp,pcf8563" }, |
---|
| 607 | + { .compatible = "epson,rtc8564" }, |
---|
| 608 | + { .compatible = "microcrystal,rv8564" }, |
---|
638 | 609 | {} |
---|
639 | 610 | }; |
---|
640 | 611 | MODULE_DEVICE_TABLE(of, pcf8563_of_match); |
---|