| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for Epson RTC-9701JE |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 7 | 8 | * |
|---|
| 8 | 9 | * Copyright (C) 2006 8D Technologies inc. |
|---|
| 9 | 10 | * Copyright (C) 2004 Compulab Ltd. |
|---|
| 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 | 11 | */ |
|---|
| 15 | 12 | |
|---|
| 16 | 13 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 78 | 75 | if (ret) |
|---|
| 79 | 76 | return ret; |
|---|
| 80 | 77 | |
|---|
| 81 | | - memset(dt, 0, sizeof(*dt)); |
|---|
| 82 | | - |
|---|
| 83 | 78 | dt->tm_sec = bcd2bin(buf[0]); /* RSECCNT */ |
|---|
| 84 | 79 | dt->tm_min = bcd2bin(buf[1]); /* RMINCNT */ |
|---|
| 85 | 80 | dt->tm_hour = bcd2bin(buf[2]); /* RHRCNT */ |
|---|
| .. | .. |
|---|
| 88 | 83 | dt->tm_mon = bcd2bin(buf[4]) - 1; /* RMONCNT */ |
|---|
| 89 | 84 | dt->tm_year = bcd2bin(buf[5]) + 100; /* RYRCNT */ |
|---|
| 90 | 85 | |
|---|
| 91 | | - /* the rtc device may contain illegal values on power up |
|---|
| 92 | | - * according to the data sheet. make sure they are valid. |
|---|
| 93 | | - */ |
|---|
| 94 | | - |
|---|
| 95 | 86 | return 0; |
|---|
| 96 | 87 | } |
|---|
| 97 | 88 | |
|---|
| 98 | 89 | static int r9701_set_datetime(struct device *dev, struct rtc_time *dt) |
|---|
| 99 | 90 | { |
|---|
| 100 | | - int ret, year; |
|---|
| 101 | | - |
|---|
| 102 | | - year = dt->tm_year + 1900; |
|---|
| 103 | | - if (year >= 2100 || year < 2000) |
|---|
| 104 | | - return -EINVAL; |
|---|
| 91 | + int ret; |
|---|
| 105 | 92 | |
|---|
| 106 | 93 | ret = write_reg(dev, RHRCNT, bin2bcd(dt->tm_hour)); |
|---|
| 107 | 94 | ret = ret ? ret : write_reg(dev, RMINCNT, bin2bcd(dt->tm_min)); |
|---|
| .. | .. |
|---|
| 109 | 96 | ret = ret ? ret : write_reg(dev, RDAYCNT, bin2bcd(dt->tm_mday)); |
|---|
| 110 | 97 | ret = ret ? ret : write_reg(dev, RMONCNT, bin2bcd(dt->tm_mon + 1)); |
|---|
| 111 | 98 | ret = ret ? ret : write_reg(dev, RYRCNT, bin2bcd(dt->tm_year - 100)); |
|---|
| 112 | | - ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday); |
|---|
| 113 | 99 | |
|---|
| 114 | 100 | return ret; |
|---|
| 115 | 101 | } |
|---|
| .. | .. |
|---|
| 122 | 108 | static int r9701_probe(struct spi_device *spi) |
|---|
| 123 | 109 | { |
|---|
| 124 | 110 | struct rtc_device *rtc; |
|---|
| 125 | | - struct rtc_time dt; |
|---|
| 126 | 111 | unsigned char tmp; |
|---|
| 127 | 112 | int res; |
|---|
| 128 | 113 | |
|---|
| .. | .. |
|---|
| 133 | 118 | return -ENODEV; |
|---|
| 134 | 119 | } |
|---|
| 135 | 120 | |
|---|
| 136 | | - /* |
|---|
| 137 | | - * The device seems to be present. Now check if the registers |
|---|
| 138 | | - * contain invalid values. If so, try to write a default date: |
|---|
| 139 | | - * 2000/1/1 00:00:00 |
|---|
| 140 | | - */ |
|---|
| 141 | | - if (r9701_get_datetime(&spi->dev, &dt)) { |
|---|
| 142 | | - dev_info(&spi->dev, "trying to repair invalid date/time\n"); |
|---|
| 143 | | - dt.tm_sec = 0; |
|---|
| 144 | | - dt.tm_min = 0; |
|---|
| 145 | | - dt.tm_hour = 0; |
|---|
| 146 | | - dt.tm_mday = 1; |
|---|
| 147 | | - dt.tm_mon = 0; |
|---|
| 148 | | - dt.tm_year = 100; |
|---|
| 149 | | - |
|---|
| 150 | | - if (r9701_set_datetime(&spi->dev, &dt) || |
|---|
| 151 | | - r9701_get_datetime(&spi->dev, &dt)) { |
|---|
| 152 | | - dev_err(&spi->dev, "cannot repair RTC register\n"); |
|---|
| 153 | | - return -ENODEV; |
|---|
| 154 | | - } |
|---|
| 155 | | - } |
|---|
| 156 | | - |
|---|
| 157 | | - rtc = devm_rtc_device_register(&spi->dev, "r9701", |
|---|
| 158 | | - &r9701_rtc_ops, THIS_MODULE); |
|---|
| 121 | + rtc = devm_rtc_allocate_device(&spi->dev); |
|---|
| 159 | 122 | if (IS_ERR(rtc)) |
|---|
| 160 | 123 | return PTR_ERR(rtc); |
|---|
| 161 | 124 | |
|---|
| 162 | 125 | spi_set_drvdata(spi, rtc); |
|---|
| 126 | + rtc->ops = &r9701_rtc_ops; |
|---|
| 127 | + rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; |
|---|
| 128 | + rtc->range_max = RTC_TIMESTAMP_END_2099; |
|---|
| 163 | 129 | |
|---|
| 164 | | - return 0; |
|---|
| 130 | + return rtc_register_device(rtc); |
|---|
| 165 | 131 | } |
|---|
| 166 | 132 | |
|---|
| 167 | 133 | static struct spi_driver r9701_driver = { |
|---|