Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: add driver for RX6110SA real time clock

The RX6110 comes in two different variants: SPI and I2C.
This driver only supports the SPI variant.

If the need ever arises to also support the I2C variant, this driver
could easily be refactored to support both cases.

Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

authored by

Steffen Trumtrar and committed by
Alexandre Belloni
68298c2d cfe94162

+412
+9
drivers/rtc/Kconfig
··· 743 743 This driver can also be built as a module. If so the module 744 744 will be called rtc-rx4581. 745 745 746 + config RTC_DRV_RX6110 747 + tristate "Epson RX-6110" 748 + select REGMAP_SPI 749 + help 750 + If you say yes here you will get support for the Epson RX-6610. 751 + 752 + This driver can also be built as a module. If so the module 753 + will be called rtc-rx6110. 754 + 746 755 config RTC_DRV_MCP795 747 756 tristate "Microchip MCP795" 748 757 help
+1
drivers/rtc/Makefile
··· 127 127 obj-$(CONFIG_RTC_DRV_RV3029C2) += rtc-rv3029c2.o 128 128 obj-$(CONFIG_RTC_DRV_RV8803) += rtc-rv8803.o 129 129 obj-$(CONFIG_RTC_DRV_RX4581) += rtc-rx4581.o 130 + obj-$(CONFIG_RTC_DRV_RX6110) += rtc-rx6110.o 130 131 obj-$(CONFIG_RTC_DRV_RX8010) += rtc-rx8010.o 131 132 obj-$(CONFIG_RTC_DRV_RX8025) += rtc-rx8025.o 132 133 obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o
+402
drivers/rtc/rtc-rx6110.c
··· 1 + /* 2 + * Driver for the Epson RTC module RX-6110 SA 3 + * 4 + * Copyright(C) 2015 Pengutronix, Steffen Trumtrar <kernel@pengutronix.de> 5 + * Copyright(C) SEIKO EPSON CORPORATION 2013. All rights reserved. 6 + * 7 + * This driver software is distributed as is, without any warranty of any kind, 8 + * either express or implied as further specified in the GNU Public License. 9 + * This software may be used and distributed according to the terms of the GNU 10 + * Public License, version 2 as published by the Free Software Foundation. 11 + * See the file COPYING in the main directory of this archive for more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + 17 + #include <linux/bcd.h> 18 + #include <linux/init.h> 19 + #include <linux/kernel.h> 20 + #include <linux/module.h> 21 + #include <linux/of_gpio.h> 22 + #include <linux/regmap.h> 23 + #include <linux/rtc.h> 24 + #include <linux/spi/spi.h> 25 + 26 + /* RX-6110 Register definitions */ 27 + #define RX6110_REG_SEC 0x10 28 + #define RX6110_REG_MIN 0x11 29 + #define RX6110_REG_HOUR 0x12 30 + #define RX6110_REG_WDAY 0x13 31 + #define RX6110_REG_MDAY 0x14 32 + #define RX6110_REG_MONTH 0x15 33 + #define RX6110_REG_YEAR 0x16 34 + #define RX6110_REG_RES1 0x17 35 + #define RX6110_REG_ALMIN 0x18 36 + #define RX6110_REG_ALHOUR 0x19 37 + #define RX6110_REG_ALWDAY 0x1A 38 + #define RX6110_REG_TCOUNT0 0x1B 39 + #define RX6110_REG_TCOUNT1 0x1C 40 + #define RX6110_REG_EXT 0x1D 41 + #define RX6110_REG_FLAG 0x1E 42 + #define RX6110_REG_CTRL 0x1F 43 + #define RX6110_REG_USER0 0x20 44 + #define RX6110_REG_USER1 0x21 45 + #define RX6110_REG_USER2 0x22 46 + #define RX6110_REG_USER3 0x23 47 + #define RX6110_REG_USER4 0x24 48 + #define RX6110_REG_USER5 0x25 49 + #define RX6110_REG_USER6 0x26 50 + #define RX6110_REG_USER7 0x27 51 + #define RX6110_REG_USER8 0x28 52 + #define RX6110_REG_USER9 0x29 53 + #define RX6110_REG_USERA 0x2A 54 + #define RX6110_REG_USERB 0x2B 55 + #define RX6110_REG_USERC 0x2C 56 + #define RX6110_REG_USERD 0x2D 57 + #define RX6110_REG_USERE 0x2E 58 + #define RX6110_REG_USERF 0x2F 59 + #define RX6110_REG_RES2 0x30 60 + #define RX6110_REG_RES3 0x31 61 + #define RX6110_REG_IRQ 0x32 62 + 63 + #define RX6110_BIT_ALARM_EN BIT(7) 64 + 65 + /* Extension Register (1Dh) bit positions */ 66 + #define RX6110_BIT_EXT_TSEL0 BIT(0) 67 + #define RX6110_BIT_EXT_TSEL1 BIT(1) 68 + #define RX6110_BIT_EXT_TSEL2 BIT(2) 69 + #define RX6110_BIT_EXT_WADA BIT(3) 70 + #define RX6110_BIT_EXT_TE BIT(4) 71 + #define RX6110_BIT_EXT_USEL BIT(5) 72 + #define RX6110_BIT_EXT_FSEL0 BIT(6) 73 + #define RX6110_BIT_EXT_FSEL1 BIT(7) 74 + 75 + /* Flag Register (1Eh) bit positions */ 76 + #define RX6110_BIT_FLAG_VLF BIT(1) 77 + #define RX6110_BIT_FLAG_AF BIT(3) 78 + #define RX6110_BIT_FLAG_TF BIT(4) 79 + #define RX6110_BIT_FLAG_UF BIT(5) 80 + 81 + /* Control Register (1Fh) bit positions */ 82 + #define RX6110_BIT_CTRL_TBKE BIT(0) 83 + #define RX6110_BIT_CTRL_TBKON BIT(1) 84 + #define RX6110_BIT_CTRL_TSTP BIT(2) 85 + #define RX6110_BIT_CTRL_AIE BIT(3) 86 + #define RX6110_BIT_CTRL_TIE BIT(4) 87 + #define RX6110_BIT_CTRL_UIE BIT(5) 88 + #define RX6110_BIT_CTRL_STOP BIT(6) 89 + #define RX6110_BIT_CTRL_TEST BIT(7) 90 + 91 + enum { 92 + RTC_SEC = 0, 93 + RTC_MIN, 94 + RTC_HOUR, 95 + RTC_WDAY, 96 + RTC_MDAY, 97 + RTC_MONTH, 98 + RTC_YEAR, 99 + RTC_NR_TIME 100 + }; 101 + 102 + #define RX6110_DRIVER_NAME "rx6110" 103 + 104 + struct rx6110_data { 105 + struct rtc_device *rtc; 106 + struct regmap *regmap; 107 + }; 108 + 109 + /** 110 + * rx6110_rtc_tm_to_data - convert rtc_time to native time encoding 111 + * 112 + * @tm: holds date and time 113 + * @data: holds the encoding in rx6110 native form 114 + */ 115 + static int rx6110_rtc_tm_to_data(struct rtc_time *tm, u8 *data) 116 + { 117 + pr_debug("%s: date %ds %dm %dh %dmd %dm %dy\n", __func__, 118 + tm->tm_sec, tm->tm_min, tm->tm_hour, 119 + tm->tm_mday, tm->tm_mon, tm->tm_year); 120 + 121 + /* 122 + * The year in the RTC is a value between 0 and 99. 123 + * Assume that this represents the current century 124 + * and disregard all other values. 125 + */ 126 + if (tm->tm_year < 100 || tm->tm_year >= 200) 127 + return -EINVAL; 128 + 129 + data[RTC_SEC] = bin2bcd(tm->tm_sec); 130 + data[RTC_MIN] = bin2bcd(tm->tm_min); 131 + data[RTC_HOUR] = bin2bcd(tm->tm_hour); 132 + data[RTC_WDAY] = BIT(bin2bcd(tm->tm_wday)); 133 + data[RTC_MDAY] = bin2bcd(tm->tm_mday); 134 + data[RTC_MONTH] = bin2bcd(tm->tm_mon + 1); 135 + data[RTC_YEAR] = bin2bcd(tm->tm_year % 100); 136 + 137 + return 0; 138 + } 139 + 140 + /** 141 + * rx6110_data_to_rtc_tm - convert native time encoding to rtc_time 142 + * 143 + * @data: holds the encoding in rx6110 native form 144 + * @tm: holds date and time 145 + */ 146 + static int rx6110_data_to_rtc_tm(u8 *data, struct rtc_time *tm) 147 + { 148 + tm->tm_sec = bcd2bin(data[RTC_SEC] & 0x7f); 149 + tm->tm_min = bcd2bin(data[RTC_MIN] & 0x7f); 150 + /* only 24-hour clock */ 151 + tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f); 152 + tm->tm_wday = ffs(data[RTC_WDAY] & 0x7f); 153 + tm->tm_mday = bcd2bin(data[RTC_MDAY] & 0x3f); 154 + tm->tm_mon = bcd2bin(data[RTC_MONTH] & 0x1f) - 1; 155 + tm->tm_year = bcd2bin(data[RTC_YEAR]) + 100; 156 + 157 + pr_debug("%s: date %ds %dm %dh %dmd %dm %dy\n", __func__, 158 + tm->tm_sec, tm->tm_min, tm->tm_hour, 159 + tm->tm_mday, tm->tm_mon, tm->tm_year); 160 + 161 + /* 162 + * The year in the RTC is a value between 0 and 99. 163 + * Assume that this represents the current century 164 + * and disregard all other values. 165 + */ 166 + if (tm->tm_year < 100 || tm->tm_year >= 200) 167 + return -EINVAL; 168 + 169 + return 0; 170 + } 171 + 172 + /** 173 + * rx6110_set_time - set the current time in the rx6110 registers 174 + * 175 + * @dev: the rtc device in use 176 + * @tm: holds date and time 177 + * 178 + * BUG: The HW assumes every year that is a multiple of 4 to be a leap 179 + * year. Next time this is wrong is 2100, which will not be a leap year 180 + * 181 + * Note: If STOP is not set/cleared, the clock will start when the seconds 182 + * register is written 183 + * 184 + */ 185 + static int rx6110_set_time(struct device *dev, struct rtc_time *tm) 186 + { 187 + struct rx6110_data *rx6110 = dev_get_drvdata(dev); 188 + u8 data[RTC_NR_TIME]; 189 + int ret; 190 + 191 + ret = rx6110_rtc_tm_to_data(tm, data); 192 + if (ret < 0) 193 + return ret; 194 + 195 + /* set STOP bit before changing clock/calendar */ 196 + ret = regmap_update_bits(rx6110->regmap, RX6110_REG_CTRL, 197 + RX6110_BIT_CTRL_STOP, RX6110_BIT_CTRL_STOP); 198 + if (ret) 199 + return ret; 200 + 201 + ret = regmap_bulk_write(rx6110->regmap, RX6110_REG_SEC, data, 202 + RTC_NR_TIME); 203 + if (ret) 204 + return ret; 205 + 206 + /* The time in the RTC is valid. Be sure to have VLF cleared. */ 207 + ret = regmap_update_bits(rx6110->regmap, RX6110_REG_FLAG, 208 + RX6110_BIT_FLAG_VLF, 0); 209 + if (ret) 210 + return ret; 211 + 212 + /* clear STOP bit after changing clock/calendar */ 213 + ret = regmap_update_bits(rx6110->regmap, RX6110_REG_CTRL, 214 + RX6110_BIT_CTRL_STOP, 0); 215 + 216 + return ret; 217 + } 218 + 219 + /** 220 + * rx6110_get_time - get the current time from the rx6110 registers 221 + * @dev: the rtc device in use 222 + * @tm: holds date and time 223 + */ 224 + static int rx6110_get_time(struct device *dev, struct rtc_time *tm) 225 + { 226 + struct rx6110_data *rx6110 = dev_get_drvdata(dev); 227 + u8 data[RTC_NR_TIME]; 228 + int flags; 229 + int ret; 230 + 231 + ret = regmap_read(rx6110->regmap, RX6110_REG_FLAG, &flags); 232 + if (ret) 233 + return -EINVAL; 234 + 235 + /* check for VLF Flag (set at power-on) */ 236 + if ((flags & RX6110_BIT_FLAG_VLF)) { 237 + dev_warn(dev, "Voltage low, data is invalid.\n"); 238 + return -EINVAL; 239 + } 240 + 241 + /* read registers to date */ 242 + ret = regmap_bulk_read(rx6110->regmap, RX6110_REG_SEC, data, 243 + RTC_NR_TIME); 244 + if (ret) 245 + return ret; 246 + 247 + ret = rx6110_data_to_rtc_tm(data, tm); 248 + if (ret) 249 + return ret; 250 + 251 + dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__, 252 + tm->tm_sec, tm->tm_min, tm->tm_hour, 253 + tm->tm_mday, tm->tm_mon, tm->tm_year); 254 + 255 + return rtc_valid_tm(tm); 256 + } 257 + 258 + static const struct reg_sequence rx6110_default_regs[] = { 259 + { RX6110_REG_RES1, 0xB8 }, 260 + { RX6110_REG_RES2, 0x00 }, 261 + { RX6110_REG_RES3, 0x10 }, 262 + { RX6110_REG_IRQ, 0x00 }, 263 + { RX6110_REG_ALMIN, 0x00 }, 264 + { RX6110_REG_ALHOUR, 0x00 }, 265 + { RX6110_REG_ALWDAY, 0x00 }, 266 + }; 267 + 268 + /** 269 + * rx6110_init - initialize the rx6110 registers 270 + * 271 + * @rx6110: pointer to the rx6110 struct in use 272 + * 273 + */ 274 + static int rx6110_init(struct rx6110_data *rx6110) 275 + { 276 + struct rtc_device *rtc = rx6110->rtc; 277 + int flags; 278 + int ret; 279 + 280 + ret = regmap_update_bits(rx6110->regmap, RX6110_REG_EXT, 281 + RX6110_BIT_EXT_TE, 0); 282 + if (ret) 283 + return ret; 284 + 285 + ret = regmap_register_patch(rx6110->regmap, rx6110_default_regs, 286 + ARRAY_SIZE(rx6110_default_regs)); 287 + if (ret) 288 + return ret; 289 + 290 + ret = regmap_read(rx6110->regmap, RX6110_REG_FLAG, &flags); 291 + if (ret) 292 + return ret; 293 + 294 + /* check for VLF Flag (set at power-on) */ 295 + if ((flags & RX6110_BIT_FLAG_VLF)) 296 + dev_warn(&rtc->dev, "Voltage low, data loss detected.\n"); 297 + 298 + /* check for Alarm Flag */ 299 + if (flags & RX6110_BIT_FLAG_AF) 300 + dev_warn(&rtc->dev, "An alarm may have been missed.\n"); 301 + 302 + /* check for Periodic Timer Flag */ 303 + if (flags & RX6110_BIT_FLAG_TF) 304 + dev_warn(&rtc->dev, "Periodic timer was detected\n"); 305 + 306 + /* check for Update Timer Flag */ 307 + if (flags & RX6110_BIT_FLAG_UF) 308 + dev_warn(&rtc->dev, "Update timer was detected\n"); 309 + 310 + /* clear all flags BUT VLF */ 311 + ret = regmap_update_bits(rx6110->regmap, RX6110_REG_FLAG, 312 + RX6110_BIT_FLAG_AF | 313 + RX6110_BIT_FLAG_UF | 314 + RX6110_BIT_FLAG_TF, 315 + 0); 316 + 317 + return ret; 318 + } 319 + 320 + static struct rtc_class_ops rx6110_rtc_ops = { 321 + .read_time = rx6110_get_time, 322 + .set_time = rx6110_set_time, 323 + }; 324 + 325 + static struct regmap_config regmap_spi_config = { 326 + .reg_bits = 8, 327 + .val_bits = 8, 328 + .max_register = RX6110_REG_IRQ, 329 + .read_flag_mask = 0x80, 330 + }; 331 + 332 + /** 333 + * rx6110_probe - initialize rtc driver 334 + * @spi: pointer to spi device 335 + */ 336 + static int rx6110_probe(struct spi_device *spi) 337 + { 338 + struct rx6110_data *rx6110; 339 + int err; 340 + 341 + if ((spi->bits_per_word && spi->bits_per_word != 8) || 342 + (spi->max_speed_hz > 2000000) || 343 + (spi->mode != (SPI_CS_HIGH | SPI_CPOL | SPI_CPHA))) { 344 + dev_warn(&spi->dev, "SPI settings: bits_per_word: %d, max_speed_hz: %d, mode: %xh\n", 345 + spi->bits_per_word, spi->max_speed_hz, spi->mode); 346 + dev_warn(&spi->dev, "driving device in an unsupported mode"); 347 + } 348 + 349 + rx6110 = devm_kzalloc(&spi->dev, sizeof(*rx6110), GFP_KERNEL); 350 + if (!rx6110) 351 + return -ENOMEM; 352 + 353 + rx6110->regmap = devm_regmap_init_spi(spi, &regmap_spi_config); 354 + if (IS_ERR(rx6110->regmap)) { 355 + dev_err(&spi->dev, "regmap init failed for rtc rx6110\n"); 356 + return PTR_ERR(rx6110->regmap); 357 + } 358 + 359 + spi_set_drvdata(spi, rx6110); 360 + 361 + rx6110->rtc = devm_rtc_device_register(&spi->dev, 362 + RX6110_DRIVER_NAME, 363 + &rx6110_rtc_ops, THIS_MODULE); 364 + 365 + if (IS_ERR(rx6110->rtc)) 366 + return PTR_ERR(rx6110->rtc); 367 + 368 + err = rx6110_init(rx6110); 369 + if (err) 370 + return err; 371 + 372 + rx6110->rtc->max_user_freq = 1; 373 + 374 + return 0; 375 + } 376 + 377 + static int rx6110_remove(struct spi_device *spi) 378 + { 379 + return 0; 380 + } 381 + 382 + static const struct spi_device_id rx6110_id[] = { 383 + { "rx6110", 0 }, 384 + { } 385 + }; 386 + MODULE_DEVICE_TABLE(spi, rx6110_id); 387 + 388 + static struct spi_driver rx6110_driver = { 389 + .driver = { 390 + .name = RX6110_DRIVER_NAME, 391 + .owner = THIS_MODULE, 392 + }, 393 + .probe = rx6110_probe, 394 + .remove = rx6110_remove, 395 + .id_table = rx6110_id, 396 + }; 397 + 398 + module_spi_driver(rx6110_driver); 399 + 400 + MODULE_AUTHOR("Val Krutov <val.krutov@erd.epson.com>"); 401 + MODULE_DESCRIPTION("RX-6110 SA RTC driver"); 402 + MODULE_LICENSE("GPL");