.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * RTC driver for the Micro Crystal RV8803 |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2015 Micro Crystal SA |
---|
5 | | - * |
---|
6 | | - * Alexandre Belloni <alexandre.belloni@free-electrons.com> |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License version 2 as |
---|
10 | | - * published by the Free Software Foundation. |
---|
| 6 | + * Alexandre Belloni <alexandre.belloni@bootlin.com> |
---|
11 | 7 | * |
---|
12 | 8 | */ |
---|
13 | 9 | |
---|
.. | .. |
---|
236 | 232 | u8 date[7]; |
---|
237 | 233 | int ctrl, flags, ret; |
---|
238 | 234 | |
---|
239 | | - if ((tm->tm_year < 100) || (tm->tm_year > 199)) |
---|
240 | | - return -EINVAL; |
---|
241 | | - |
---|
242 | 235 | ctrl = rv8803_read_reg(rv8803->client, RV8803_CTRL); |
---|
243 | 236 | if (ctrl < 0) |
---|
244 | 237 | return ctrl; |
---|
.. | .. |
---|
418 | 411 | { |
---|
419 | 412 | struct i2c_client *client = to_i2c_client(dev); |
---|
420 | 413 | struct rv8803_data *rv8803 = dev_get_drvdata(dev); |
---|
| 414 | + unsigned int vl = 0; |
---|
421 | 415 | int flags, ret = 0; |
---|
422 | 416 | |
---|
423 | 417 | switch (cmd) { |
---|
.. | .. |
---|
426 | 420 | if (flags < 0) |
---|
427 | 421 | return flags; |
---|
428 | 422 | |
---|
429 | | - if (flags & RV8803_FLAG_V1F) |
---|
| 423 | + if (flags & RV8803_FLAG_V1F) { |
---|
430 | 424 | dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n"); |
---|
| 425 | + vl = RTC_VL_ACCURACY_LOW; |
---|
| 426 | + } |
---|
431 | 427 | |
---|
432 | 428 | if (flags & RV8803_FLAG_V2F) |
---|
433 | | - dev_warn(&client->dev, "Voltage low, data loss detected.\n"); |
---|
| 429 | + vl |= RTC_VL_DATA_INVALID; |
---|
434 | 430 | |
---|
435 | | - flags &= RV8803_FLAG_V1F | RV8803_FLAG_V2F; |
---|
436 | | - |
---|
437 | | - if (copy_to_user((void __user *)arg, &flags, sizeof(int))) |
---|
438 | | - return -EFAULT; |
---|
439 | | - |
---|
440 | | - return 0; |
---|
| 431 | + return put_user(vl, (unsigned int __user *)arg); |
---|
441 | 432 | |
---|
442 | 433 | case RTC_VL_CLR: |
---|
443 | 434 | mutex_lock(&rv8803->flags_lock); |
---|
.. | .. |
---|
447 | 438 | return flags; |
---|
448 | 439 | } |
---|
449 | 440 | |
---|
450 | | - flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F); |
---|
| 441 | + flags &= ~RV8803_FLAG_V1F; |
---|
451 | 442 | ret = rv8803_write_reg(client, RV8803_FLAG, flags); |
---|
452 | 443 | mutex_unlock(&rv8803->flags_lock); |
---|
453 | 444 | if (ret) |
---|
.. | .. |
---|
463 | 454 | static int rv8803_nvram_write(void *priv, unsigned int offset, void *val, |
---|
464 | 455 | size_t bytes) |
---|
465 | 456 | { |
---|
466 | | - int ret; |
---|
467 | | - |
---|
468 | | - ret = rv8803_write_reg(priv, RV8803_RAM, *(u8 *)val); |
---|
469 | | - if (ret) |
---|
470 | | - return ret; |
---|
471 | | - |
---|
472 | | - return 0; |
---|
| 457 | + return rv8803_write_reg(priv, RV8803_RAM, *(u8 *)val); |
---|
473 | 458 | } |
---|
474 | 459 | |
---|
475 | 460 | static int rv8803_nvram_read(void *priv, unsigned int offset, |
---|
.. | .. |
---|
524 | 509 | static int rv8803_probe(struct i2c_client *client, |
---|
525 | 510 | const struct i2c_device_id *id) |
---|
526 | 511 | { |
---|
527 | | - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
---|
| 512 | + struct i2c_adapter *adapter = client->adapter; |
---|
528 | 513 | struct rv8803_data *rv8803; |
---|
529 | 514 | int err, flags; |
---|
530 | 515 | struct nvmem_config nvmem_cfg = { |
---|
.. | .. |
---|
571 | 556 | dev_warn(&client->dev, "An alarm maybe have been missed.\n"); |
---|
572 | 557 | |
---|
573 | 558 | rv8803->rtc = devm_rtc_allocate_device(&client->dev); |
---|
574 | | - if (IS_ERR(rv8803->rtc)) { |
---|
| 559 | + if (IS_ERR(rv8803->rtc)) |
---|
575 | 560 | return PTR_ERR(rv8803->rtc); |
---|
576 | | - } |
---|
577 | 561 | |
---|
578 | 562 | if (client->irq > 0) { |
---|
579 | 563 | err = devm_request_threaded_irq(&client->dev, client->irq, |
---|
.. | .. |
---|
602 | 586 | |
---|
603 | 587 | rv8803->rtc->ops = &rv8803_rtc_ops; |
---|
604 | 588 | rv8803->rtc->nvram_old_abi = true; |
---|
| 589 | + rv8803->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; |
---|
| 590 | + rv8803->rtc->range_max = RTC_TIMESTAMP_END_2099; |
---|
605 | 591 | err = rtc_register_device(rv8803->rtc); |
---|
606 | 592 | if (err) |
---|
607 | 593 | return err; |
---|
.. | .. |
---|
615 | 601 | |
---|
616 | 602 | static const struct i2c_device_id rv8803_id[] = { |
---|
617 | 603 | { "rv8803", rv_8803 }, |
---|
| 604 | + { "rx8803", rv_8803 }, |
---|
618 | 605 | { "rx8900", rx_8900 }, |
---|
619 | 606 | { } |
---|
620 | 607 | }; |
---|
.. | .. |
---|
623 | 610 | static const struct of_device_id rv8803_of_match[] = { |
---|
624 | 611 | { |
---|
625 | 612 | .compatible = "microcrystal,rv8803", |
---|
| 613 | + .data = (void *)rv_8803 |
---|
| 614 | + }, |
---|
| 615 | + { |
---|
| 616 | + .compatible = "epson,rx8803", |
---|
626 | 617 | .data = (void *)rv_8803 |
---|
627 | 618 | }, |
---|
628 | 619 | { |
---|
.. | .. |
---|
643 | 634 | }; |
---|
644 | 635 | module_i2c_driver(rv8803_driver); |
---|
645 | 636 | |
---|
646 | | -MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>"); |
---|
| 637 | +MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>"); |
---|
647 | 638 | MODULE_DESCRIPTION("Micro Crystal RV8803 RTC driver"); |
---|
648 | 639 | MODULE_LICENSE("GPL v2"); |
---|