| .. | .. |
|---|
| 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); |
|---|