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