12eeaa532SAlexandre Belloni // SPDX-License-Identifier: GPL-2.0 22eeaa532SAlexandre Belloni /* 32eeaa532SAlexandre Belloni * RTC driver for the Micro Crystal RV3032 42eeaa532SAlexandre Belloni * 52eeaa532SAlexandre Belloni * Copyright (C) 2020 Micro Crystal SA 62eeaa532SAlexandre Belloni * 72eeaa532SAlexandre Belloni * Alexandre Belloni <alexandre.belloni@bootlin.com> 82eeaa532SAlexandre Belloni * 92eeaa532SAlexandre Belloni */ 102eeaa532SAlexandre Belloni 112eeaa532SAlexandre Belloni #include <linux/clk.h> 122eeaa532SAlexandre Belloni #include <linux/clk-provider.h> 132eeaa532SAlexandre Belloni #include <linux/bcd.h> 142eeaa532SAlexandre Belloni #include <linux/bitfield.h> 152eeaa532SAlexandre Belloni #include <linux/bitops.h> 162eeaa532SAlexandre Belloni #include <linux/hwmon.h> 172eeaa532SAlexandre Belloni #include <linux/i2c.h> 182eeaa532SAlexandre Belloni #include <linux/interrupt.h> 192eeaa532SAlexandre Belloni #include <linux/kernel.h> 202eeaa532SAlexandre Belloni #include <linux/log2.h> 212eeaa532SAlexandre Belloni #include <linux/module.h> 222eeaa532SAlexandre Belloni #include <linux/of_device.h> 232eeaa532SAlexandre Belloni #include <linux/regmap.h> 242eeaa532SAlexandre Belloni #include <linux/rtc.h> 252eeaa532SAlexandre Belloni 262eeaa532SAlexandre Belloni #define RV3032_SEC 0x01 272eeaa532SAlexandre Belloni #define RV3032_MIN 0x02 282eeaa532SAlexandre Belloni #define RV3032_HOUR 0x03 292eeaa532SAlexandre Belloni #define RV3032_WDAY 0x04 302eeaa532SAlexandre Belloni #define RV3032_DAY 0x05 312eeaa532SAlexandre Belloni #define RV3032_MONTH 0x06 322eeaa532SAlexandre Belloni #define RV3032_YEAR 0x07 332eeaa532SAlexandre Belloni #define RV3032_ALARM_MIN 0x08 342eeaa532SAlexandre Belloni #define RV3032_ALARM_HOUR 0x09 352eeaa532SAlexandre Belloni #define RV3032_ALARM_DAY 0x0A 362eeaa532SAlexandre Belloni #define RV3032_STATUS 0x0D 372eeaa532SAlexandre Belloni #define RV3032_TLSB 0x0E 382eeaa532SAlexandre Belloni #define RV3032_TMSB 0x0F 392eeaa532SAlexandre Belloni #define RV3032_CTRL1 0x10 402eeaa532SAlexandre Belloni #define RV3032_CTRL2 0x11 412eeaa532SAlexandre Belloni #define RV3032_CTRL3 0x12 422eeaa532SAlexandre Belloni #define RV3032_TS_CTRL 0x13 432eeaa532SAlexandre Belloni #define RV3032_CLK_IRQ 0x14 442eeaa532SAlexandre Belloni #define RV3032_EEPROM_ADDR 0x3D 452eeaa532SAlexandre Belloni #define RV3032_EEPROM_DATA 0x3E 462eeaa532SAlexandre Belloni #define RV3032_EEPROM_CMD 0x3F 472eeaa532SAlexandre Belloni #define RV3032_RAM1 0x40 482eeaa532SAlexandre Belloni #define RV3032_PMU 0xC0 492eeaa532SAlexandre Belloni #define RV3032_OFFSET 0xC1 502eeaa532SAlexandre Belloni #define RV3032_CLKOUT1 0xC2 512eeaa532SAlexandre Belloni #define RV3032_CLKOUT2 0xC3 522eeaa532SAlexandre Belloni #define RV3032_TREF0 0xC4 532eeaa532SAlexandre Belloni #define RV3032_TREF1 0xC5 542eeaa532SAlexandre Belloni 552eeaa532SAlexandre Belloni #define RV3032_STATUS_VLF BIT(0) 562eeaa532SAlexandre Belloni #define RV3032_STATUS_PORF BIT(1) 572eeaa532SAlexandre Belloni #define RV3032_STATUS_EVF BIT(2) 582eeaa532SAlexandre Belloni #define RV3032_STATUS_AF BIT(3) 592eeaa532SAlexandre Belloni #define RV3032_STATUS_TF BIT(4) 602eeaa532SAlexandre Belloni #define RV3032_STATUS_UF BIT(5) 612eeaa532SAlexandre Belloni #define RV3032_STATUS_TLF BIT(6) 622eeaa532SAlexandre Belloni #define RV3032_STATUS_THF BIT(7) 632eeaa532SAlexandre Belloni 642eeaa532SAlexandre Belloni #define RV3032_TLSB_CLKF BIT(1) 652eeaa532SAlexandre Belloni #define RV3032_TLSB_EEBUSY BIT(2) 662eeaa532SAlexandre Belloni #define RV3032_TLSB_TEMP GENMASK(7, 4) 672eeaa532SAlexandre Belloni 682eeaa532SAlexandre Belloni #define RV3032_CLKOUT2_HFD_MSK GENMASK(4, 0) 692eeaa532SAlexandre Belloni #define RV3032_CLKOUT2_FD_MSK GENMASK(6, 5) 702eeaa532SAlexandre Belloni #define RV3032_CLKOUT2_OS BIT(7) 712eeaa532SAlexandre Belloni 722eeaa532SAlexandre Belloni #define RV3032_CTRL1_EERD BIT(3) 732eeaa532SAlexandre Belloni #define RV3032_CTRL1_WADA BIT(5) 742eeaa532SAlexandre Belloni 752eeaa532SAlexandre Belloni #define RV3032_CTRL2_STOP BIT(0) 762eeaa532SAlexandre Belloni #define RV3032_CTRL2_EIE BIT(2) 772eeaa532SAlexandre Belloni #define RV3032_CTRL2_AIE BIT(3) 782eeaa532SAlexandre Belloni #define RV3032_CTRL2_TIE BIT(4) 792eeaa532SAlexandre Belloni #define RV3032_CTRL2_UIE BIT(5) 802eeaa532SAlexandre Belloni #define RV3032_CTRL2_CLKIE BIT(6) 812eeaa532SAlexandre Belloni #define RV3032_CTRL2_TSE BIT(7) 822eeaa532SAlexandre Belloni 832eeaa532SAlexandre Belloni #define RV3032_PMU_TCM GENMASK(1, 0) 842eeaa532SAlexandre Belloni #define RV3032_PMU_TCR GENMASK(3, 2) 852eeaa532SAlexandre Belloni #define RV3032_PMU_BSM GENMASK(5, 4) 862eeaa532SAlexandre Belloni #define RV3032_PMU_NCLKE BIT(6) 872eeaa532SAlexandre Belloni 882eeaa532SAlexandre Belloni #define RV3032_PMU_BSM_DSM 1 892eeaa532SAlexandre Belloni #define RV3032_PMU_BSM_LSM 2 902eeaa532SAlexandre Belloni 912eeaa532SAlexandre Belloni #define RV3032_OFFSET_MSK GENMASK(5, 0) 922eeaa532SAlexandre Belloni 932eeaa532SAlexandre Belloni #define RV3032_EVT_CTRL_TSR BIT(2) 942eeaa532SAlexandre Belloni 952eeaa532SAlexandre Belloni #define RV3032_EEPROM_CMD_UPDATE 0x11 962eeaa532SAlexandre Belloni #define RV3032_EEPROM_CMD_WRITE 0x21 972eeaa532SAlexandre Belloni #define RV3032_EEPROM_CMD_READ 0x22 982eeaa532SAlexandre Belloni 992eeaa532SAlexandre Belloni #define RV3032_EEPROM_USER 0xCB 1002eeaa532SAlexandre Belloni 1012eeaa532SAlexandre Belloni #define RV3032_EEBUSY_POLL 10000 1022eeaa532SAlexandre Belloni #define RV3032_EEBUSY_TIMEOUT 100000 1032eeaa532SAlexandre Belloni 1042eeaa532SAlexandre Belloni #define OFFSET_STEP_PPT 238419 1052eeaa532SAlexandre Belloni 1062eeaa532SAlexandre Belloni struct rv3032_data { 1072eeaa532SAlexandre Belloni struct regmap *regmap; 1082eeaa532SAlexandre Belloni struct rtc_device *rtc; 109*6084eac3SAlexandre Belloni bool trickle_charger_set; 1102eeaa532SAlexandre Belloni #ifdef CONFIG_COMMON_CLK 1112eeaa532SAlexandre Belloni struct clk_hw clkout_hw; 1122eeaa532SAlexandre Belloni #endif 1132eeaa532SAlexandre Belloni }; 1142eeaa532SAlexandre Belloni 1152eeaa532SAlexandre Belloni static u16 rv3032_trickle_resistors[] = {1000, 2000, 7000, 11000}; 1162eeaa532SAlexandre Belloni static u16 rv3032_trickle_voltages[] = {0, 1750, 3000, 4400}; 1172eeaa532SAlexandre Belloni 1182eeaa532SAlexandre Belloni static int rv3032_exit_eerd(struct rv3032_data *rv3032, u32 eerd) 1192eeaa532SAlexandre Belloni { 1202eeaa532SAlexandre Belloni if (eerd) 1212eeaa532SAlexandre Belloni return 0; 1222eeaa532SAlexandre Belloni 1232eeaa532SAlexandre Belloni return regmap_update_bits(rv3032->regmap, RV3032_CTRL1, RV3032_CTRL1_EERD, 0); 1242eeaa532SAlexandre Belloni } 1252eeaa532SAlexandre Belloni 1262eeaa532SAlexandre Belloni static int rv3032_enter_eerd(struct rv3032_data *rv3032, u32 *eerd) 1272eeaa532SAlexandre Belloni { 1282eeaa532SAlexandre Belloni u32 ctrl1, status; 1292eeaa532SAlexandre Belloni int ret; 1302eeaa532SAlexandre Belloni 1312eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_CTRL1, &ctrl1); 1322eeaa532SAlexandre Belloni if (ret) 1332eeaa532SAlexandre Belloni return ret; 1342eeaa532SAlexandre Belloni 1352eeaa532SAlexandre Belloni *eerd = ctrl1 & RV3032_CTRL1_EERD; 1362eeaa532SAlexandre Belloni if (*eerd) 1372eeaa532SAlexandre Belloni return 0; 1382eeaa532SAlexandre Belloni 1392eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1, 1402eeaa532SAlexandre Belloni RV3032_CTRL1_EERD, RV3032_CTRL1_EERD); 1412eeaa532SAlexandre Belloni if (ret) 1422eeaa532SAlexandre Belloni return ret; 1432eeaa532SAlexandre Belloni 1442eeaa532SAlexandre Belloni ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status, 1452eeaa532SAlexandre Belloni !(status & RV3032_TLSB_EEBUSY), 1462eeaa532SAlexandre Belloni RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 1472eeaa532SAlexandre Belloni if (ret) { 1482eeaa532SAlexandre Belloni rv3032_exit_eerd(rv3032, *eerd); 1492eeaa532SAlexandre Belloni 1502eeaa532SAlexandre Belloni return ret; 1512eeaa532SAlexandre Belloni } 1522eeaa532SAlexandre Belloni 1532eeaa532SAlexandre Belloni return 0; 1542eeaa532SAlexandre Belloni } 1552eeaa532SAlexandre Belloni 1562eeaa532SAlexandre Belloni static int rv3032_update_cfg(struct rv3032_data *rv3032, unsigned int reg, 1572eeaa532SAlexandre Belloni unsigned int mask, unsigned int val) 1582eeaa532SAlexandre Belloni { 1592eeaa532SAlexandre Belloni u32 status, eerd; 1602eeaa532SAlexandre Belloni int ret; 1612eeaa532SAlexandre Belloni 1622eeaa532SAlexandre Belloni ret = rv3032_enter_eerd(rv3032, &eerd); 1632eeaa532SAlexandre Belloni if (ret) 1642eeaa532SAlexandre Belloni return ret; 1652eeaa532SAlexandre Belloni 1662eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, reg, mask, val); 1672eeaa532SAlexandre Belloni if (ret) 1682eeaa532SAlexandre Belloni goto exit_eerd; 1692eeaa532SAlexandre Belloni 1702eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, RV3032_EEPROM_CMD_UPDATE); 1712eeaa532SAlexandre Belloni if (ret) 1722eeaa532SAlexandre Belloni goto exit_eerd; 1732eeaa532SAlexandre Belloni 1742eeaa532SAlexandre Belloni usleep_range(46000, RV3032_EEBUSY_TIMEOUT); 1752eeaa532SAlexandre Belloni 1762eeaa532SAlexandre Belloni ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status, 1772eeaa532SAlexandre Belloni !(status & RV3032_TLSB_EEBUSY), 1782eeaa532SAlexandre Belloni RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 1792eeaa532SAlexandre Belloni 1802eeaa532SAlexandre Belloni exit_eerd: 1812eeaa532SAlexandre Belloni rv3032_exit_eerd(rv3032, eerd); 1822eeaa532SAlexandre Belloni 1832eeaa532SAlexandre Belloni return ret; 1842eeaa532SAlexandre Belloni } 1852eeaa532SAlexandre Belloni 1862eeaa532SAlexandre Belloni static irqreturn_t rv3032_handle_irq(int irq, void *dev_id) 1872eeaa532SAlexandre Belloni { 1882eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_id; 1892eeaa532SAlexandre Belloni unsigned long events = 0; 1902eeaa532SAlexandre Belloni u32 status = 0, ctrl = 0; 1912eeaa532SAlexandre Belloni 1922eeaa532SAlexandre Belloni if (regmap_read(rv3032->regmap, RV3032_STATUS, &status) < 0 || 1932eeaa532SAlexandre Belloni status == 0) { 1942eeaa532SAlexandre Belloni return IRQ_NONE; 1952eeaa532SAlexandre Belloni } 1962eeaa532SAlexandre Belloni 1972eeaa532SAlexandre Belloni if (status & RV3032_STATUS_TF) { 1982eeaa532SAlexandre Belloni status |= RV3032_STATUS_TF; 1992eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_TIE; 2002eeaa532SAlexandre Belloni events |= RTC_PF; 2012eeaa532SAlexandre Belloni } 2022eeaa532SAlexandre Belloni 2032eeaa532SAlexandre Belloni if (status & RV3032_STATUS_AF) { 2042eeaa532SAlexandre Belloni status |= RV3032_STATUS_AF; 2052eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_AIE; 2062eeaa532SAlexandre Belloni events |= RTC_AF; 2072eeaa532SAlexandre Belloni } 2082eeaa532SAlexandre Belloni 2092eeaa532SAlexandre Belloni if (status & RV3032_STATUS_UF) { 2102eeaa532SAlexandre Belloni status |= RV3032_STATUS_UF; 2112eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_UIE; 2122eeaa532SAlexandre Belloni events |= RTC_UF; 2132eeaa532SAlexandre Belloni } 2142eeaa532SAlexandre Belloni 2152eeaa532SAlexandre Belloni if (events) { 2162eeaa532SAlexandre Belloni rtc_update_irq(rv3032->rtc, 1, events); 2172eeaa532SAlexandre Belloni regmap_update_bits(rv3032->regmap, RV3032_STATUS, status, 0); 2182eeaa532SAlexandre Belloni regmap_update_bits(rv3032->regmap, RV3032_CTRL2, ctrl, 0); 2192eeaa532SAlexandre Belloni } 2202eeaa532SAlexandre Belloni 2212eeaa532SAlexandre Belloni return IRQ_HANDLED; 2222eeaa532SAlexandre Belloni } 2232eeaa532SAlexandre Belloni 2242eeaa532SAlexandre Belloni static int rv3032_get_time(struct device *dev, struct rtc_time *tm) 2252eeaa532SAlexandre Belloni { 2262eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 2272eeaa532SAlexandre Belloni u8 date[7]; 2282eeaa532SAlexandre Belloni int ret, status; 2292eeaa532SAlexandre Belloni 2302eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status); 2312eeaa532SAlexandre Belloni if (ret < 0) 2322eeaa532SAlexandre Belloni return ret; 2332eeaa532SAlexandre Belloni 2342eeaa532SAlexandre Belloni if (status & (RV3032_STATUS_PORF | RV3032_STATUS_VLF)) 2352eeaa532SAlexandre Belloni return -EINVAL; 2362eeaa532SAlexandre Belloni 2372eeaa532SAlexandre Belloni ret = regmap_bulk_read(rv3032->regmap, RV3032_SEC, date, sizeof(date)); 2382eeaa532SAlexandre Belloni if (ret) 2392eeaa532SAlexandre Belloni return ret; 2402eeaa532SAlexandre Belloni 2412eeaa532SAlexandre Belloni tm->tm_sec = bcd2bin(date[0] & 0x7f); 2422eeaa532SAlexandre Belloni tm->tm_min = bcd2bin(date[1] & 0x7f); 2432eeaa532SAlexandre Belloni tm->tm_hour = bcd2bin(date[2] & 0x3f); 2442eeaa532SAlexandre Belloni tm->tm_wday = date[3] & 0x7; 2452eeaa532SAlexandre Belloni tm->tm_mday = bcd2bin(date[4] & 0x3f); 2462eeaa532SAlexandre Belloni tm->tm_mon = bcd2bin(date[5] & 0x1f) - 1; 2472eeaa532SAlexandre Belloni tm->tm_year = bcd2bin(date[6]) + 100; 2482eeaa532SAlexandre Belloni 2492eeaa532SAlexandre Belloni return 0; 2502eeaa532SAlexandre Belloni } 2512eeaa532SAlexandre Belloni 2522eeaa532SAlexandre Belloni static int rv3032_set_time(struct device *dev, struct rtc_time *tm) 2532eeaa532SAlexandre Belloni { 2542eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 2552eeaa532SAlexandre Belloni u8 date[7]; 2562eeaa532SAlexandre Belloni int ret; 2572eeaa532SAlexandre Belloni 2582eeaa532SAlexandre Belloni date[0] = bin2bcd(tm->tm_sec); 2592eeaa532SAlexandre Belloni date[1] = bin2bcd(tm->tm_min); 2602eeaa532SAlexandre Belloni date[2] = bin2bcd(tm->tm_hour); 2612eeaa532SAlexandre Belloni date[3] = tm->tm_wday; 2622eeaa532SAlexandre Belloni date[4] = bin2bcd(tm->tm_mday); 2632eeaa532SAlexandre Belloni date[5] = bin2bcd(tm->tm_mon + 1); 2642eeaa532SAlexandre Belloni date[6] = bin2bcd(tm->tm_year - 100); 2652eeaa532SAlexandre Belloni 2662eeaa532SAlexandre Belloni ret = regmap_bulk_write(rv3032->regmap, RV3032_SEC, date, 2672eeaa532SAlexandre Belloni sizeof(date)); 2682eeaa532SAlexandre Belloni if (ret) 2692eeaa532SAlexandre Belloni return ret; 2702eeaa532SAlexandre Belloni 2712eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS, 2722eeaa532SAlexandre Belloni RV3032_STATUS_PORF | RV3032_STATUS_VLF, 0); 2732eeaa532SAlexandre Belloni 2742eeaa532SAlexandre Belloni return ret; 2752eeaa532SAlexandre Belloni } 2762eeaa532SAlexandre Belloni 2772eeaa532SAlexandre Belloni static int rv3032_get_alarm(struct device *dev, struct rtc_wkalrm *alrm) 2782eeaa532SAlexandre Belloni { 2792eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 2802eeaa532SAlexandre Belloni u8 alarmvals[3]; 2812eeaa532SAlexandre Belloni int status, ctrl, ret; 2822eeaa532SAlexandre Belloni 2832eeaa532SAlexandre Belloni ret = regmap_bulk_read(rv3032->regmap, RV3032_ALARM_MIN, alarmvals, 2842eeaa532SAlexandre Belloni sizeof(alarmvals)); 2852eeaa532SAlexandre Belloni if (ret) 2862eeaa532SAlexandre Belloni return ret; 2872eeaa532SAlexandre Belloni 2882eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status); 2892eeaa532SAlexandre Belloni if (ret < 0) 2902eeaa532SAlexandre Belloni return ret; 2912eeaa532SAlexandre Belloni 2922eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_CTRL2, &ctrl); 2932eeaa532SAlexandre Belloni if (ret < 0) 2942eeaa532SAlexandre Belloni return ret; 2952eeaa532SAlexandre Belloni 2962eeaa532SAlexandre Belloni alrm->time.tm_sec = 0; 2972eeaa532SAlexandre Belloni alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); 2982eeaa532SAlexandre Belloni alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); 2992eeaa532SAlexandre Belloni alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); 3002eeaa532SAlexandre Belloni 3012eeaa532SAlexandre Belloni alrm->enabled = !!(ctrl & RV3032_CTRL2_AIE); 3022eeaa532SAlexandre Belloni alrm->pending = (status & RV3032_STATUS_AF) && alrm->enabled; 3032eeaa532SAlexandre Belloni 3042eeaa532SAlexandre Belloni return 0; 3052eeaa532SAlexandre Belloni } 3062eeaa532SAlexandre Belloni 3072eeaa532SAlexandre Belloni static int rv3032_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 3082eeaa532SAlexandre Belloni { 3092eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 3102eeaa532SAlexandre Belloni u8 alarmvals[3]; 3112eeaa532SAlexandre Belloni u8 ctrl = 0; 3122eeaa532SAlexandre Belloni int ret; 3132eeaa532SAlexandre Belloni 3142eeaa532SAlexandre Belloni /* The alarm has no seconds, round up to nearest minute */ 3152eeaa532SAlexandre Belloni if (alrm->time.tm_sec) { 3162eeaa532SAlexandre Belloni time64_t alarm_time = rtc_tm_to_time64(&alrm->time); 3172eeaa532SAlexandre Belloni 3182eeaa532SAlexandre Belloni alarm_time += 60 - alrm->time.tm_sec; 3192eeaa532SAlexandre Belloni rtc_time64_to_tm(alarm_time, &alrm->time); 3202eeaa532SAlexandre Belloni } 3212eeaa532SAlexandre Belloni 3222eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, 3232eeaa532SAlexandre Belloni RV3032_CTRL2_AIE | RV3032_CTRL2_UIE, 0); 3242eeaa532SAlexandre Belloni if (ret) 3252eeaa532SAlexandre Belloni return ret; 3262eeaa532SAlexandre Belloni 3272eeaa532SAlexandre Belloni alarmvals[0] = bin2bcd(alrm->time.tm_min); 3282eeaa532SAlexandre Belloni alarmvals[1] = bin2bcd(alrm->time.tm_hour); 3292eeaa532SAlexandre Belloni alarmvals[2] = bin2bcd(alrm->time.tm_mday); 3302eeaa532SAlexandre Belloni 3312eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS, 3322eeaa532SAlexandre Belloni RV3032_STATUS_AF, 0); 3332eeaa532SAlexandre Belloni if (ret) 3342eeaa532SAlexandre Belloni return ret; 3352eeaa532SAlexandre Belloni 3362eeaa532SAlexandre Belloni ret = regmap_bulk_write(rv3032->regmap, RV3032_ALARM_MIN, alarmvals, 3372eeaa532SAlexandre Belloni sizeof(alarmvals)); 3382eeaa532SAlexandre Belloni if (ret) 3392eeaa532SAlexandre Belloni return ret; 3402eeaa532SAlexandre Belloni 3412eeaa532SAlexandre Belloni if (alrm->enabled) { 3422eeaa532SAlexandre Belloni if (rv3032->rtc->uie_rtctimer.enabled) 3432eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_UIE; 3442eeaa532SAlexandre Belloni if (rv3032->rtc->aie_timer.enabled) 3452eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_AIE; 3462eeaa532SAlexandre Belloni } 3472eeaa532SAlexandre Belloni 3482eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, 3492eeaa532SAlexandre Belloni RV3032_CTRL2_UIE | RV3032_CTRL2_AIE, ctrl); 3502eeaa532SAlexandre Belloni 3512eeaa532SAlexandre Belloni return ret; 3522eeaa532SAlexandre Belloni } 3532eeaa532SAlexandre Belloni 3542eeaa532SAlexandre Belloni static int rv3032_alarm_irq_enable(struct device *dev, unsigned int enabled) 3552eeaa532SAlexandre Belloni { 3562eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 3572eeaa532SAlexandre Belloni int ctrl = 0, ret; 3582eeaa532SAlexandre Belloni 3592eeaa532SAlexandre Belloni if (enabled) { 3602eeaa532SAlexandre Belloni if (rv3032->rtc->uie_rtctimer.enabled) 3612eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_UIE; 3622eeaa532SAlexandre Belloni if (rv3032->rtc->aie_timer.enabled) 3632eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_AIE; 3642eeaa532SAlexandre Belloni } 3652eeaa532SAlexandre Belloni 3662eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS, 3672eeaa532SAlexandre Belloni RV3032_STATUS_AF | RV3032_STATUS_UF, 0); 3682eeaa532SAlexandre Belloni if (ret) 3692eeaa532SAlexandre Belloni return ret; 3702eeaa532SAlexandre Belloni 3712eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, 3722eeaa532SAlexandre Belloni RV3032_CTRL2_UIE | RV3032_CTRL2_AIE, ctrl); 3732eeaa532SAlexandre Belloni if (ret) 3742eeaa532SAlexandre Belloni return ret; 3752eeaa532SAlexandre Belloni 3762eeaa532SAlexandre Belloni return 0; 3772eeaa532SAlexandre Belloni } 3782eeaa532SAlexandre Belloni 3792eeaa532SAlexandre Belloni static int rv3032_read_offset(struct device *dev, long *offset) 3802eeaa532SAlexandre Belloni { 3812eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 3822eeaa532SAlexandre Belloni int ret, value, steps; 3832eeaa532SAlexandre Belloni 3842eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_OFFSET, &value); 3852eeaa532SAlexandre Belloni if (ret < 0) 3862eeaa532SAlexandre Belloni return ret; 3872eeaa532SAlexandre Belloni 3882eeaa532SAlexandre Belloni steps = sign_extend32(FIELD_GET(RV3032_OFFSET_MSK, value), 5); 3892eeaa532SAlexandre Belloni 3902eeaa532SAlexandre Belloni *offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000); 3912eeaa532SAlexandre Belloni 3922eeaa532SAlexandre Belloni return 0; 3932eeaa532SAlexandre Belloni } 3942eeaa532SAlexandre Belloni 3952eeaa532SAlexandre Belloni static int rv3032_set_offset(struct device *dev, long offset) 3962eeaa532SAlexandre Belloni { 3972eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 3982eeaa532SAlexandre Belloni 3992eeaa532SAlexandre Belloni offset = clamp(offset, -7629L, 7391L) * 1000; 4002eeaa532SAlexandre Belloni offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT); 4012eeaa532SAlexandre Belloni 4022eeaa532SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_OFFSET, RV3032_OFFSET_MSK, 4032eeaa532SAlexandre Belloni FIELD_PREP(RV3032_OFFSET_MSK, offset)); 4042eeaa532SAlexandre Belloni } 4052eeaa532SAlexandre Belloni 406*6084eac3SAlexandre Belloni static int rv3032_param_get(struct device *dev, struct rtc_param *param) 407*6084eac3SAlexandre Belloni { 408*6084eac3SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 409*6084eac3SAlexandre Belloni int ret; 410*6084eac3SAlexandre Belloni 411*6084eac3SAlexandre Belloni switch(param->param) { 412*6084eac3SAlexandre Belloni u32 value; 413*6084eac3SAlexandre Belloni 414*6084eac3SAlexandre Belloni case RTC_PARAM_BACKUP_SWITCH_MODE: 415*6084eac3SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_PMU, &value); 416*6084eac3SAlexandre Belloni if (ret < 0) 417*6084eac3SAlexandre Belloni return ret; 418*6084eac3SAlexandre Belloni 419*6084eac3SAlexandre Belloni value = FIELD_GET(RV3032_PMU_BSM, value); 420*6084eac3SAlexandre Belloni 421*6084eac3SAlexandre Belloni switch(value) { 422*6084eac3SAlexandre Belloni case RV3032_PMU_BSM_DSM: 423*6084eac3SAlexandre Belloni param->uvalue = RTC_BSM_DIRECT; 424*6084eac3SAlexandre Belloni break; 425*6084eac3SAlexandre Belloni case RV3032_PMU_BSM_LSM: 426*6084eac3SAlexandre Belloni param->uvalue = RTC_BSM_LEVEL; 427*6084eac3SAlexandre Belloni break; 428*6084eac3SAlexandre Belloni default: 429*6084eac3SAlexandre Belloni param->uvalue = RTC_BSM_DISABLED; 430*6084eac3SAlexandre Belloni } 431*6084eac3SAlexandre Belloni 432*6084eac3SAlexandre Belloni break; 433*6084eac3SAlexandre Belloni 434*6084eac3SAlexandre Belloni default: 435*6084eac3SAlexandre Belloni return -EINVAL; 436*6084eac3SAlexandre Belloni } 437*6084eac3SAlexandre Belloni 438*6084eac3SAlexandre Belloni return 0; 439*6084eac3SAlexandre Belloni } 440*6084eac3SAlexandre Belloni 441*6084eac3SAlexandre Belloni static int rv3032_param_set(struct device *dev, struct rtc_param *param) 442*6084eac3SAlexandre Belloni { 443*6084eac3SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 444*6084eac3SAlexandre Belloni 445*6084eac3SAlexandre Belloni switch(param->param) { 446*6084eac3SAlexandre Belloni u8 mode; 447*6084eac3SAlexandre Belloni case RTC_PARAM_BACKUP_SWITCH_MODE: 448*6084eac3SAlexandre Belloni if (rv3032->trickle_charger_set) 449*6084eac3SAlexandre Belloni return -EINVAL; 450*6084eac3SAlexandre Belloni 451*6084eac3SAlexandre Belloni switch (param->uvalue) { 452*6084eac3SAlexandre Belloni case RTC_BSM_DISABLED: 453*6084eac3SAlexandre Belloni mode = 0; 454*6084eac3SAlexandre Belloni break; 455*6084eac3SAlexandre Belloni case RTC_BSM_DIRECT: 456*6084eac3SAlexandre Belloni mode = RV3032_PMU_BSM_DSM; 457*6084eac3SAlexandre Belloni break; 458*6084eac3SAlexandre Belloni case RTC_BSM_LEVEL: 459*6084eac3SAlexandre Belloni mode = RV3032_PMU_BSM_LSM; 460*6084eac3SAlexandre Belloni break; 461*6084eac3SAlexandre Belloni default: 462*6084eac3SAlexandre Belloni return -EINVAL; 463*6084eac3SAlexandre Belloni } 464*6084eac3SAlexandre Belloni 465*6084eac3SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_BSM, 466*6084eac3SAlexandre Belloni FIELD_PREP(RV3032_PMU_BSM, mode)); 467*6084eac3SAlexandre Belloni 468*6084eac3SAlexandre Belloni default: 469*6084eac3SAlexandre Belloni return -EINVAL; 470*6084eac3SAlexandre Belloni } 471*6084eac3SAlexandre Belloni 472*6084eac3SAlexandre Belloni return 0; 473*6084eac3SAlexandre Belloni } 474*6084eac3SAlexandre Belloni 4752eeaa532SAlexandre Belloni static int rv3032_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 4762eeaa532SAlexandre Belloni { 4772eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 4782eeaa532SAlexandre Belloni int status, val = 0, ret = 0; 4792eeaa532SAlexandre Belloni 4802eeaa532SAlexandre Belloni switch (cmd) { 4812eeaa532SAlexandre Belloni case RTC_VL_READ: 4822eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status); 4832eeaa532SAlexandre Belloni if (ret < 0) 4842eeaa532SAlexandre Belloni return ret; 4852eeaa532SAlexandre Belloni 4862eeaa532SAlexandre Belloni if (status & (RV3032_STATUS_PORF | RV3032_STATUS_VLF)) 4872eeaa532SAlexandre Belloni val = RTC_VL_DATA_INVALID; 4882eeaa532SAlexandre Belloni return put_user(val, (unsigned int __user *)arg); 4892eeaa532SAlexandre Belloni 4902eeaa532SAlexandre Belloni default: 4912eeaa532SAlexandre Belloni return -ENOIOCTLCMD; 4922eeaa532SAlexandre Belloni } 4932eeaa532SAlexandre Belloni } 4942eeaa532SAlexandre Belloni 4952eeaa532SAlexandre Belloni static int rv3032_nvram_write(void *priv, unsigned int offset, void *val, size_t bytes) 4962eeaa532SAlexandre Belloni { 4972eeaa532SAlexandre Belloni return regmap_bulk_write(priv, RV3032_RAM1 + offset, val, bytes); 4982eeaa532SAlexandre Belloni } 4992eeaa532SAlexandre Belloni 5002eeaa532SAlexandre Belloni static int rv3032_nvram_read(void *priv, unsigned int offset, void *val, size_t bytes) 5012eeaa532SAlexandre Belloni { 5022eeaa532SAlexandre Belloni return regmap_bulk_read(priv, RV3032_RAM1 + offset, val, bytes); 5032eeaa532SAlexandre Belloni } 5042eeaa532SAlexandre Belloni 5052eeaa532SAlexandre Belloni static int rv3032_eeprom_write(void *priv, unsigned int offset, void *val, size_t bytes) 5062eeaa532SAlexandre Belloni { 5072eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = priv; 5082eeaa532SAlexandre Belloni u32 status, eerd; 5092eeaa532SAlexandre Belloni int i, ret; 5102eeaa532SAlexandre Belloni u8 *buf = val; 5112eeaa532SAlexandre Belloni 5122eeaa532SAlexandre Belloni ret = rv3032_enter_eerd(rv3032, &eerd); 5132eeaa532SAlexandre Belloni if (ret) 5142eeaa532SAlexandre Belloni return ret; 5152eeaa532SAlexandre Belloni 5162eeaa532SAlexandre Belloni for (i = 0; i < bytes; i++) { 5172eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_ADDR, 5182eeaa532SAlexandre Belloni RV3032_EEPROM_USER + offset + i); 5192eeaa532SAlexandre Belloni if (ret) 5202eeaa532SAlexandre Belloni goto exit_eerd; 5212eeaa532SAlexandre Belloni 5222eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_DATA, buf[i]); 5232eeaa532SAlexandre Belloni if (ret) 5242eeaa532SAlexandre Belloni goto exit_eerd; 5252eeaa532SAlexandre Belloni 5262eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, 5272eeaa532SAlexandre Belloni RV3032_EEPROM_CMD_WRITE); 5282eeaa532SAlexandre Belloni if (ret) 5292eeaa532SAlexandre Belloni goto exit_eerd; 5302eeaa532SAlexandre Belloni 5312eeaa532SAlexandre Belloni usleep_range(RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 5322eeaa532SAlexandre Belloni 5332eeaa532SAlexandre Belloni ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status, 5342eeaa532SAlexandre Belloni !(status & RV3032_TLSB_EEBUSY), 5352eeaa532SAlexandre Belloni RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 5362eeaa532SAlexandre Belloni if (ret) 5372eeaa532SAlexandre Belloni goto exit_eerd; 5382eeaa532SAlexandre Belloni } 5392eeaa532SAlexandre Belloni 5402eeaa532SAlexandre Belloni exit_eerd: 5412eeaa532SAlexandre Belloni rv3032_exit_eerd(rv3032, eerd); 5422eeaa532SAlexandre Belloni 5432eeaa532SAlexandre Belloni return ret; 5442eeaa532SAlexandre Belloni } 5452eeaa532SAlexandre Belloni 5462eeaa532SAlexandre Belloni static int rv3032_eeprom_read(void *priv, unsigned int offset, void *val, size_t bytes) 5472eeaa532SAlexandre Belloni { 5482eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = priv; 5492eeaa532SAlexandre Belloni u32 status, eerd, data; 5502eeaa532SAlexandre Belloni int i, ret; 5512eeaa532SAlexandre Belloni u8 *buf = val; 5522eeaa532SAlexandre Belloni 5532eeaa532SAlexandre Belloni ret = rv3032_enter_eerd(rv3032, &eerd); 5542eeaa532SAlexandre Belloni if (ret) 5552eeaa532SAlexandre Belloni return ret; 5562eeaa532SAlexandre Belloni 5572eeaa532SAlexandre Belloni for (i = 0; i < bytes; i++) { 5582eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_ADDR, 5592eeaa532SAlexandre Belloni RV3032_EEPROM_USER + offset + i); 5602eeaa532SAlexandre Belloni if (ret) 5612eeaa532SAlexandre Belloni goto exit_eerd; 5622eeaa532SAlexandre Belloni 5632eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, 5642eeaa532SAlexandre Belloni RV3032_EEPROM_CMD_READ); 5652eeaa532SAlexandre Belloni if (ret) 5662eeaa532SAlexandre Belloni goto exit_eerd; 5672eeaa532SAlexandre Belloni 5682eeaa532SAlexandre Belloni ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status, 5692eeaa532SAlexandre Belloni !(status & RV3032_TLSB_EEBUSY), 5702eeaa532SAlexandre Belloni RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 5712eeaa532SAlexandre Belloni if (ret) 5722eeaa532SAlexandre Belloni goto exit_eerd; 5732eeaa532SAlexandre Belloni 5742eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_EEPROM_DATA, &data); 5752eeaa532SAlexandre Belloni if (ret) 5762eeaa532SAlexandre Belloni goto exit_eerd; 5772eeaa532SAlexandre Belloni buf[i] = data; 5782eeaa532SAlexandre Belloni } 5792eeaa532SAlexandre Belloni 5802eeaa532SAlexandre Belloni exit_eerd: 5812eeaa532SAlexandre Belloni rv3032_exit_eerd(rv3032, eerd); 5822eeaa532SAlexandre Belloni 5832eeaa532SAlexandre Belloni return ret; 5842eeaa532SAlexandre Belloni } 5852eeaa532SAlexandre Belloni 5862eeaa532SAlexandre Belloni static int rv3032_trickle_charger_setup(struct device *dev, struct rv3032_data *rv3032) 5872eeaa532SAlexandre Belloni { 5882eeaa532SAlexandre Belloni u32 val, ohms, voltage; 5892eeaa532SAlexandre Belloni int i; 5902eeaa532SAlexandre Belloni 5912eeaa532SAlexandre Belloni val = FIELD_PREP(RV3032_PMU_TCM, 1) | FIELD_PREP(RV3032_PMU_BSM, RV3032_PMU_BSM_DSM); 5922eeaa532SAlexandre Belloni if (!device_property_read_u32(dev, "trickle-voltage-millivolt", &voltage)) { 5932eeaa532SAlexandre Belloni for (i = 0; i < ARRAY_SIZE(rv3032_trickle_voltages); i++) 5942eeaa532SAlexandre Belloni if (voltage == rv3032_trickle_voltages[i]) 5952eeaa532SAlexandre Belloni break; 5962eeaa532SAlexandre Belloni if (i < ARRAY_SIZE(rv3032_trickle_voltages)) 5972eeaa532SAlexandre Belloni val = FIELD_PREP(RV3032_PMU_TCM, i) | 5982eeaa532SAlexandre Belloni FIELD_PREP(RV3032_PMU_BSM, RV3032_PMU_BSM_LSM); 5992eeaa532SAlexandre Belloni } 6002eeaa532SAlexandre Belloni 6012eeaa532SAlexandre Belloni if (device_property_read_u32(dev, "trickle-resistor-ohms", &ohms)) 6022eeaa532SAlexandre Belloni return 0; 6032eeaa532SAlexandre Belloni 6042eeaa532SAlexandre Belloni for (i = 0; i < ARRAY_SIZE(rv3032_trickle_resistors); i++) 6052eeaa532SAlexandre Belloni if (ohms == rv3032_trickle_resistors[i]) 6062eeaa532SAlexandre Belloni break; 6072eeaa532SAlexandre Belloni 6082eeaa532SAlexandre Belloni if (i >= ARRAY_SIZE(rv3032_trickle_resistors)) { 6092eeaa532SAlexandre Belloni dev_warn(dev, "invalid trickle resistor value\n"); 6102eeaa532SAlexandre Belloni 6112eeaa532SAlexandre Belloni return 0; 6122eeaa532SAlexandre Belloni } 6132eeaa532SAlexandre Belloni 614*6084eac3SAlexandre Belloni rv3032->trickle_charger_set = true; 615*6084eac3SAlexandre Belloni 6162eeaa532SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_PMU, 6172eeaa532SAlexandre Belloni RV3032_PMU_TCR | RV3032_PMU_TCM | RV3032_PMU_BSM, 6182eeaa532SAlexandre Belloni val | FIELD_PREP(RV3032_PMU_TCR, i)); 6192eeaa532SAlexandre Belloni } 6202eeaa532SAlexandre Belloni 6212eeaa532SAlexandre Belloni #ifdef CONFIG_COMMON_CLK 6222eeaa532SAlexandre Belloni #define clkout_hw_to_rv3032(hw) container_of(hw, struct rv3032_data, clkout_hw) 6232eeaa532SAlexandre Belloni 6242eeaa532SAlexandre Belloni static int clkout_xtal_rates[] = { 6252eeaa532SAlexandre Belloni 32768, 6262eeaa532SAlexandre Belloni 1024, 6272eeaa532SAlexandre Belloni 64, 6282eeaa532SAlexandre Belloni 1, 6292eeaa532SAlexandre Belloni }; 6302eeaa532SAlexandre Belloni 6312eeaa532SAlexandre Belloni #define RV3032_HFD_STEP 8192 6322eeaa532SAlexandre Belloni 6332eeaa532SAlexandre Belloni static unsigned long rv3032_clkout_recalc_rate(struct clk_hw *hw, 6342eeaa532SAlexandre Belloni unsigned long parent_rate) 6352eeaa532SAlexandre Belloni { 6362eeaa532SAlexandre Belloni int clkout, ret; 6372eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 6382eeaa532SAlexandre Belloni 6392eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_CLKOUT2, &clkout); 6402eeaa532SAlexandre Belloni if (ret < 0) 6412eeaa532SAlexandre Belloni return 0; 6422eeaa532SAlexandre Belloni 6432eeaa532SAlexandre Belloni if (clkout & RV3032_CLKOUT2_OS) { 6442eeaa532SAlexandre Belloni unsigned long rate = FIELD_GET(RV3032_CLKOUT2_HFD_MSK, clkout) << 8; 6452eeaa532SAlexandre Belloni 6462eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_CLKOUT1, &clkout); 6472eeaa532SAlexandre Belloni if (ret < 0) 6482eeaa532SAlexandre Belloni return 0; 6492eeaa532SAlexandre Belloni 6502eeaa532SAlexandre Belloni rate += clkout + 1; 6512eeaa532SAlexandre Belloni 6522eeaa532SAlexandre Belloni return rate * RV3032_HFD_STEP; 6532eeaa532SAlexandre Belloni } 6542eeaa532SAlexandre Belloni 6552eeaa532SAlexandre Belloni return clkout_xtal_rates[FIELD_GET(RV3032_CLKOUT2_FD_MSK, clkout)]; 6562eeaa532SAlexandre Belloni } 6572eeaa532SAlexandre Belloni 6582eeaa532SAlexandre Belloni static long rv3032_clkout_round_rate(struct clk_hw *hw, unsigned long rate, 6592eeaa532SAlexandre Belloni unsigned long *prate) 6602eeaa532SAlexandre Belloni { 6612eeaa532SAlexandre Belloni int i, hfd; 6622eeaa532SAlexandre Belloni 6632eeaa532SAlexandre Belloni if (rate < RV3032_HFD_STEP) 6642eeaa532SAlexandre Belloni for (i = 0; i < ARRAY_SIZE(clkout_xtal_rates); i++) 6652eeaa532SAlexandre Belloni if (clkout_xtal_rates[i] <= rate) 6662eeaa532SAlexandre Belloni return clkout_xtal_rates[i]; 6672eeaa532SAlexandre Belloni 6682eeaa532SAlexandre Belloni hfd = DIV_ROUND_CLOSEST(rate, RV3032_HFD_STEP); 6692eeaa532SAlexandre Belloni 6702eeaa532SAlexandre Belloni return RV3032_HFD_STEP * clamp(hfd, 0, 8192); 6712eeaa532SAlexandre Belloni } 6722eeaa532SAlexandre Belloni 6732eeaa532SAlexandre Belloni static int rv3032_clkout_set_rate(struct clk_hw *hw, unsigned long rate, 6742eeaa532SAlexandre Belloni unsigned long parent_rate) 6752eeaa532SAlexandre Belloni { 6762eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 6772eeaa532SAlexandre Belloni u32 status, eerd; 6782eeaa532SAlexandre Belloni int i, hfd, ret; 6792eeaa532SAlexandre Belloni 6802eeaa532SAlexandre Belloni for (i = 0; i < ARRAY_SIZE(clkout_xtal_rates); i++) { 6812eeaa532SAlexandre Belloni if (clkout_xtal_rates[i] == rate) { 6822eeaa532SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_CLKOUT2, 0xff, 6832eeaa532SAlexandre Belloni FIELD_PREP(RV3032_CLKOUT2_FD_MSK, i)); 6842eeaa532SAlexandre Belloni } 6852eeaa532SAlexandre Belloni } 6862eeaa532SAlexandre Belloni 6872eeaa532SAlexandre Belloni hfd = DIV_ROUND_CLOSEST(rate, RV3032_HFD_STEP); 6882eeaa532SAlexandre Belloni hfd = clamp(hfd, 1, 8192) - 1; 6892eeaa532SAlexandre Belloni 6902eeaa532SAlexandre Belloni ret = rv3032_enter_eerd(rv3032, &eerd); 6912eeaa532SAlexandre Belloni if (ret) 692c3336b8aSDan Carpenter return ret; 6932eeaa532SAlexandre Belloni 6942eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_CLKOUT1, hfd & 0xff); 6952eeaa532SAlexandre Belloni if (ret) 696c3336b8aSDan Carpenter goto exit_eerd; 6972eeaa532SAlexandre Belloni 6982eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_CLKOUT2, RV3032_CLKOUT2_OS | 6992eeaa532SAlexandre Belloni FIELD_PREP(RV3032_CLKOUT2_HFD_MSK, hfd >> 8)); 7002eeaa532SAlexandre Belloni if (ret) 7012eeaa532SAlexandre Belloni goto exit_eerd; 7022eeaa532SAlexandre Belloni 7032eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, RV3032_EEPROM_CMD_UPDATE); 7042eeaa532SAlexandre Belloni if (ret) 7052eeaa532SAlexandre Belloni goto exit_eerd; 7062eeaa532SAlexandre Belloni 7072eeaa532SAlexandre Belloni usleep_range(46000, RV3032_EEBUSY_TIMEOUT); 7082eeaa532SAlexandre Belloni 7092eeaa532SAlexandre Belloni ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status, 7102eeaa532SAlexandre Belloni !(status & RV3032_TLSB_EEBUSY), 7112eeaa532SAlexandre Belloni RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 7122eeaa532SAlexandre Belloni 7132eeaa532SAlexandre Belloni exit_eerd: 7142eeaa532SAlexandre Belloni rv3032_exit_eerd(rv3032, eerd); 7152eeaa532SAlexandre Belloni 7162eeaa532SAlexandre Belloni return ret; 7172eeaa532SAlexandre Belloni } 7182eeaa532SAlexandre Belloni 7192eeaa532SAlexandre Belloni static int rv3032_clkout_prepare(struct clk_hw *hw) 7202eeaa532SAlexandre Belloni { 7212eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 7222eeaa532SAlexandre Belloni 7232eeaa532SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_NCLKE, 0); 7242eeaa532SAlexandre Belloni } 7252eeaa532SAlexandre Belloni 7262eeaa532SAlexandre Belloni static void rv3032_clkout_unprepare(struct clk_hw *hw) 7272eeaa532SAlexandre Belloni { 7282eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 7292eeaa532SAlexandre Belloni 7302eeaa532SAlexandre Belloni rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_NCLKE, RV3032_PMU_NCLKE); 7312eeaa532SAlexandre Belloni } 7322eeaa532SAlexandre Belloni 7332eeaa532SAlexandre Belloni static int rv3032_clkout_is_prepared(struct clk_hw *hw) 7342eeaa532SAlexandre Belloni { 7352eeaa532SAlexandre Belloni int val, ret; 7362eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 7372eeaa532SAlexandre Belloni 7382eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_PMU, &val); 7392eeaa532SAlexandre Belloni if (ret < 0) 7402eeaa532SAlexandre Belloni return ret; 7412eeaa532SAlexandre Belloni 7422eeaa532SAlexandre Belloni return !(val & RV3032_PMU_NCLKE); 7432eeaa532SAlexandre Belloni } 7442eeaa532SAlexandre Belloni 7452eeaa532SAlexandre Belloni static const struct clk_ops rv3032_clkout_ops = { 7462eeaa532SAlexandre Belloni .prepare = rv3032_clkout_prepare, 7472eeaa532SAlexandre Belloni .unprepare = rv3032_clkout_unprepare, 7482eeaa532SAlexandre Belloni .is_prepared = rv3032_clkout_is_prepared, 7492eeaa532SAlexandre Belloni .recalc_rate = rv3032_clkout_recalc_rate, 7502eeaa532SAlexandre Belloni .round_rate = rv3032_clkout_round_rate, 7512eeaa532SAlexandre Belloni .set_rate = rv3032_clkout_set_rate, 7522eeaa532SAlexandre Belloni }; 7532eeaa532SAlexandre Belloni 7542eeaa532SAlexandre Belloni static int rv3032_clkout_register_clk(struct rv3032_data *rv3032, 7552eeaa532SAlexandre Belloni struct i2c_client *client) 7562eeaa532SAlexandre Belloni { 7572eeaa532SAlexandre Belloni int ret; 7582eeaa532SAlexandre Belloni struct clk *clk; 7592eeaa532SAlexandre Belloni struct clk_init_data init; 7602eeaa532SAlexandre Belloni struct device_node *node = client->dev.of_node; 7612eeaa532SAlexandre Belloni 7622eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_TLSB, RV3032_TLSB_CLKF, 0); 7632eeaa532SAlexandre Belloni if (ret < 0) 7642eeaa532SAlexandre Belloni return ret; 7652eeaa532SAlexandre Belloni 7662eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, RV3032_CTRL2_CLKIE, 0); 7672eeaa532SAlexandre Belloni if (ret < 0) 7682eeaa532SAlexandre Belloni return ret; 7692eeaa532SAlexandre Belloni 7702eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_CLK_IRQ, 0); 7712eeaa532SAlexandre Belloni if (ret < 0) 7722eeaa532SAlexandre Belloni return ret; 7732eeaa532SAlexandre Belloni 7742eeaa532SAlexandre Belloni init.name = "rv3032-clkout"; 7752eeaa532SAlexandre Belloni init.ops = &rv3032_clkout_ops; 7762eeaa532SAlexandre Belloni init.flags = 0; 7772eeaa532SAlexandre Belloni init.parent_names = NULL; 7782eeaa532SAlexandre Belloni init.num_parents = 0; 7792eeaa532SAlexandre Belloni rv3032->clkout_hw.init = &init; 7802eeaa532SAlexandre Belloni 7812eeaa532SAlexandre Belloni of_property_read_string(node, "clock-output-names", &init.name); 7822eeaa532SAlexandre Belloni 7832eeaa532SAlexandre Belloni clk = devm_clk_register(&client->dev, &rv3032->clkout_hw); 7842eeaa532SAlexandre Belloni if (!IS_ERR(clk)) 7852eeaa532SAlexandre Belloni of_clk_add_provider(node, of_clk_src_simple_get, clk); 7862eeaa532SAlexandre Belloni 7872eeaa532SAlexandre Belloni return 0; 7882eeaa532SAlexandre Belloni } 7892eeaa532SAlexandre Belloni #endif 7902eeaa532SAlexandre Belloni 7912eeaa532SAlexandre Belloni static int rv3032_hwmon_read_temp(struct device *dev, long *mC) 7922eeaa532SAlexandre Belloni { 7932eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 7942eeaa532SAlexandre Belloni u8 buf[2]; 7952eeaa532SAlexandre Belloni int temp, prev = 0; 7962eeaa532SAlexandre Belloni int ret; 7972eeaa532SAlexandre Belloni 7982eeaa532SAlexandre Belloni ret = regmap_bulk_read(rv3032->regmap, RV3032_TLSB, buf, sizeof(buf)); 7992eeaa532SAlexandre Belloni if (ret) 8002eeaa532SAlexandre Belloni return ret; 8012eeaa532SAlexandre Belloni 8022eeaa532SAlexandre Belloni temp = sign_extend32(buf[1], 7) << 4; 8032eeaa532SAlexandre Belloni temp |= FIELD_GET(RV3032_TLSB_TEMP, buf[0]); 8042eeaa532SAlexandre Belloni 8052eeaa532SAlexandre Belloni /* No blocking or shadowing on RV3032_TLSB and RV3032_TMSB */ 8062eeaa532SAlexandre Belloni do { 8072eeaa532SAlexandre Belloni prev = temp; 8082eeaa532SAlexandre Belloni 8092eeaa532SAlexandre Belloni ret = regmap_bulk_read(rv3032->regmap, RV3032_TLSB, buf, sizeof(buf)); 8102eeaa532SAlexandre Belloni if (ret) 8112eeaa532SAlexandre Belloni return ret; 8122eeaa532SAlexandre Belloni 8132eeaa532SAlexandre Belloni temp = sign_extend32(buf[1], 7) << 4; 8142eeaa532SAlexandre Belloni temp |= FIELD_GET(RV3032_TLSB_TEMP, buf[0]); 8152eeaa532SAlexandre Belloni } while (temp != prev); 8162eeaa532SAlexandre Belloni 8172eeaa532SAlexandre Belloni *mC = (temp * 1000) / 16; 8182eeaa532SAlexandre Belloni 8192eeaa532SAlexandre Belloni return 0; 8202eeaa532SAlexandre Belloni } 8212eeaa532SAlexandre Belloni 8222eeaa532SAlexandre Belloni static umode_t rv3032_hwmon_is_visible(const void *data, enum hwmon_sensor_types type, 8232eeaa532SAlexandre Belloni u32 attr, int channel) 8242eeaa532SAlexandre Belloni { 8252eeaa532SAlexandre Belloni if (type != hwmon_temp) 8262eeaa532SAlexandre Belloni return 0; 8272eeaa532SAlexandre Belloni 8282eeaa532SAlexandre Belloni switch (attr) { 8292eeaa532SAlexandre Belloni case hwmon_temp_input: 8302eeaa532SAlexandre Belloni return 0444; 8312eeaa532SAlexandre Belloni default: 8322eeaa532SAlexandre Belloni return 0; 8332eeaa532SAlexandre Belloni } 8342eeaa532SAlexandre Belloni } 8352eeaa532SAlexandre Belloni 8362eeaa532SAlexandre Belloni static int rv3032_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 8372eeaa532SAlexandre Belloni u32 attr, int channel, long *temp) 8382eeaa532SAlexandre Belloni { 8392eeaa532SAlexandre Belloni int err; 8402eeaa532SAlexandre Belloni 8412eeaa532SAlexandre Belloni switch (attr) { 8422eeaa532SAlexandre Belloni case hwmon_temp_input: 8432eeaa532SAlexandre Belloni err = rv3032_hwmon_read_temp(dev, temp); 8442eeaa532SAlexandre Belloni break; 8452eeaa532SAlexandre Belloni default: 8462eeaa532SAlexandre Belloni err = -EOPNOTSUPP; 8472eeaa532SAlexandre Belloni break; 8482eeaa532SAlexandre Belloni } 8492eeaa532SAlexandre Belloni 8502eeaa532SAlexandre Belloni return err; 8512eeaa532SAlexandre Belloni } 8522eeaa532SAlexandre Belloni 8532eeaa532SAlexandre Belloni static const struct hwmon_channel_info *rv3032_hwmon_info[] = { 8542eeaa532SAlexandre Belloni HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), 8552eeaa532SAlexandre Belloni HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), 8562eeaa532SAlexandre Belloni NULL 8572eeaa532SAlexandre Belloni }; 8582eeaa532SAlexandre Belloni 8592eeaa532SAlexandre Belloni static const struct hwmon_ops rv3032_hwmon_hwmon_ops = { 8602eeaa532SAlexandre Belloni .is_visible = rv3032_hwmon_is_visible, 8612eeaa532SAlexandre Belloni .read = rv3032_hwmon_read, 8622eeaa532SAlexandre Belloni }; 8632eeaa532SAlexandre Belloni 8642eeaa532SAlexandre Belloni static const struct hwmon_chip_info rv3032_hwmon_chip_info = { 8652eeaa532SAlexandre Belloni .ops = &rv3032_hwmon_hwmon_ops, 8662eeaa532SAlexandre Belloni .info = rv3032_hwmon_info, 8672eeaa532SAlexandre Belloni }; 8682eeaa532SAlexandre Belloni 8692eeaa532SAlexandre Belloni static void rv3032_hwmon_register(struct device *dev) 8702eeaa532SAlexandre Belloni { 8712eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 8722eeaa532SAlexandre Belloni 8732eeaa532SAlexandre Belloni if (!IS_REACHABLE(CONFIG_HWMON)) 8742eeaa532SAlexandre Belloni return; 8752eeaa532SAlexandre Belloni 8762eeaa532SAlexandre Belloni devm_hwmon_device_register_with_info(dev, "rv3032", rv3032, &rv3032_hwmon_chip_info, NULL); 8772eeaa532SAlexandre Belloni } 8782eeaa532SAlexandre Belloni 87919588d50SAlexandre Belloni static const struct rtc_class_ops rv3032_rtc_ops = { 8802eeaa532SAlexandre Belloni .read_time = rv3032_get_time, 8812eeaa532SAlexandre Belloni .set_time = rv3032_set_time, 8822eeaa532SAlexandre Belloni .read_offset = rv3032_read_offset, 8832eeaa532SAlexandre Belloni .set_offset = rv3032_set_offset, 8842eeaa532SAlexandre Belloni .ioctl = rv3032_ioctl, 88519588d50SAlexandre Belloni .read_alarm = rv3032_get_alarm, 88619588d50SAlexandre Belloni .set_alarm = rv3032_set_alarm, 88719588d50SAlexandre Belloni .alarm_irq_enable = rv3032_alarm_irq_enable, 888*6084eac3SAlexandre Belloni .param_get = rv3032_param_get, 889*6084eac3SAlexandre Belloni .param_set = rv3032_param_set, 8902eeaa532SAlexandre Belloni }; 8912eeaa532SAlexandre Belloni 8922eeaa532SAlexandre Belloni static const struct regmap_config regmap_config = { 8932eeaa532SAlexandre Belloni .reg_bits = 8, 8942eeaa532SAlexandre Belloni .val_bits = 8, 8952eeaa532SAlexandre Belloni .max_register = 0xCA, 8962eeaa532SAlexandre Belloni }; 8972eeaa532SAlexandre Belloni 8982eeaa532SAlexandre Belloni static int rv3032_probe(struct i2c_client *client) 8992eeaa532SAlexandre Belloni { 9002eeaa532SAlexandre Belloni struct rv3032_data *rv3032; 9012eeaa532SAlexandre Belloni int ret, status; 9022eeaa532SAlexandre Belloni struct nvmem_config nvmem_cfg = { 9032eeaa532SAlexandre Belloni .name = "rv3032_nvram", 9042eeaa532SAlexandre Belloni .word_size = 1, 9052eeaa532SAlexandre Belloni .stride = 1, 9062eeaa532SAlexandre Belloni .size = 16, 9072eeaa532SAlexandre Belloni .type = NVMEM_TYPE_BATTERY_BACKED, 9082eeaa532SAlexandre Belloni .reg_read = rv3032_nvram_read, 9092eeaa532SAlexandre Belloni .reg_write = rv3032_nvram_write, 9102eeaa532SAlexandre Belloni }; 9112eeaa532SAlexandre Belloni struct nvmem_config eeprom_cfg = { 9122eeaa532SAlexandre Belloni .name = "rv3032_eeprom", 9132eeaa532SAlexandre Belloni .word_size = 1, 9142eeaa532SAlexandre Belloni .stride = 1, 9152eeaa532SAlexandre Belloni .size = 32, 9162eeaa532SAlexandre Belloni .type = NVMEM_TYPE_EEPROM, 9172eeaa532SAlexandre Belloni .reg_read = rv3032_eeprom_read, 9182eeaa532SAlexandre Belloni .reg_write = rv3032_eeprom_write, 9192eeaa532SAlexandre Belloni }; 9202eeaa532SAlexandre Belloni 9212eeaa532SAlexandre Belloni rv3032 = devm_kzalloc(&client->dev, sizeof(struct rv3032_data), 9222eeaa532SAlexandre Belloni GFP_KERNEL); 9232eeaa532SAlexandre Belloni if (!rv3032) 9242eeaa532SAlexandre Belloni return -ENOMEM; 9252eeaa532SAlexandre Belloni 9262eeaa532SAlexandre Belloni rv3032->regmap = devm_regmap_init_i2c(client, ®map_config); 9272eeaa532SAlexandre Belloni if (IS_ERR(rv3032->regmap)) 9282eeaa532SAlexandre Belloni return PTR_ERR(rv3032->regmap); 9292eeaa532SAlexandre Belloni 9302eeaa532SAlexandre Belloni i2c_set_clientdata(client, rv3032); 9312eeaa532SAlexandre Belloni 9322eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status); 9332eeaa532SAlexandre Belloni if (ret < 0) 9342eeaa532SAlexandre Belloni return ret; 9352eeaa532SAlexandre Belloni 9362eeaa532SAlexandre Belloni rv3032->rtc = devm_rtc_allocate_device(&client->dev); 9372eeaa532SAlexandre Belloni if (IS_ERR(rv3032->rtc)) 9382eeaa532SAlexandre Belloni return PTR_ERR(rv3032->rtc); 9392eeaa532SAlexandre Belloni 9402eeaa532SAlexandre Belloni if (client->irq > 0) { 9412eeaa532SAlexandre Belloni ret = devm_request_threaded_irq(&client->dev, client->irq, 9422eeaa532SAlexandre Belloni NULL, rv3032_handle_irq, 9432eeaa532SAlexandre Belloni IRQF_TRIGGER_LOW | IRQF_ONESHOT, 9442eeaa532SAlexandre Belloni "rv3032", rv3032); 9452eeaa532SAlexandre Belloni if (ret) { 9462eeaa532SAlexandre Belloni dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); 9472eeaa532SAlexandre Belloni client->irq = 0; 9482eeaa532SAlexandre Belloni } 9492eeaa532SAlexandre Belloni } 95019588d50SAlexandre Belloni if (!client->irq) 95119588d50SAlexandre Belloni clear_bit(RTC_FEATURE_ALARM, rv3032->rtc->features); 9522eeaa532SAlexandre Belloni 9532eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1, 9542eeaa532SAlexandre Belloni RV3032_CTRL1_WADA, RV3032_CTRL1_WADA); 9552eeaa532SAlexandre Belloni if (ret) 9562eeaa532SAlexandre Belloni return ret; 9572eeaa532SAlexandre Belloni 9582eeaa532SAlexandre Belloni rv3032_trickle_charger_setup(&client->dev, rv3032); 9592eeaa532SAlexandre Belloni 960*6084eac3SAlexandre Belloni set_bit(RTC_FEATURE_BACKUP_SWITCH_MODE, rv3032->rtc->features); 961*6084eac3SAlexandre Belloni 9622eeaa532SAlexandre Belloni rv3032->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 9632eeaa532SAlexandre Belloni rv3032->rtc->range_max = RTC_TIMESTAMP_END_2099; 9642eeaa532SAlexandre Belloni rv3032->rtc->ops = &rv3032_rtc_ops; 965fdcfd854SBartosz Golaszewski ret = devm_rtc_register_device(rv3032->rtc); 9662eeaa532SAlexandre Belloni if (ret) 9672eeaa532SAlexandre Belloni return ret; 9682eeaa532SAlexandre Belloni 969767fbb71SAlexandre Belloni nvmem_cfg.priv = rv3032->regmap; 9703a905c2dSBartosz Golaszewski devm_rtc_nvmem_register(rv3032->rtc, &nvmem_cfg); 9712eeaa532SAlexandre Belloni eeprom_cfg.priv = rv3032; 9723a905c2dSBartosz Golaszewski devm_rtc_nvmem_register(rv3032->rtc, &eeprom_cfg); 9732eeaa532SAlexandre Belloni 9742eeaa532SAlexandre Belloni rv3032->rtc->max_user_freq = 1; 9752eeaa532SAlexandre Belloni 9762eeaa532SAlexandre Belloni #ifdef CONFIG_COMMON_CLK 9772eeaa532SAlexandre Belloni rv3032_clkout_register_clk(rv3032, client); 9782eeaa532SAlexandre Belloni #endif 9792eeaa532SAlexandre Belloni 9802eeaa532SAlexandre Belloni rv3032_hwmon_register(&client->dev); 9812eeaa532SAlexandre Belloni 9822eeaa532SAlexandre Belloni return 0; 9832eeaa532SAlexandre Belloni } 9842eeaa532SAlexandre Belloni 98594428ac9SAlexandre Belloni static const __maybe_unused struct of_device_id rv3032_of_match[] = { 9862eeaa532SAlexandre Belloni { .compatible = "microcrystal,rv3032", }, 9872eeaa532SAlexandre Belloni { } 9882eeaa532SAlexandre Belloni }; 9892eeaa532SAlexandre Belloni MODULE_DEVICE_TABLE(of, rv3032_of_match); 9902eeaa532SAlexandre Belloni 9912eeaa532SAlexandre Belloni static struct i2c_driver rv3032_driver = { 9922eeaa532SAlexandre Belloni .driver = { 9932eeaa532SAlexandre Belloni .name = "rtc-rv3032", 9942eeaa532SAlexandre Belloni .of_match_table = of_match_ptr(rv3032_of_match), 9952eeaa532SAlexandre Belloni }, 9962eeaa532SAlexandre Belloni .probe_new = rv3032_probe, 9972eeaa532SAlexandre Belloni }; 9982eeaa532SAlexandre Belloni module_i2c_driver(rv3032_driver); 9992eeaa532SAlexandre Belloni 10002eeaa532SAlexandre Belloni MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>"); 10012eeaa532SAlexandre Belloni MODULE_DESCRIPTION("Micro Crystal RV3032 RTC driver"); 10022eeaa532SAlexandre Belloni MODULE_LICENSE("GPL v2"); 1003