1e6e7376cSAlexandre Belloni // SPDX-License-Identifier: GPL-2.0 2e6e7376cSAlexandre Belloni /* 3e6e7376cSAlexandre Belloni * RTC driver for the Micro Crystal RV3028 4e6e7376cSAlexandre Belloni * 5e6e7376cSAlexandre Belloni * Copyright (C) 2019 Micro Crystal SA 6e6e7376cSAlexandre Belloni * 7e6e7376cSAlexandre Belloni * Alexandre Belloni <alexandre.belloni@bootlin.com> 8e6e7376cSAlexandre Belloni * 9e6e7376cSAlexandre Belloni */ 10e6e7376cSAlexandre Belloni 11e6e7376cSAlexandre Belloni #include <linux/bcd.h> 12e6e7376cSAlexandre Belloni #include <linux/bitops.h> 13e6e7376cSAlexandre Belloni #include <linux/i2c.h> 14e6e7376cSAlexandre Belloni #include <linux/interrupt.h> 15e6e7376cSAlexandre Belloni #include <linux/kernel.h> 16e6e7376cSAlexandre Belloni #include <linux/log2.h> 17e6e7376cSAlexandre Belloni #include <linux/module.h> 18e6e7376cSAlexandre Belloni #include <linux/of_device.h> 19e6e7376cSAlexandre Belloni #include <linux/regmap.h> 20e6e7376cSAlexandre Belloni #include <linux/rtc.h> 21e6e7376cSAlexandre Belloni 22e6e7376cSAlexandre Belloni #define RV3028_SEC 0x00 23e6e7376cSAlexandre Belloni #define RV3028_MIN 0x01 24e6e7376cSAlexandre Belloni #define RV3028_HOUR 0x02 25e6e7376cSAlexandre Belloni #define RV3028_WDAY 0x03 26e6e7376cSAlexandre Belloni #define RV3028_DAY 0x04 27e6e7376cSAlexandre Belloni #define RV3028_MONTH 0x05 28e6e7376cSAlexandre Belloni #define RV3028_YEAR 0x06 29e6e7376cSAlexandre Belloni #define RV3028_ALARM_MIN 0x07 30e6e7376cSAlexandre Belloni #define RV3028_ALARM_HOUR 0x08 31e6e7376cSAlexandre Belloni #define RV3028_ALARM_DAY 0x09 32e6e7376cSAlexandre Belloni #define RV3028_STATUS 0x0E 33e6e7376cSAlexandre Belloni #define RV3028_CTRL1 0x0F 34e6e7376cSAlexandre Belloni #define RV3028_CTRL2 0x10 35e6e7376cSAlexandre Belloni #define RV3028_EVT_CTRL 0x13 36e6e7376cSAlexandre Belloni #define RV3028_TS_COUNT 0x14 37e6e7376cSAlexandre Belloni #define RV3028_TS_SEC 0x15 38e6e7376cSAlexandre Belloni #define RV3028_RAM1 0x1F 39e6e7376cSAlexandre Belloni #define RV3028_EEPROM_ADDR 0x25 40e6e7376cSAlexandre Belloni #define RV3028_EEPROM_DATA 0x26 41e6e7376cSAlexandre Belloni #define RV3028_EEPROM_CMD 0x27 42e6e7376cSAlexandre Belloni #define RV3028_CLKOUT 0x35 43e6e7376cSAlexandre Belloni #define RV3028_OFFSET 0x36 44e6e7376cSAlexandre Belloni #define RV3028_BACKUP 0x37 45e6e7376cSAlexandre Belloni 46e6e7376cSAlexandre Belloni #define RV3028_STATUS_PORF BIT(0) 47e6e7376cSAlexandre Belloni #define RV3028_STATUS_EVF BIT(1) 48e6e7376cSAlexandre Belloni #define RV3028_STATUS_AF BIT(2) 49e6e7376cSAlexandre Belloni #define RV3028_STATUS_TF BIT(3) 50e6e7376cSAlexandre Belloni #define RV3028_STATUS_UF BIT(4) 51e6e7376cSAlexandre Belloni #define RV3028_STATUS_BSF BIT(5) 52e6e7376cSAlexandre Belloni #define RV3028_STATUS_CLKF BIT(6) 53e6e7376cSAlexandre Belloni #define RV3028_STATUS_EEBUSY BIT(7) 54e6e7376cSAlexandre Belloni 55e6e7376cSAlexandre Belloni #define RV3028_CTRL1_EERD BIT(3) 56e6e7376cSAlexandre Belloni #define RV3028_CTRL1_WADA BIT(5) 57e6e7376cSAlexandre Belloni 58e6e7376cSAlexandre Belloni #define RV3028_CTRL2_RESET BIT(0) 59e6e7376cSAlexandre Belloni #define RV3028_CTRL2_12_24 BIT(1) 60e6e7376cSAlexandre Belloni #define RV3028_CTRL2_EIE BIT(2) 61e6e7376cSAlexandre Belloni #define RV3028_CTRL2_AIE BIT(3) 62e6e7376cSAlexandre Belloni #define RV3028_CTRL2_TIE BIT(4) 63e6e7376cSAlexandre Belloni #define RV3028_CTRL2_UIE BIT(5) 64e6e7376cSAlexandre Belloni #define RV3028_CTRL2_TSE BIT(7) 65e6e7376cSAlexandre Belloni 66e6e7376cSAlexandre Belloni #define RV3028_EVT_CTRL_TSR BIT(2) 67e6e7376cSAlexandre Belloni 68e6e7376cSAlexandre Belloni #define RV3028_EEPROM_CMD_WRITE 0x21 69e6e7376cSAlexandre Belloni #define RV3028_EEPROM_CMD_READ 0x22 70e6e7376cSAlexandre Belloni 71e6e7376cSAlexandre Belloni #define RV3028_EEBUSY_POLL 10000 72e6e7376cSAlexandre Belloni #define RV3028_EEBUSY_TIMEOUT 100000 73e6e7376cSAlexandre Belloni 74e6e7376cSAlexandre Belloni #define RV3028_BACKUP_TCE BIT(5) 75e6e7376cSAlexandre Belloni #define RV3028_BACKUP_TCR_MASK GENMASK(1,0) 76e6e7376cSAlexandre Belloni 77e6e7376cSAlexandre Belloni #define OFFSET_STEP_PPT 953674 78e6e7376cSAlexandre Belloni 79e6e7376cSAlexandre Belloni enum rv3028_type { 80e6e7376cSAlexandre Belloni rv_3028, 81e6e7376cSAlexandre Belloni }; 82e6e7376cSAlexandre Belloni 83e6e7376cSAlexandre Belloni struct rv3028_data { 84e6e7376cSAlexandre Belloni struct regmap *regmap; 85e6e7376cSAlexandre Belloni struct rtc_device *rtc; 86e6e7376cSAlexandre Belloni enum rv3028_type type; 87e6e7376cSAlexandre Belloni }; 88e6e7376cSAlexandre Belloni 89e6e7376cSAlexandre Belloni static u16 rv3028_trickle_resistors[] = {1000, 3000, 6000, 11000}; 90e6e7376cSAlexandre Belloni 91e6e7376cSAlexandre Belloni static ssize_t timestamp0_store(struct device *dev, 92e6e7376cSAlexandre Belloni struct device_attribute *attr, 93e6e7376cSAlexandre Belloni const char *buf, size_t count) 94e6e7376cSAlexandre Belloni { 95e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); 96e6e7376cSAlexandre Belloni 97e6e7376cSAlexandre Belloni regmap_update_bits(rv3028->regmap, RV3028_EVT_CTRL, RV3028_EVT_CTRL_TSR, 98e6e7376cSAlexandre Belloni RV3028_EVT_CTRL_TSR); 99e6e7376cSAlexandre Belloni 100e6e7376cSAlexandre Belloni return count; 101e6e7376cSAlexandre Belloni }; 102e6e7376cSAlexandre Belloni 103e6e7376cSAlexandre Belloni static ssize_t timestamp0_show(struct device *dev, 104e6e7376cSAlexandre Belloni struct device_attribute *attr, char *buf) 105e6e7376cSAlexandre Belloni { 106e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); 107e6e7376cSAlexandre Belloni struct rtc_time tm; 108e6e7376cSAlexandre Belloni int ret, count; 109e6e7376cSAlexandre Belloni u8 date[6]; 110e6e7376cSAlexandre Belloni 111e6e7376cSAlexandre Belloni ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count); 112e6e7376cSAlexandre Belloni if (ret) 113e6e7376cSAlexandre Belloni return ret; 114e6e7376cSAlexandre Belloni 115e6e7376cSAlexandre Belloni if (!count) 116e6e7376cSAlexandre Belloni return 0; 117e6e7376cSAlexandre Belloni 118e6e7376cSAlexandre Belloni ret = regmap_bulk_read(rv3028->regmap, RV3028_TS_SEC, date, 119e6e7376cSAlexandre Belloni sizeof(date)); 120e6e7376cSAlexandre Belloni if (ret) 121e6e7376cSAlexandre Belloni return ret; 122e6e7376cSAlexandre Belloni 123e6e7376cSAlexandre Belloni tm.tm_sec = bcd2bin(date[0]); 124e6e7376cSAlexandre Belloni tm.tm_min = bcd2bin(date[1]); 125e6e7376cSAlexandre Belloni tm.tm_hour = bcd2bin(date[2]); 126e6e7376cSAlexandre Belloni tm.tm_mday = bcd2bin(date[3]); 127e6e7376cSAlexandre Belloni tm.tm_mon = bcd2bin(date[4]) - 1; 128e6e7376cSAlexandre Belloni tm.tm_year = bcd2bin(date[5]) + 100; 129e6e7376cSAlexandre Belloni 130e6e7376cSAlexandre Belloni ret = rtc_valid_tm(&tm); 131e6e7376cSAlexandre Belloni if (ret) 132e6e7376cSAlexandre Belloni return ret; 133e6e7376cSAlexandre Belloni 134e6e7376cSAlexandre Belloni return sprintf(buf, "%llu\n", 135e6e7376cSAlexandre Belloni (unsigned long long)rtc_tm_to_time64(&tm)); 136e6e7376cSAlexandre Belloni }; 137e6e7376cSAlexandre Belloni 138e6e7376cSAlexandre Belloni static DEVICE_ATTR_RW(timestamp0); 139e6e7376cSAlexandre Belloni 140e6e7376cSAlexandre Belloni static ssize_t timestamp0_count_show(struct device *dev, 141e6e7376cSAlexandre Belloni struct device_attribute *attr, char *buf) 142e6e7376cSAlexandre Belloni { 143e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); 144e6e7376cSAlexandre Belloni int ret, count; 145e6e7376cSAlexandre Belloni 146e6e7376cSAlexandre Belloni ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count); 147e6e7376cSAlexandre Belloni if (ret) 148e6e7376cSAlexandre Belloni return ret; 149e6e7376cSAlexandre Belloni 150e6e7376cSAlexandre Belloni return sprintf(buf, "%u\n", count); 151e6e7376cSAlexandre Belloni }; 152e6e7376cSAlexandre Belloni 153e6e7376cSAlexandre Belloni static DEVICE_ATTR_RO(timestamp0_count); 154e6e7376cSAlexandre Belloni 155e6e7376cSAlexandre Belloni static struct attribute *rv3028_attrs[] = { 156e6e7376cSAlexandre Belloni &dev_attr_timestamp0.attr, 157e6e7376cSAlexandre Belloni &dev_attr_timestamp0_count.attr, 158e6e7376cSAlexandre Belloni NULL 159e6e7376cSAlexandre Belloni }; 160e6e7376cSAlexandre Belloni 161e6e7376cSAlexandre Belloni static const struct attribute_group rv3028_attr_group = { 162e6e7376cSAlexandre Belloni .attrs = rv3028_attrs, 163e6e7376cSAlexandre Belloni }; 164e6e7376cSAlexandre Belloni 165e6e7376cSAlexandre Belloni static irqreturn_t rv3028_handle_irq(int irq, void *dev_id) 166e6e7376cSAlexandre Belloni { 167e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_id; 168e6e7376cSAlexandre Belloni unsigned long events = 0; 169e6e7376cSAlexandre Belloni u32 status = 0, ctrl = 0; 170e6e7376cSAlexandre Belloni 171e6e7376cSAlexandre Belloni if (regmap_read(rv3028->regmap, RV3028_STATUS, &status) < 0 || 172e6e7376cSAlexandre Belloni status == 0) { 173e6e7376cSAlexandre Belloni return IRQ_NONE; 174e6e7376cSAlexandre Belloni } 175e6e7376cSAlexandre Belloni 176e6e7376cSAlexandre Belloni if (status & RV3028_STATUS_PORF) 177e6e7376cSAlexandre Belloni dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n"); 178e6e7376cSAlexandre Belloni 179e6e7376cSAlexandre Belloni if (status & RV3028_STATUS_TF) { 180e6e7376cSAlexandre Belloni status |= RV3028_STATUS_TF; 181e6e7376cSAlexandre Belloni ctrl |= RV3028_CTRL2_TIE; 182e6e7376cSAlexandre Belloni events |= RTC_PF; 183e6e7376cSAlexandre Belloni } 184e6e7376cSAlexandre Belloni 185e6e7376cSAlexandre Belloni if (status & RV3028_STATUS_AF) { 186e6e7376cSAlexandre Belloni status |= RV3028_STATUS_AF; 187e6e7376cSAlexandre Belloni ctrl |= RV3028_CTRL2_AIE; 188e6e7376cSAlexandre Belloni events |= RTC_AF; 189e6e7376cSAlexandre Belloni } 190e6e7376cSAlexandre Belloni 191e6e7376cSAlexandre Belloni if (status & RV3028_STATUS_UF) { 192e6e7376cSAlexandre Belloni status |= RV3028_STATUS_UF; 193e6e7376cSAlexandre Belloni ctrl |= RV3028_CTRL2_UIE; 194e6e7376cSAlexandre Belloni events |= RTC_UF; 195e6e7376cSAlexandre Belloni } 196e6e7376cSAlexandre Belloni 197e6e7376cSAlexandre Belloni if (events) { 198e6e7376cSAlexandre Belloni rtc_update_irq(rv3028->rtc, 1, events); 199e6e7376cSAlexandre Belloni regmap_update_bits(rv3028->regmap, RV3028_STATUS, status, 0); 200e6e7376cSAlexandre Belloni regmap_update_bits(rv3028->regmap, RV3028_CTRL2, ctrl, 0); 201e6e7376cSAlexandre Belloni } 202e6e7376cSAlexandre Belloni 203e6e7376cSAlexandre Belloni if (status & RV3028_STATUS_EVF) { 204e6e7376cSAlexandre Belloni sysfs_notify(&rv3028->rtc->dev.kobj, NULL, 205e6e7376cSAlexandre Belloni dev_attr_timestamp0.attr.name); 206e6e7376cSAlexandre Belloni dev_warn(&rv3028->rtc->dev, "event detected"); 207e6e7376cSAlexandre Belloni } 208e6e7376cSAlexandre Belloni 209e6e7376cSAlexandre Belloni return IRQ_HANDLED; 210e6e7376cSAlexandre Belloni } 211e6e7376cSAlexandre Belloni 212e6e7376cSAlexandre Belloni static int rv3028_get_time(struct device *dev, struct rtc_time *tm) 213e6e7376cSAlexandre Belloni { 214e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev); 215e6e7376cSAlexandre Belloni u8 date[7]; 216e6e7376cSAlexandre Belloni int ret, status; 217e6e7376cSAlexandre Belloni 218e6e7376cSAlexandre Belloni ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); 219e6e7376cSAlexandre Belloni if (ret < 0) 220e6e7376cSAlexandre Belloni return ret; 221e6e7376cSAlexandre Belloni 222e6e7376cSAlexandre Belloni if (status & RV3028_STATUS_PORF) { 223e6e7376cSAlexandre Belloni dev_warn(dev, "Voltage low, data is invalid.\n"); 224e6e7376cSAlexandre Belloni return -EINVAL; 225e6e7376cSAlexandre Belloni } 226e6e7376cSAlexandre Belloni 227e6e7376cSAlexandre Belloni ret = regmap_bulk_read(rv3028->regmap, RV3028_SEC, date, sizeof(date)); 228e6e7376cSAlexandre Belloni if (ret) 229e6e7376cSAlexandre Belloni return ret; 230e6e7376cSAlexandre Belloni 231e6e7376cSAlexandre Belloni tm->tm_sec = bcd2bin(date[RV3028_SEC] & 0x7f); 232e6e7376cSAlexandre Belloni tm->tm_min = bcd2bin(date[RV3028_MIN] & 0x7f); 233e6e7376cSAlexandre Belloni tm->tm_hour = bcd2bin(date[RV3028_HOUR] & 0x3f); 234e6e7376cSAlexandre Belloni tm->tm_wday = ilog2(date[RV3028_WDAY] & 0x7f); 235e6e7376cSAlexandre Belloni tm->tm_mday = bcd2bin(date[RV3028_DAY] & 0x3f); 236e6e7376cSAlexandre Belloni tm->tm_mon = bcd2bin(date[RV3028_MONTH] & 0x1f) - 1; 237e6e7376cSAlexandre Belloni tm->tm_year = bcd2bin(date[RV3028_YEAR]) + 100; 238e6e7376cSAlexandre Belloni 239e6e7376cSAlexandre Belloni return 0; 240e6e7376cSAlexandre Belloni } 241e6e7376cSAlexandre Belloni 242e6e7376cSAlexandre Belloni static int rv3028_set_time(struct device *dev, struct rtc_time *tm) 243e6e7376cSAlexandre Belloni { 244e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev); 245e6e7376cSAlexandre Belloni u8 date[7]; 246e6e7376cSAlexandre Belloni int ret; 247e6e7376cSAlexandre Belloni 248e6e7376cSAlexandre Belloni date[RV3028_SEC] = bin2bcd(tm->tm_sec); 249e6e7376cSAlexandre Belloni date[RV3028_MIN] = bin2bcd(tm->tm_min); 250e6e7376cSAlexandre Belloni date[RV3028_HOUR] = bin2bcd(tm->tm_hour); 251e6e7376cSAlexandre Belloni date[RV3028_WDAY] = 1 << (tm->tm_wday); 252e6e7376cSAlexandre Belloni date[RV3028_DAY] = bin2bcd(tm->tm_mday); 253e6e7376cSAlexandre Belloni date[RV3028_MONTH] = bin2bcd(tm->tm_mon + 1); 254e6e7376cSAlexandre Belloni date[RV3028_YEAR] = bin2bcd(tm->tm_year - 100); 255e6e7376cSAlexandre Belloni 256e6e7376cSAlexandre Belloni /* 257e6e7376cSAlexandre Belloni * Writing to the Seconds register has the same effect as setting RESET 258e6e7376cSAlexandre Belloni * bit to 1 259e6e7376cSAlexandre Belloni */ 260e6e7376cSAlexandre Belloni ret = regmap_bulk_write(rv3028->regmap, RV3028_SEC, date, 261e6e7376cSAlexandre Belloni sizeof(date)); 262e6e7376cSAlexandre Belloni if (ret) 263e6e7376cSAlexandre Belloni return ret; 264e6e7376cSAlexandre Belloni 265e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, 266e6e7376cSAlexandre Belloni RV3028_STATUS_PORF, 0); 267e6e7376cSAlexandre Belloni 268e6e7376cSAlexandre Belloni return ret; 269e6e7376cSAlexandre Belloni } 270e6e7376cSAlexandre Belloni 271e6e7376cSAlexandre Belloni static int rv3028_get_alarm(struct device *dev, struct rtc_wkalrm *alrm) 272e6e7376cSAlexandre Belloni { 273e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev); 274e6e7376cSAlexandre Belloni u8 alarmvals[3]; 275e6e7376cSAlexandre Belloni int status, ctrl, ret; 276e6e7376cSAlexandre Belloni 277e6e7376cSAlexandre Belloni ret = regmap_bulk_read(rv3028->regmap, RV3028_ALARM_MIN, alarmvals, 278e6e7376cSAlexandre Belloni sizeof(alarmvals)); 279e6e7376cSAlexandre Belloni if (ret) 280e6e7376cSAlexandre Belloni return ret; 281e6e7376cSAlexandre Belloni 282e6e7376cSAlexandre Belloni ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); 283e6e7376cSAlexandre Belloni if (ret < 0) 284e6e7376cSAlexandre Belloni return ret; 285e6e7376cSAlexandre Belloni 286e6e7376cSAlexandre Belloni ret = regmap_read(rv3028->regmap, RV3028_CTRL2, &ctrl); 287e6e7376cSAlexandre Belloni if (ret < 0) 288e6e7376cSAlexandre Belloni return ret; 289e6e7376cSAlexandre Belloni 290e6e7376cSAlexandre Belloni alrm->time.tm_sec = 0; 291e6e7376cSAlexandre Belloni alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); 292e6e7376cSAlexandre Belloni alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); 293e6e7376cSAlexandre Belloni alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); 294e6e7376cSAlexandre Belloni 295e6e7376cSAlexandre Belloni alrm->enabled = !!(ctrl & RV3028_CTRL2_AIE); 296e6e7376cSAlexandre Belloni alrm->pending = (status & RV3028_STATUS_AF) && alrm->enabled; 297e6e7376cSAlexandre Belloni 298e6e7376cSAlexandre Belloni return 0; 299e6e7376cSAlexandre Belloni } 300e6e7376cSAlexandre Belloni 301e6e7376cSAlexandre Belloni static int rv3028_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 302e6e7376cSAlexandre Belloni { 303e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev); 304e6e7376cSAlexandre Belloni u8 alarmvals[3]; 305e6e7376cSAlexandre Belloni u8 ctrl = 0; 306e6e7376cSAlexandre Belloni int ret; 307e6e7376cSAlexandre Belloni 308e6e7376cSAlexandre Belloni /* The alarm has no seconds, round up to nearest minute */ 309e6e7376cSAlexandre Belloni if (alrm->time.tm_sec) { 310e6e7376cSAlexandre Belloni time64_t alarm_time = rtc_tm_to_time64(&alrm->time); 311e6e7376cSAlexandre Belloni 312e6e7376cSAlexandre Belloni alarm_time += 60 - alrm->time.tm_sec; 313e6e7376cSAlexandre Belloni rtc_time64_to_tm(alarm_time, &alrm->time); 314e6e7376cSAlexandre Belloni } 315e6e7376cSAlexandre Belloni 316e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, 317e6e7376cSAlexandre Belloni RV3028_CTRL2_AIE | RV3028_CTRL2_UIE, 0); 318e6e7376cSAlexandre Belloni if (ret) 319e6e7376cSAlexandre Belloni return ret; 320e6e7376cSAlexandre Belloni 321e6e7376cSAlexandre Belloni alarmvals[0] = bin2bcd(alrm->time.tm_min); 322e6e7376cSAlexandre Belloni alarmvals[1] = bin2bcd(alrm->time.tm_hour); 323e6e7376cSAlexandre Belloni alarmvals[2] = bin2bcd(alrm->time.tm_mday); 324e6e7376cSAlexandre Belloni 325e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, 326e6e7376cSAlexandre Belloni RV3028_STATUS_AF, 0); 327e6e7376cSAlexandre Belloni if (ret) 328e6e7376cSAlexandre Belloni return ret; 329e6e7376cSAlexandre Belloni 330e6e7376cSAlexandre Belloni ret = regmap_bulk_write(rv3028->regmap, RV3028_ALARM_MIN, alarmvals, 331e6e7376cSAlexandre Belloni sizeof(alarmvals)); 332e6e7376cSAlexandre Belloni if (ret) 333e6e7376cSAlexandre Belloni return ret; 334e6e7376cSAlexandre Belloni 335e6e7376cSAlexandre Belloni if (alrm->enabled) { 336e6e7376cSAlexandre Belloni if (rv3028->rtc->uie_rtctimer.enabled) 337e6e7376cSAlexandre Belloni ctrl |= RV3028_CTRL2_UIE; 338e6e7376cSAlexandre Belloni if (rv3028->rtc->aie_timer.enabled) 339e6e7376cSAlexandre Belloni ctrl |= RV3028_CTRL2_AIE; 340e6e7376cSAlexandre Belloni } 341e6e7376cSAlexandre Belloni 342e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, 343e6e7376cSAlexandre Belloni RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl); 344e6e7376cSAlexandre Belloni 345e6e7376cSAlexandre Belloni return ret; 346e6e7376cSAlexandre Belloni } 347e6e7376cSAlexandre Belloni 348e6e7376cSAlexandre Belloni static int rv3028_alarm_irq_enable(struct device *dev, unsigned int enabled) 349e6e7376cSAlexandre Belloni { 350e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev); 351e6e7376cSAlexandre Belloni int ctrl = 0, ret; 352e6e7376cSAlexandre Belloni 353e6e7376cSAlexandre Belloni if (enabled) { 354e6e7376cSAlexandre Belloni if (rv3028->rtc->uie_rtctimer.enabled) 355e6e7376cSAlexandre Belloni ctrl |= RV3028_CTRL2_UIE; 356e6e7376cSAlexandre Belloni if (rv3028->rtc->aie_timer.enabled) 357e6e7376cSAlexandre Belloni ctrl |= RV3028_CTRL2_AIE; 358e6e7376cSAlexandre Belloni } 359e6e7376cSAlexandre Belloni 360e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, 361e6e7376cSAlexandre Belloni RV3028_STATUS_AF | RV3028_STATUS_UF, 0); 362e6e7376cSAlexandre Belloni if (ret) 363e6e7376cSAlexandre Belloni return ret; 364e6e7376cSAlexandre Belloni 365e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, 366e6e7376cSAlexandre Belloni RV3028_CTRL2_UIE | RV3028_CTRL2_AIE, ctrl); 367e6e7376cSAlexandre Belloni if (ret) 368e6e7376cSAlexandre Belloni return ret; 369e6e7376cSAlexandre Belloni 370e6e7376cSAlexandre Belloni return 0; 371e6e7376cSAlexandre Belloni } 372e6e7376cSAlexandre Belloni 373e6e7376cSAlexandre Belloni static int rv3028_read_offset(struct device *dev, long *offset) 374e6e7376cSAlexandre Belloni { 375e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev); 376e6e7376cSAlexandre Belloni int ret, value, steps; 377e6e7376cSAlexandre Belloni 378e6e7376cSAlexandre Belloni ret = regmap_read(rv3028->regmap, RV3028_OFFSET, &value); 379e6e7376cSAlexandre Belloni if (ret < 0) 380e6e7376cSAlexandre Belloni return ret; 381e6e7376cSAlexandre Belloni 382e6e7376cSAlexandre Belloni steps = sign_extend32(value << 1, 8); 383e6e7376cSAlexandre Belloni 384e6e7376cSAlexandre Belloni ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &value); 385e6e7376cSAlexandre Belloni if (ret < 0) 386e6e7376cSAlexandre Belloni return ret; 387e6e7376cSAlexandre Belloni 388e6e7376cSAlexandre Belloni steps += value >> 7; 389e6e7376cSAlexandre Belloni 390e6e7376cSAlexandre Belloni *offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000); 391e6e7376cSAlexandre Belloni 392e6e7376cSAlexandre Belloni return 0; 393e6e7376cSAlexandre Belloni } 394e6e7376cSAlexandre Belloni 395e6e7376cSAlexandre Belloni static int rv3028_set_offset(struct device *dev, long offset) 396e6e7376cSAlexandre Belloni { 397e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev); 398e6e7376cSAlexandre Belloni int ret; 399e6e7376cSAlexandre Belloni 400e6e7376cSAlexandre Belloni offset = clamp(offset, -244141L, 243187L) * 1000; 401e6e7376cSAlexandre Belloni offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT); 402e6e7376cSAlexandre Belloni 403e6e7376cSAlexandre Belloni ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1); 404e6e7376cSAlexandre Belloni if (ret < 0) 405e6e7376cSAlexandre Belloni return ret; 406e6e7376cSAlexandre Belloni 407e6e7376cSAlexandre Belloni return regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7), 408e6e7376cSAlexandre Belloni offset << 7); 409e6e7376cSAlexandre Belloni } 410e6e7376cSAlexandre Belloni 411e6e7376cSAlexandre Belloni static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 412e6e7376cSAlexandre Belloni { 413e6e7376cSAlexandre Belloni struct rv3028_data *rv3028 = dev_get_drvdata(dev); 414e6e7376cSAlexandre Belloni int status, ret = 0; 415e6e7376cSAlexandre Belloni 416e6e7376cSAlexandre Belloni switch (cmd) { 417e6e7376cSAlexandre Belloni case RTC_VL_READ: 418e6e7376cSAlexandre Belloni ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); 419e6e7376cSAlexandre Belloni if (ret < 0) 420e6e7376cSAlexandre Belloni return ret; 421e6e7376cSAlexandre Belloni 422e6e7376cSAlexandre Belloni if (status & RV3028_STATUS_PORF) 423e6e7376cSAlexandre Belloni dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n"); 424e6e7376cSAlexandre Belloni 425e6e7376cSAlexandre Belloni status &= RV3028_STATUS_PORF; 426e6e7376cSAlexandre Belloni 427e6e7376cSAlexandre Belloni if (copy_to_user((void __user *)arg, &status, sizeof(int))) 428e6e7376cSAlexandre Belloni return -EFAULT; 429e6e7376cSAlexandre Belloni 430e6e7376cSAlexandre Belloni return 0; 431e6e7376cSAlexandre Belloni 432e6e7376cSAlexandre Belloni case RTC_VL_CLR: 433e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS, 434e6e7376cSAlexandre Belloni RV3028_STATUS_PORF, 0); 435e6e7376cSAlexandre Belloni 436e6e7376cSAlexandre Belloni return ret; 437e6e7376cSAlexandre Belloni 438e6e7376cSAlexandre Belloni default: 439e6e7376cSAlexandre Belloni return -ENOIOCTLCMD; 440e6e7376cSAlexandre Belloni } 441e6e7376cSAlexandre Belloni } 442e6e7376cSAlexandre Belloni 443e6e7376cSAlexandre Belloni static int rv3028_nvram_write(void *priv, unsigned int offset, void *val, 444e6e7376cSAlexandre Belloni size_t bytes) 445e6e7376cSAlexandre Belloni { 446e6e7376cSAlexandre Belloni return regmap_bulk_write(priv, RV3028_RAM1 + offset, val, bytes); 447e6e7376cSAlexandre Belloni } 448e6e7376cSAlexandre Belloni 449e6e7376cSAlexandre Belloni static int rv3028_nvram_read(void *priv, unsigned int offset, void *val, 450e6e7376cSAlexandre Belloni size_t bytes) 451e6e7376cSAlexandre Belloni { 452e6e7376cSAlexandre Belloni return regmap_bulk_read(priv, RV3028_RAM1 + offset, val, bytes); 453e6e7376cSAlexandre Belloni } 454e6e7376cSAlexandre Belloni 455e6e7376cSAlexandre Belloni static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val, 456e6e7376cSAlexandre Belloni size_t bytes) 457e6e7376cSAlexandre Belloni { 458e6e7376cSAlexandre Belloni u32 status, ctrl1; 459e6e7376cSAlexandre Belloni int i, ret, err; 460e6e7376cSAlexandre Belloni u8 *buf = val; 461e6e7376cSAlexandre Belloni 462e6e7376cSAlexandre Belloni ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); 463e6e7376cSAlexandre Belloni if (ret) 464e6e7376cSAlexandre Belloni return ret; 465e6e7376cSAlexandre Belloni 466e6e7376cSAlexandre Belloni if (!(ctrl1 & RV3028_CTRL1_EERD)) { 467e6e7376cSAlexandre Belloni ret = regmap_update_bits(priv, RV3028_CTRL1, 468e6e7376cSAlexandre Belloni RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); 469e6e7376cSAlexandre Belloni if (ret) 470e6e7376cSAlexandre Belloni return ret; 471e6e7376cSAlexandre Belloni 472e6e7376cSAlexandre Belloni ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, 473e6e7376cSAlexandre Belloni !(status & RV3028_STATUS_EEBUSY), 474e6e7376cSAlexandre Belloni RV3028_EEBUSY_POLL, 475e6e7376cSAlexandre Belloni RV3028_EEBUSY_TIMEOUT); 476e6e7376cSAlexandre Belloni if (ret) 477e6e7376cSAlexandre Belloni goto restore_eerd; 478e6e7376cSAlexandre Belloni } 479e6e7376cSAlexandre Belloni 480e6e7376cSAlexandre Belloni for (i = 0; i < bytes; i++) { 481e6e7376cSAlexandre Belloni ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); 482e6e7376cSAlexandre Belloni if (ret) 483e6e7376cSAlexandre Belloni goto restore_eerd; 484e6e7376cSAlexandre Belloni 485e6e7376cSAlexandre Belloni ret = regmap_write(priv, RV3028_EEPROM_DATA, buf[i]); 486e6e7376cSAlexandre Belloni if (ret) 487e6e7376cSAlexandre Belloni goto restore_eerd; 488e6e7376cSAlexandre Belloni 489e6e7376cSAlexandre Belloni ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); 490e6e7376cSAlexandre Belloni if (ret) 491e6e7376cSAlexandre Belloni goto restore_eerd; 492e6e7376cSAlexandre Belloni 493e6e7376cSAlexandre Belloni ret = regmap_write(priv, RV3028_EEPROM_CMD, 494e6e7376cSAlexandre Belloni RV3028_EEPROM_CMD_WRITE); 495e6e7376cSAlexandre Belloni if (ret) 496e6e7376cSAlexandre Belloni goto restore_eerd; 497e6e7376cSAlexandre Belloni 498e6e7376cSAlexandre Belloni usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT); 499e6e7376cSAlexandre Belloni 500e6e7376cSAlexandre Belloni ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, 501e6e7376cSAlexandre Belloni !(status & RV3028_STATUS_EEBUSY), 502e6e7376cSAlexandre Belloni RV3028_EEBUSY_POLL, 503e6e7376cSAlexandre Belloni RV3028_EEBUSY_TIMEOUT); 504e6e7376cSAlexandre Belloni if (ret) 505e6e7376cSAlexandre Belloni goto restore_eerd; 506e6e7376cSAlexandre Belloni } 507e6e7376cSAlexandre Belloni 508e6e7376cSAlexandre Belloni restore_eerd: 509e6e7376cSAlexandre Belloni if (!(ctrl1 & RV3028_CTRL1_EERD)) 510e6e7376cSAlexandre Belloni { 511e6e7376cSAlexandre Belloni err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD, 512e6e7376cSAlexandre Belloni 0); 513e6e7376cSAlexandre Belloni if (err && !ret) 514e6e7376cSAlexandre Belloni ret = err; 515e6e7376cSAlexandre Belloni } 516e6e7376cSAlexandre Belloni 517e6e7376cSAlexandre Belloni return ret; 518e6e7376cSAlexandre Belloni } 519e6e7376cSAlexandre Belloni 520e6e7376cSAlexandre Belloni static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val, 521e6e7376cSAlexandre Belloni size_t bytes) 522e6e7376cSAlexandre Belloni { 523e6e7376cSAlexandre Belloni u32 status, ctrl1, data; 524e6e7376cSAlexandre Belloni int i, ret, err; 525e6e7376cSAlexandre Belloni u8 *buf = val; 526e6e7376cSAlexandre Belloni 527e6e7376cSAlexandre Belloni ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); 528e6e7376cSAlexandre Belloni if (ret) 529e6e7376cSAlexandre Belloni return ret; 530e6e7376cSAlexandre Belloni 531e6e7376cSAlexandre Belloni if (!(ctrl1 & RV3028_CTRL1_EERD)) { 532e6e7376cSAlexandre Belloni ret = regmap_update_bits(priv, RV3028_CTRL1, 533e6e7376cSAlexandre Belloni RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); 534e6e7376cSAlexandre Belloni if (ret) 535e6e7376cSAlexandre Belloni return ret; 536e6e7376cSAlexandre Belloni 537e6e7376cSAlexandre Belloni ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, 538e6e7376cSAlexandre Belloni !(status & RV3028_STATUS_EEBUSY), 539e6e7376cSAlexandre Belloni RV3028_EEBUSY_POLL, 540e6e7376cSAlexandre Belloni RV3028_EEBUSY_TIMEOUT); 541e6e7376cSAlexandre Belloni if (ret) 542e6e7376cSAlexandre Belloni goto restore_eerd; 543e6e7376cSAlexandre Belloni } 544e6e7376cSAlexandre Belloni 545e6e7376cSAlexandre Belloni for (i = 0; i < bytes; i++) { 546e6e7376cSAlexandre Belloni ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); 547e6e7376cSAlexandre Belloni if (ret) 548e6e7376cSAlexandre Belloni goto restore_eerd; 549e6e7376cSAlexandre Belloni 550e6e7376cSAlexandre Belloni ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); 551e6e7376cSAlexandre Belloni if (ret) 552e6e7376cSAlexandre Belloni goto restore_eerd; 553e6e7376cSAlexandre Belloni 554e6e7376cSAlexandre Belloni ret = regmap_write(priv, RV3028_EEPROM_CMD, 555e6e7376cSAlexandre Belloni RV3028_EEPROM_CMD_READ); 556e6e7376cSAlexandre Belloni if (ret) 557e6e7376cSAlexandre Belloni goto restore_eerd; 558e6e7376cSAlexandre Belloni 559e6e7376cSAlexandre Belloni ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, 560e6e7376cSAlexandre Belloni !(status & RV3028_STATUS_EEBUSY), 561e6e7376cSAlexandre Belloni RV3028_EEBUSY_POLL, 562e6e7376cSAlexandre Belloni RV3028_EEBUSY_TIMEOUT); 563e6e7376cSAlexandre Belloni if (ret) 564e6e7376cSAlexandre Belloni goto restore_eerd; 565e6e7376cSAlexandre Belloni 566e6e7376cSAlexandre Belloni ret = regmap_read(priv, RV3028_EEPROM_DATA, &data); 567e6e7376cSAlexandre Belloni if (ret) 568e6e7376cSAlexandre Belloni goto restore_eerd; 569e6e7376cSAlexandre Belloni buf[i] = data; 570e6e7376cSAlexandre Belloni } 571e6e7376cSAlexandre Belloni 572e6e7376cSAlexandre Belloni restore_eerd: 573e6e7376cSAlexandre Belloni if (!(ctrl1 & RV3028_CTRL1_EERD)) 574e6e7376cSAlexandre Belloni { 575e6e7376cSAlexandre Belloni err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD, 576e6e7376cSAlexandre Belloni 0); 577e6e7376cSAlexandre Belloni if (err && !ret) 578e6e7376cSAlexandre Belloni ret = err; 579e6e7376cSAlexandre Belloni } 580e6e7376cSAlexandre Belloni 581e6e7376cSAlexandre Belloni return ret; 582e6e7376cSAlexandre Belloni } 583e6e7376cSAlexandre Belloni 584e6e7376cSAlexandre Belloni static struct rtc_class_ops rv3028_rtc_ops = { 585e6e7376cSAlexandre Belloni .read_time = rv3028_get_time, 586e6e7376cSAlexandre Belloni .set_time = rv3028_set_time, 587e6e7376cSAlexandre Belloni .read_offset = rv3028_read_offset, 588e6e7376cSAlexandre Belloni .set_offset = rv3028_set_offset, 589e6e7376cSAlexandre Belloni .ioctl = rv3028_ioctl, 590e6e7376cSAlexandre Belloni }; 591e6e7376cSAlexandre Belloni 592e6e7376cSAlexandre Belloni static const struct regmap_config regmap_config = { 593e6e7376cSAlexandre Belloni .reg_bits = 8, 594e6e7376cSAlexandre Belloni .val_bits = 8, 595e6e7376cSAlexandre Belloni .max_register = 0x37, 596e6e7376cSAlexandre Belloni }; 597e6e7376cSAlexandre Belloni 598e6e7376cSAlexandre Belloni static int rv3028_probe(struct i2c_client *client) 599e6e7376cSAlexandre Belloni { 600e6e7376cSAlexandre Belloni struct rv3028_data *rv3028; 601e6e7376cSAlexandre Belloni int ret, status; 602e6e7376cSAlexandre Belloni u32 ohms; 603e6e7376cSAlexandre Belloni struct nvmem_config nvmem_cfg = { 604e6e7376cSAlexandre Belloni .name = "rv3028_nvram", 605e6e7376cSAlexandre Belloni .word_size = 1, 606e6e7376cSAlexandre Belloni .stride = 1, 607e6e7376cSAlexandre Belloni .size = 2, 608e6e7376cSAlexandre Belloni .type = NVMEM_TYPE_BATTERY_BACKED, 609e6e7376cSAlexandre Belloni .reg_read = rv3028_nvram_read, 610e6e7376cSAlexandre Belloni .reg_write = rv3028_nvram_write, 611e6e7376cSAlexandre Belloni }; 612e6e7376cSAlexandre Belloni struct nvmem_config eeprom_cfg = { 613e6e7376cSAlexandre Belloni .name = "rv3028_eeprom", 614e6e7376cSAlexandre Belloni .word_size = 1, 615e6e7376cSAlexandre Belloni .stride = 1, 616e6e7376cSAlexandre Belloni .size = 43, 617e6e7376cSAlexandre Belloni .type = NVMEM_TYPE_EEPROM, 618e6e7376cSAlexandre Belloni .reg_read = rv3028_eeprom_read, 619e6e7376cSAlexandre Belloni .reg_write = rv3028_eeprom_write, 620e6e7376cSAlexandre Belloni }; 621e6e7376cSAlexandre Belloni 622e6e7376cSAlexandre Belloni rv3028 = devm_kzalloc(&client->dev, sizeof(struct rv3028_data), 623e6e7376cSAlexandre Belloni GFP_KERNEL); 624e6e7376cSAlexandre Belloni if (!rv3028) 625e6e7376cSAlexandre Belloni return -ENOMEM; 626e6e7376cSAlexandre Belloni 627e6e7376cSAlexandre Belloni rv3028->regmap = devm_regmap_init_i2c(client, ®map_config); 628e6e7376cSAlexandre Belloni 629e6e7376cSAlexandre Belloni i2c_set_clientdata(client, rv3028); 630e6e7376cSAlexandre Belloni 631e6e7376cSAlexandre Belloni ret = regmap_read(rv3028->regmap, RV3028_STATUS, &status); 632e6e7376cSAlexandre Belloni if (ret < 0) 633e6e7376cSAlexandre Belloni return ret; 634e6e7376cSAlexandre Belloni 635e6e7376cSAlexandre Belloni if (status & RV3028_STATUS_PORF) 636e6e7376cSAlexandre Belloni dev_warn(&client->dev, "Voltage low, data loss detected.\n"); 637e6e7376cSAlexandre Belloni 638e6e7376cSAlexandre Belloni if (status & RV3028_STATUS_AF) 639e6e7376cSAlexandre Belloni dev_warn(&client->dev, "An alarm may have been missed.\n"); 640e6e7376cSAlexandre Belloni 641e6e7376cSAlexandre Belloni rv3028->rtc = devm_rtc_allocate_device(&client->dev); 642*44c638ceSAlexandre Belloni if (IS_ERR(rv3028->rtc)) 643e6e7376cSAlexandre Belloni return PTR_ERR(rv3028->rtc); 644e6e7376cSAlexandre Belloni 645e6e7376cSAlexandre Belloni if (client->irq > 0) { 646e6e7376cSAlexandre Belloni ret = devm_request_threaded_irq(&client->dev, client->irq, 647e6e7376cSAlexandre Belloni NULL, rv3028_handle_irq, 648e6e7376cSAlexandre Belloni IRQF_TRIGGER_LOW | IRQF_ONESHOT, 649e6e7376cSAlexandre Belloni "rv3028", rv3028); 650e6e7376cSAlexandre Belloni if (ret) { 651e6e7376cSAlexandre Belloni dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); 652e6e7376cSAlexandre Belloni client->irq = 0; 653e6e7376cSAlexandre Belloni } else { 654e6e7376cSAlexandre Belloni rv3028_rtc_ops.read_alarm = rv3028_get_alarm; 655e6e7376cSAlexandre Belloni rv3028_rtc_ops.set_alarm = rv3028_set_alarm; 656e6e7376cSAlexandre Belloni rv3028_rtc_ops.alarm_irq_enable = rv3028_alarm_irq_enable; 657e6e7376cSAlexandre Belloni } 658e6e7376cSAlexandre Belloni } 659e6e7376cSAlexandre Belloni 660e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1, 661e6e7376cSAlexandre Belloni RV3028_CTRL1_WADA, RV3028_CTRL1_WADA); 662e6e7376cSAlexandre Belloni if (ret) 663e6e7376cSAlexandre Belloni return ret; 664e6e7376cSAlexandre Belloni 665e6e7376cSAlexandre Belloni /* setup timestamping */ 666e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL2, 667e6e7376cSAlexandre Belloni RV3028_CTRL2_EIE | RV3028_CTRL2_TSE, 668e6e7376cSAlexandre Belloni RV3028_CTRL2_EIE | RV3028_CTRL2_TSE); 669e6e7376cSAlexandre Belloni if (ret) 670e6e7376cSAlexandre Belloni return ret; 671e6e7376cSAlexandre Belloni 672e6e7376cSAlexandre Belloni /* setup trickle charger */ 673e6e7376cSAlexandre Belloni if (!device_property_read_u32(&client->dev, "trickle-resistor-ohms", 674e6e7376cSAlexandre Belloni &ohms)) { 675e6e7376cSAlexandre Belloni int i; 676e6e7376cSAlexandre Belloni 677e6e7376cSAlexandre Belloni for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++) 678e6e7376cSAlexandre Belloni if (ohms == rv3028_trickle_resistors[i]) 679e6e7376cSAlexandre Belloni break; 680e6e7376cSAlexandre Belloni 681e6e7376cSAlexandre Belloni if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { 682e6e7376cSAlexandre Belloni ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, 683e6e7376cSAlexandre Belloni RV3028_BACKUP_TCE | 684e6e7376cSAlexandre Belloni RV3028_BACKUP_TCR_MASK, 685e6e7376cSAlexandre Belloni RV3028_BACKUP_TCE | i); 686e6e7376cSAlexandre Belloni if (ret) 687e6e7376cSAlexandre Belloni return ret; 688e6e7376cSAlexandre Belloni } else { 689e6e7376cSAlexandre Belloni dev_warn(&client->dev, "invalid trickle resistor value\n"); 690e6e7376cSAlexandre Belloni } 691e6e7376cSAlexandre Belloni } 692e6e7376cSAlexandre Belloni 693e6e7376cSAlexandre Belloni ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group); 694e6e7376cSAlexandre Belloni if (ret) 695e6e7376cSAlexandre Belloni return ret; 696e6e7376cSAlexandre Belloni 697e6e7376cSAlexandre Belloni rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 698e6e7376cSAlexandre Belloni rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099; 699e6e7376cSAlexandre Belloni rv3028->rtc->ops = &rv3028_rtc_ops; 700e6e7376cSAlexandre Belloni ret = rtc_register_device(rv3028->rtc); 701e6e7376cSAlexandre Belloni if (ret) 702e6e7376cSAlexandre Belloni return ret; 703e6e7376cSAlexandre Belloni 704e6e7376cSAlexandre Belloni nvmem_cfg.priv = rv3028->regmap; 705e6e7376cSAlexandre Belloni rtc_nvmem_register(rv3028->rtc, &nvmem_cfg); 706e6e7376cSAlexandre Belloni eeprom_cfg.priv = rv3028->regmap; 707e6e7376cSAlexandre Belloni rtc_nvmem_register(rv3028->rtc, &eeprom_cfg); 708e6e7376cSAlexandre Belloni 709e6e7376cSAlexandre Belloni rv3028->rtc->max_user_freq = 1; 710e6e7376cSAlexandre Belloni 711e6e7376cSAlexandre Belloni return 0; 712e6e7376cSAlexandre Belloni } 713e6e7376cSAlexandre Belloni 714e6e7376cSAlexandre Belloni static const struct of_device_id rv3028_of_match[] = { 715e6e7376cSAlexandre Belloni { .compatible = "microcrystal,rv3028", }, 716e6e7376cSAlexandre Belloni { } 717e6e7376cSAlexandre Belloni }; 718e6e7376cSAlexandre Belloni MODULE_DEVICE_TABLE(of, rv3028_of_match); 719e6e7376cSAlexandre Belloni 720e6e7376cSAlexandre Belloni static struct i2c_driver rv3028_driver = { 721e6e7376cSAlexandre Belloni .driver = { 722e6e7376cSAlexandre Belloni .name = "rtc-rv3028", 723e6e7376cSAlexandre Belloni .of_match_table = of_match_ptr(rv3028_of_match), 724e6e7376cSAlexandre Belloni }, 725e6e7376cSAlexandre Belloni .probe_new = rv3028_probe, 726e6e7376cSAlexandre Belloni }; 727e6e7376cSAlexandre Belloni module_i2c_driver(rv3028_driver); 728e6e7376cSAlexandre Belloni 729e6e7376cSAlexandre Belloni MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>"); 730e6e7376cSAlexandre Belloni MODULE_DESCRIPTION("Micro Crystal RV3028 RTC driver"); 731e6e7376cSAlexandre Belloni MODULE_LICENSE("GPL v2"); 732