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; 1096084eac3SAlexandre 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 ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, 3152eeaa532SAlexandre Belloni RV3032_CTRL2_AIE | RV3032_CTRL2_UIE, 0); 3162eeaa532SAlexandre Belloni if (ret) 3172eeaa532SAlexandre Belloni return ret; 3182eeaa532SAlexandre Belloni 3192eeaa532SAlexandre Belloni alarmvals[0] = bin2bcd(alrm->time.tm_min); 3202eeaa532SAlexandre Belloni alarmvals[1] = bin2bcd(alrm->time.tm_hour); 3212eeaa532SAlexandre Belloni alarmvals[2] = bin2bcd(alrm->time.tm_mday); 3222eeaa532SAlexandre Belloni 3232eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS, 3242eeaa532SAlexandre Belloni RV3032_STATUS_AF, 0); 3252eeaa532SAlexandre Belloni if (ret) 3262eeaa532SAlexandre Belloni return ret; 3272eeaa532SAlexandre Belloni 3282eeaa532SAlexandre Belloni ret = regmap_bulk_write(rv3032->regmap, RV3032_ALARM_MIN, alarmvals, 3292eeaa532SAlexandre Belloni sizeof(alarmvals)); 3302eeaa532SAlexandre Belloni if (ret) 3312eeaa532SAlexandre Belloni return ret; 3322eeaa532SAlexandre Belloni 3332eeaa532SAlexandre Belloni if (alrm->enabled) { 3342eeaa532SAlexandre Belloni if (rv3032->rtc->uie_rtctimer.enabled) 3352eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_UIE; 3362eeaa532SAlexandre Belloni if (rv3032->rtc->aie_timer.enabled) 3372eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_AIE; 3382eeaa532SAlexandre Belloni } 3392eeaa532SAlexandre Belloni 3402eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, 3412eeaa532SAlexandre Belloni RV3032_CTRL2_UIE | RV3032_CTRL2_AIE, ctrl); 3422eeaa532SAlexandre Belloni 3432eeaa532SAlexandre Belloni return ret; 3442eeaa532SAlexandre Belloni } 3452eeaa532SAlexandre Belloni 3462eeaa532SAlexandre Belloni static int rv3032_alarm_irq_enable(struct device *dev, unsigned int enabled) 3472eeaa532SAlexandre Belloni { 3482eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 3492eeaa532SAlexandre Belloni int ctrl = 0, ret; 3502eeaa532SAlexandre Belloni 3512eeaa532SAlexandre Belloni if (enabled) { 3522eeaa532SAlexandre Belloni if (rv3032->rtc->uie_rtctimer.enabled) 3532eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_UIE; 3542eeaa532SAlexandre Belloni if (rv3032->rtc->aie_timer.enabled) 3552eeaa532SAlexandre Belloni ctrl |= RV3032_CTRL2_AIE; 3562eeaa532SAlexandre Belloni } 3572eeaa532SAlexandre Belloni 3582eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_STATUS, 3592eeaa532SAlexandre Belloni RV3032_STATUS_AF | RV3032_STATUS_UF, 0); 3602eeaa532SAlexandre Belloni if (ret) 3612eeaa532SAlexandre Belloni return ret; 3622eeaa532SAlexandre Belloni 3632eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, 3642eeaa532SAlexandre Belloni RV3032_CTRL2_UIE | RV3032_CTRL2_AIE, ctrl); 3652eeaa532SAlexandre Belloni if (ret) 3662eeaa532SAlexandre Belloni return ret; 3672eeaa532SAlexandre Belloni 3682eeaa532SAlexandre Belloni return 0; 3692eeaa532SAlexandre Belloni } 3702eeaa532SAlexandre Belloni 3712eeaa532SAlexandre Belloni static int rv3032_read_offset(struct device *dev, long *offset) 3722eeaa532SAlexandre Belloni { 3732eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 3742eeaa532SAlexandre Belloni int ret, value, steps; 3752eeaa532SAlexandre Belloni 3762eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_OFFSET, &value); 3772eeaa532SAlexandre Belloni if (ret < 0) 3782eeaa532SAlexandre Belloni return ret; 3792eeaa532SAlexandre Belloni 3802eeaa532SAlexandre Belloni steps = sign_extend32(FIELD_GET(RV3032_OFFSET_MSK, value), 5); 3812eeaa532SAlexandre Belloni 3822eeaa532SAlexandre Belloni *offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000); 3832eeaa532SAlexandre Belloni 3842eeaa532SAlexandre Belloni return 0; 3852eeaa532SAlexandre Belloni } 3862eeaa532SAlexandre Belloni 3872eeaa532SAlexandre Belloni static int rv3032_set_offset(struct device *dev, long offset) 3882eeaa532SAlexandre Belloni { 3892eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 3902eeaa532SAlexandre Belloni 3912eeaa532SAlexandre Belloni offset = clamp(offset, -7629L, 7391L) * 1000; 3922eeaa532SAlexandre Belloni offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT); 3932eeaa532SAlexandre Belloni 3942eeaa532SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_OFFSET, RV3032_OFFSET_MSK, 3952eeaa532SAlexandre Belloni FIELD_PREP(RV3032_OFFSET_MSK, offset)); 3962eeaa532SAlexandre Belloni } 3972eeaa532SAlexandre Belloni 3986084eac3SAlexandre Belloni static int rv3032_param_get(struct device *dev, struct rtc_param *param) 3996084eac3SAlexandre Belloni { 4006084eac3SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 4016084eac3SAlexandre Belloni int ret; 4026084eac3SAlexandre Belloni 4036084eac3SAlexandre Belloni switch(param->param) { 4046084eac3SAlexandre Belloni u32 value; 4056084eac3SAlexandre Belloni 4066084eac3SAlexandre Belloni case RTC_PARAM_BACKUP_SWITCH_MODE: 4076084eac3SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_PMU, &value); 4086084eac3SAlexandre Belloni if (ret < 0) 4096084eac3SAlexandre Belloni return ret; 4106084eac3SAlexandre Belloni 4116084eac3SAlexandre Belloni value = FIELD_GET(RV3032_PMU_BSM, value); 4126084eac3SAlexandre Belloni 4136084eac3SAlexandre Belloni switch(value) { 4146084eac3SAlexandre Belloni case RV3032_PMU_BSM_DSM: 4156084eac3SAlexandre Belloni param->uvalue = RTC_BSM_DIRECT; 4166084eac3SAlexandre Belloni break; 4176084eac3SAlexandre Belloni case RV3032_PMU_BSM_LSM: 4186084eac3SAlexandre Belloni param->uvalue = RTC_BSM_LEVEL; 4196084eac3SAlexandre Belloni break; 4206084eac3SAlexandre Belloni default: 4216084eac3SAlexandre Belloni param->uvalue = RTC_BSM_DISABLED; 4226084eac3SAlexandre Belloni } 4236084eac3SAlexandre Belloni 4246084eac3SAlexandre Belloni break; 4256084eac3SAlexandre Belloni 4266084eac3SAlexandre Belloni default: 4276084eac3SAlexandre Belloni return -EINVAL; 4286084eac3SAlexandre Belloni } 4296084eac3SAlexandre Belloni 4306084eac3SAlexandre Belloni return 0; 4316084eac3SAlexandre Belloni } 4326084eac3SAlexandre Belloni 4336084eac3SAlexandre Belloni static int rv3032_param_set(struct device *dev, struct rtc_param *param) 4346084eac3SAlexandre Belloni { 4356084eac3SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 4366084eac3SAlexandre Belloni 4376084eac3SAlexandre Belloni switch(param->param) { 4386084eac3SAlexandre Belloni u8 mode; 4396084eac3SAlexandre Belloni case RTC_PARAM_BACKUP_SWITCH_MODE: 4406084eac3SAlexandre Belloni if (rv3032->trickle_charger_set) 4416084eac3SAlexandre Belloni return -EINVAL; 4426084eac3SAlexandre Belloni 4436084eac3SAlexandre Belloni switch (param->uvalue) { 4446084eac3SAlexandre Belloni case RTC_BSM_DISABLED: 4456084eac3SAlexandre Belloni mode = 0; 4466084eac3SAlexandre Belloni break; 4476084eac3SAlexandre Belloni case RTC_BSM_DIRECT: 4486084eac3SAlexandre Belloni mode = RV3032_PMU_BSM_DSM; 4496084eac3SAlexandre Belloni break; 4506084eac3SAlexandre Belloni case RTC_BSM_LEVEL: 4516084eac3SAlexandre Belloni mode = RV3032_PMU_BSM_LSM; 4526084eac3SAlexandre Belloni break; 4536084eac3SAlexandre Belloni default: 4546084eac3SAlexandre Belloni return -EINVAL; 4556084eac3SAlexandre Belloni } 4566084eac3SAlexandre Belloni 4576084eac3SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_BSM, 4586084eac3SAlexandre Belloni FIELD_PREP(RV3032_PMU_BSM, mode)); 4596084eac3SAlexandre Belloni 4606084eac3SAlexandre Belloni default: 4616084eac3SAlexandre Belloni return -EINVAL; 4626084eac3SAlexandre Belloni } 4636084eac3SAlexandre Belloni 4646084eac3SAlexandre Belloni return 0; 4656084eac3SAlexandre Belloni } 4666084eac3SAlexandre Belloni 4672eeaa532SAlexandre Belloni static int rv3032_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 4682eeaa532SAlexandre Belloni { 4692eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 4702eeaa532SAlexandre Belloni int status, val = 0, ret = 0; 4712eeaa532SAlexandre Belloni 4722eeaa532SAlexandre Belloni switch (cmd) { 4732eeaa532SAlexandre Belloni case RTC_VL_READ: 4742eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status); 4752eeaa532SAlexandre Belloni if (ret < 0) 4762eeaa532SAlexandre Belloni return ret; 4772eeaa532SAlexandre Belloni 4782eeaa532SAlexandre Belloni if (status & (RV3032_STATUS_PORF | RV3032_STATUS_VLF)) 4792eeaa532SAlexandre Belloni val = RTC_VL_DATA_INVALID; 4802eeaa532SAlexandre Belloni return put_user(val, (unsigned int __user *)arg); 4812eeaa532SAlexandre Belloni 4822eeaa532SAlexandre Belloni default: 4832eeaa532SAlexandre Belloni return -ENOIOCTLCMD; 4842eeaa532SAlexandre Belloni } 4852eeaa532SAlexandre Belloni } 4862eeaa532SAlexandre Belloni 4872eeaa532SAlexandre Belloni static int rv3032_nvram_write(void *priv, unsigned int offset, void *val, size_t bytes) 4882eeaa532SAlexandre Belloni { 4892eeaa532SAlexandre Belloni return regmap_bulk_write(priv, RV3032_RAM1 + offset, val, bytes); 4902eeaa532SAlexandre Belloni } 4912eeaa532SAlexandre Belloni 4922eeaa532SAlexandre Belloni static int rv3032_nvram_read(void *priv, unsigned int offset, void *val, size_t bytes) 4932eeaa532SAlexandre Belloni { 4942eeaa532SAlexandre Belloni return regmap_bulk_read(priv, RV3032_RAM1 + offset, val, bytes); 4952eeaa532SAlexandre Belloni } 4962eeaa532SAlexandre Belloni 4972eeaa532SAlexandre Belloni static int rv3032_eeprom_write(void *priv, unsigned int offset, void *val, size_t bytes) 4982eeaa532SAlexandre Belloni { 4992eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = priv; 5002eeaa532SAlexandre Belloni u32 status, eerd; 5012eeaa532SAlexandre Belloni int i, ret; 5022eeaa532SAlexandre Belloni u8 *buf = val; 5032eeaa532SAlexandre Belloni 5042eeaa532SAlexandre Belloni ret = rv3032_enter_eerd(rv3032, &eerd); 5052eeaa532SAlexandre Belloni if (ret) 5062eeaa532SAlexandre Belloni return ret; 5072eeaa532SAlexandre Belloni 5082eeaa532SAlexandre Belloni for (i = 0; i < bytes; i++) { 5092eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_ADDR, 5102eeaa532SAlexandre Belloni RV3032_EEPROM_USER + offset + i); 5112eeaa532SAlexandre Belloni if (ret) 5122eeaa532SAlexandre Belloni goto exit_eerd; 5132eeaa532SAlexandre Belloni 5142eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_DATA, buf[i]); 5152eeaa532SAlexandre Belloni if (ret) 5162eeaa532SAlexandre Belloni goto exit_eerd; 5172eeaa532SAlexandre Belloni 5182eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, 5192eeaa532SAlexandre Belloni RV3032_EEPROM_CMD_WRITE); 5202eeaa532SAlexandre Belloni if (ret) 5212eeaa532SAlexandre Belloni goto exit_eerd; 5222eeaa532SAlexandre Belloni 5232eeaa532SAlexandre Belloni usleep_range(RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 5242eeaa532SAlexandre Belloni 5252eeaa532SAlexandre Belloni ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status, 5262eeaa532SAlexandre Belloni !(status & RV3032_TLSB_EEBUSY), 5272eeaa532SAlexandre Belloni RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 5282eeaa532SAlexandre Belloni if (ret) 5292eeaa532SAlexandre Belloni goto exit_eerd; 5302eeaa532SAlexandre Belloni } 5312eeaa532SAlexandre Belloni 5322eeaa532SAlexandre Belloni exit_eerd: 5332eeaa532SAlexandre Belloni rv3032_exit_eerd(rv3032, eerd); 5342eeaa532SAlexandre Belloni 5352eeaa532SAlexandre Belloni return ret; 5362eeaa532SAlexandre Belloni } 5372eeaa532SAlexandre Belloni 5382eeaa532SAlexandre Belloni static int rv3032_eeprom_read(void *priv, unsigned int offset, void *val, size_t bytes) 5392eeaa532SAlexandre Belloni { 5402eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = priv; 5412eeaa532SAlexandre Belloni u32 status, eerd, data; 5422eeaa532SAlexandre Belloni int i, ret; 5432eeaa532SAlexandre Belloni u8 *buf = val; 5442eeaa532SAlexandre Belloni 5452eeaa532SAlexandre Belloni ret = rv3032_enter_eerd(rv3032, &eerd); 5462eeaa532SAlexandre Belloni if (ret) 5472eeaa532SAlexandre Belloni return ret; 5482eeaa532SAlexandre Belloni 5492eeaa532SAlexandre Belloni for (i = 0; i < bytes; i++) { 5502eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_ADDR, 5512eeaa532SAlexandre Belloni RV3032_EEPROM_USER + offset + i); 5522eeaa532SAlexandre Belloni if (ret) 5532eeaa532SAlexandre Belloni goto exit_eerd; 5542eeaa532SAlexandre Belloni 5552eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, 5562eeaa532SAlexandre Belloni RV3032_EEPROM_CMD_READ); 5572eeaa532SAlexandre Belloni if (ret) 5582eeaa532SAlexandre Belloni goto exit_eerd; 5592eeaa532SAlexandre Belloni 5602eeaa532SAlexandre Belloni ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status, 5612eeaa532SAlexandre Belloni !(status & RV3032_TLSB_EEBUSY), 5622eeaa532SAlexandre Belloni RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 5632eeaa532SAlexandre Belloni if (ret) 5642eeaa532SAlexandre Belloni goto exit_eerd; 5652eeaa532SAlexandre Belloni 5662eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_EEPROM_DATA, &data); 5672eeaa532SAlexandre Belloni if (ret) 5682eeaa532SAlexandre Belloni goto exit_eerd; 5692eeaa532SAlexandre Belloni buf[i] = data; 5702eeaa532SAlexandre Belloni } 5712eeaa532SAlexandre Belloni 5722eeaa532SAlexandre Belloni exit_eerd: 5732eeaa532SAlexandre Belloni rv3032_exit_eerd(rv3032, eerd); 5742eeaa532SAlexandre Belloni 5752eeaa532SAlexandre Belloni return ret; 5762eeaa532SAlexandre Belloni } 5772eeaa532SAlexandre Belloni 5782eeaa532SAlexandre Belloni static int rv3032_trickle_charger_setup(struct device *dev, struct rv3032_data *rv3032) 5792eeaa532SAlexandre Belloni { 5802eeaa532SAlexandre Belloni u32 val, ohms, voltage; 5812eeaa532SAlexandre Belloni int i; 5822eeaa532SAlexandre Belloni 5832eeaa532SAlexandre Belloni val = FIELD_PREP(RV3032_PMU_TCM, 1) | FIELD_PREP(RV3032_PMU_BSM, RV3032_PMU_BSM_DSM); 5842eeaa532SAlexandre Belloni if (!device_property_read_u32(dev, "trickle-voltage-millivolt", &voltage)) { 5852eeaa532SAlexandre Belloni for (i = 0; i < ARRAY_SIZE(rv3032_trickle_voltages); i++) 5862eeaa532SAlexandre Belloni if (voltage == rv3032_trickle_voltages[i]) 5872eeaa532SAlexandre Belloni break; 5882eeaa532SAlexandre Belloni if (i < ARRAY_SIZE(rv3032_trickle_voltages)) 5892eeaa532SAlexandre Belloni val = FIELD_PREP(RV3032_PMU_TCM, i) | 5902eeaa532SAlexandre Belloni FIELD_PREP(RV3032_PMU_BSM, RV3032_PMU_BSM_LSM); 5912eeaa532SAlexandre Belloni } 5922eeaa532SAlexandre Belloni 5932eeaa532SAlexandre Belloni if (device_property_read_u32(dev, "trickle-resistor-ohms", &ohms)) 5942eeaa532SAlexandre Belloni return 0; 5952eeaa532SAlexandre Belloni 5962eeaa532SAlexandre Belloni for (i = 0; i < ARRAY_SIZE(rv3032_trickle_resistors); i++) 5972eeaa532SAlexandre Belloni if (ohms == rv3032_trickle_resistors[i]) 5982eeaa532SAlexandre Belloni break; 5992eeaa532SAlexandre Belloni 6002eeaa532SAlexandre Belloni if (i >= ARRAY_SIZE(rv3032_trickle_resistors)) { 6012eeaa532SAlexandre Belloni dev_warn(dev, "invalid trickle resistor value\n"); 6022eeaa532SAlexandre Belloni 6032eeaa532SAlexandre Belloni return 0; 6042eeaa532SAlexandre Belloni } 6052eeaa532SAlexandre Belloni 6066084eac3SAlexandre Belloni rv3032->trickle_charger_set = true; 6076084eac3SAlexandre Belloni 6082eeaa532SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_PMU, 6092eeaa532SAlexandre Belloni RV3032_PMU_TCR | RV3032_PMU_TCM | RV3032_PMU_BSM, 6102eeaa532SAlexandre Belloni val | FIELD_PREP(RV3032_PMU_TCR, i)); 6112eeaa532SAlexandre Belloni } 6122eeaa532SAlexandre Belloni 6132eeaa532SAlexandre Belloni #ifdef CONFIG_COMMON_CLK 6142eeaa532SAlexandre Belloni #define clkout_hw_to_rv3032(hw) container_of(hw, struct rv3032_data, clkout_hw) 6152eeaa532SAlexandre Belloni 6162eeaa532SAlexandre Belloni static int clkout_xtal_rates[] = { 6172eeaa532SAlexandre Belloni 32768, 6182eeaa532SAlexandre Belloni 1024, 6192eeaa532SAlexandre Belloni 64, 6202eeaa532SAlexandre Belloni 1, 6212eeaa532SAlexandre Belloni }; 6222eeaa532SAlexandre Belloni 6232eeaa532SAlexandre Belloni #define RV3032_HFD_STEP 8192 6242eeaa532SAlexandre Belloni 6252eeaa532SAlexandre Belloni static unsigned long rv3032_clkout_recalc_rate(struct clk_hw *hw, 6262eeaa532SAlexandre Belloni unsigned long parent_rate) 6272eeaa532SAlexandre Belloni { 6282eeaa532SAlexandre Belloni int clkout, ret; 6292eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 6302eeaa532SAlexandre Belloni 6312eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_CLKOUT2, &clkout); 6322eeaa532SAlexandre Belloni if (ret < 0) 6332eeaa532SAlexandre Belloni return 0; 6342eeaa532SAlexandre Belloni 6352eeaa532SAlexandre Belloni if (clkout & RV3032_CLKOUT2_OS) { 6362eeaa532SAlexandre Belloni unsigned long rate = FIELD_GET(RV3032_CLKOUT2_HFD_MSK, clkout) << 8; 6372eeaa532SAlexandre Belloni 6382eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_CLKOUT1, &clkout); 6392eeaa532SAlexandre Belloni if (ret < 0) 6402eeaa532SAlexandre Belloni return 0; 6412eeaa532SAlexandre Belloni 6422eeaa532SAlexandre Belloni rate += clkout + 1; 6432eeaa532SAlexandre Belloni 6442eeaa532SAlexandre Belloni return rate * RV3032_HFD_STEP; 6452eeaa532SAlexandre Belloni } 6462eeaa532SAlexandre Belloni 6472eeaa532SAlexandre Belloni return clkout_xtal_rates[FIELD_GET(RV3032_CLKOUT2_FD_MSK, clkout)]; 6482eeaa532SAlexandre Belloni } 6492eeaa532SAlexandre Belloni 6502eeaa532SAlexandre Belloni static long rv3032_clkout_round_rate(struct clk_hw *hw, unsigned long rate, 6512eeaa532SAlexandre Belloni unsigned long *prate) 6522eeaa532SAlexandre Belloni { 6532eeaa532SAlexandre Belloni int i, hfd; 6542eeaa532SAlexandre Belloni 6552eeaa532SAlexandre Belloni if (rate < RV3032_HFD_STEP) 6562eeaa532SAlexandre Belloni for (i = 0; i < ARRAY_SIZE(clkout_xtal_rates); i++) 6572eeaa532SAlexandre Belloni if (clkout_xtal_rates[i] <= rate) 6582eeaa532SAlexandre Belloni return clkout_xtal_rates[i]; 6592eeaa532SAlexandre Belloni 6602eeaa532SAlexandre Belloni hfd = DIV_ROUND_CLOSEST(rate, RV3032_HFD_STEP); 6612eeaa532SAlexandre Belloni 6622eeaa532SAlexandre Belloni return RV3032_HFD_STEP * clamp(hfd, 0, 8192); 6632eeaa532SAlexandre Belloni } 6642eeaa532SAlexandre Belloni 6652eeaa532SAlexandre Belloni static int rv3032_clkout_set_rate(struct clk_hw *hw, unsigned long rate, 6662eeaa532SAlexandre Belloni unsigned long parent_rate) 6672eeaa532SAlexandre Belloni { 6682eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 6692eeaa532SAlexandre Belloni u32 status, eerd; 6702eeaa532SAlexandre Belloni int i, hfd, ret; 6712eeaa532SAlexandre Belloni 6722eeaa532SAlexandre Belloni for (i = 0; i < ARRAY_SIZE(clkout_xtal_rates); i++) { 6732eeaa532SAlexandre Belloni if (clkout_xtal_rates[i] == rate) { 6742eeaa532SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_CLKOUT2, 0xff, 6752eeaa532SAlexandre Belloni FIELD_PREP(RV3032_CLKOUT2_FD_MSK, i)); 6762eeaa532SAlexandre Belloni } 6772eeaa532SAlexandre Belloni } 6782eeaa532SAlexandre Belloni 6792eeaa532SAlexandre Belloni hfd = DIV_ROUND_CLOSEST(rate, RV3032_HFD_STEP); 6802eeaa532SAlexandre Belloni hfd = clamp(hfd, 1, 8192) - 1; 6812eeaa532SAlexandre Belloni 6822eeaa532SAlexandre Belloni ret = rv3032_enter_eerd(rv3032, &eerd); 6832eeaa532SAlexandre Belloni if (ret) 684c3336b8aSDan Carpenter return ret; 6852eeaa532SAlexandre Belloni 6862eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_CLKOUT1, hfd & 0xff); 6872eeaa532SAlexandre Belloni if (ret) 688c3336b8aSDan Carpenter goto exit_eerd; 6892eeaa532SAlexandre Belloni 6902eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_CLKOUT2, RV3032_CLKOUT2_OS | 6912eeaa532SAlexandre Belloni FIELD_PREP(RV3032_CLKOUT2_HFD_MSK, hfd >> 8)); 6922eeaa532SAlexandre Belloni if (ret) 6932eeaa532SAlexandre Belloni goto exit_eerd; 6942eeaa532SAlexandre Belloni 6952eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_EEPROM_CMD, RV3032_EEPROM_CMD_UPDATE); 6962eeaa532SAlexandre Belloni if (ret) 6972eeaa532SAlexandre Belloni goto exit_eerd; 6982eeaa532SAlexandre Belloni 6992eeaa532SAlexandre Belloni usleep_range(46000, RV3032_EEBUSY_TIMEOUT); 7002eeaa532SAlexandre Belloni 7012eeaa532SAlexandre Belloni ret = regmap_read_poll_timeout(rv3032->regmap, RV3032_TLSB, status, 7022eeaa532SAlexandre Belloni !(status & RV3032_TLSB_EEBUSY), 7032eeaa532SAlexandre Belloni RV3032_EEBUSY_POLL, RV3032_EEBUSY_TIMEOUT); 7042eeaa532SAlexandre Belloni 7052eeaa532SAlexandre Belloni exit_eerd: 7062eeaa532SAlexandre Belloni rv3032_exit_eerd(rv3032, eerd); 7072eeaa532SAlexandre Belloni 7082eeaa532SAlexandre Belloni return ret; 7092eeaa532SAlexandre Belloni } 7102eeaa532SAlexandre Belloni 7112eeaa532SAlexandre Belloni static int rv3032_clkout_prepare(struct clk_hw *hw) 7122eeaa532SAlexandre Belloni { 7132eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 7142eeaa532SAlexandre Belloni 7152eeaa532SAlexandre Belloni return rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_NCLKE, 0); 7162eeaa532SAlexandre Belloni } 7172eeaa532SAlexandre Belloni 7182eeaa532SAlexandre Belloni static void rv3032_clkout_unprepare(struct clk_hw *hw) 7192eeaa532SAlexandre Belloni { 7202eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 7212eeaa532SAlexandre Belloni 7222eeaa532SAlexandre Belloni rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_NCLKE, RV3032_PMU_NCLKE); 7232eeaa532SAlexandre Belloni } 7242eeaa532SAlexandre Belloni 7252eeaa532SAlexandre Belloni static int rv3032_clkout_is_prepared(struct clk_hw *hw) 7262eeaa532SAlexandre Belloni { 7272eeaa532SAlexandre Belloni int val, ret; 7282eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = clkout_hw_to_rv3032(hw); 7292eeaa532SAlexandre Belloni 7302eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_PMU, &val); 7312eeaa532SAlexandre Belloni if (ret < 0) 7322eeaa532SAlexandre Belloni return ret; 7332eeaa532SAlexandre Belloni 7342eeaa532SAlexandre Belloni return !(val & RV3032_PMU_NCLKE); 7352eeaa532SAlexandre Belloni } 7362eeaa532SAlexandre Belloni 7372eeaa532SAlexandre Belloni static const struct clk_ops rv3032_clkout_ops = { 7382eeaa532SAlexandre Belloni .prepare = rv3032_clkout_prepare, 7392eeaa532SAlexandre Belloni .unprepare = rv3032_clkout_unprepare, 7402eeaa532SAlexandre Belloni .is_prepared = rv3032_clkout_is_prepared, 7412eeaa532SAlexandre Belloni .recalc_rate = rv3032_clkout_recalc_rate, 7422eeaa532SAlexandre Belloni .round_rate = rv3032_clkout_round_rate, 7432eeaa532SAlexandre Belloni .set_rate = rv3032_clkout_set_rate, 7442eeaa532SAlexandre Belloni }; 7452eeaa532SAlexandre Belloni 7462eeaa532SAlexandre Belloni static int rv3032_clkout_register_clk(struct rv3032_data *rv3032, 7472eeaa532SAlexandre Belloni struct i2c_client *client) 7482eeaa532SAlexandre Belloni { 7492eeaa532SAlexandre Belloni int ret; 7502eeaa532SAlexandre Belloni struct clk *clk; 7512eeaa532SAlexandre Belloni struct clk_init_data init; 7522eeaa532SAlexandre Belloni struct device_node *node = client->dev.of_node; 7532eeaa532SAlexandre Belloni 7542eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_TLSB, RV3032_TLSB_CLKF, 0); 7552eeaa532SAlexandre Belloni if (ret < 0) 7562eeaa532SAlexandre Belloni return ret; 7572eeaa532SAlexandre Belloni 7582eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2, RV3032_CTRL2_CLKIE, 0); 7592eeaa532SAlexandre Belloni if (ret < 0) 7602eeaa532SAlexandre Belloni return ret; 7612eeaa532SAlexandre Belloni 7622eeaa532SAlexandre Belloni ret = regmap_write(rv3032->regmap, RV3032_CLK_IRQ, 0); 7632eeaa532SAlexandre Belloni if (ret < 0) 7642eeaa532SAlexandre Belloni return ret; 7652eeaa532SAlexandre Belloni 7662eeaa532SAlexandre Belloni init.name = "rv3032-clkout"; 7672eeaa532SAlexandre Belloni init.ops = &rv3032_clkout_ops; 7682eeaa532SAlexandre Belloni init.flags = 0; 7692eeaa532SAlexandre Belloni init.parent_names = NULL; 7702eeaa532SAlexandre Belloni init.num_parents = 0; 7712eeaa532SAlexandre Belloni rv3032->clkout_hw.init = &init; 7722eeaa532SAlexandre Belloni 7732eeaa532SAlexandre Belloni of_property_read_string(node, "clock-output-names", &init.name); 7742eeaa532SAlexandre Belloni 7752eeaa532SAlexandre Belloni clk = devm_clk_register(&client->dev, &rv3032->clkout_hw); 7762eeaa532SAlexandre Belloni if (!IS_ERR(clk)) 7772eeaa532SAlexandre Belloni of_clk_add_provider(node, of_clk_src_simple_get, clk); 7782eeaa532SAlexandre Belloni 7792eeaa532SAlexandre Belloni return 0; 7802eeaa532SAlexandre Belloni } 7812eeaa532SAlexandre Belloni #endif 7822eeaa532SAlexandre Belloni 7832eeaa532SAlexandre Belloni static int rv3032_hwmon_read_temp(struct device *dev, long *mC) 7842eeaa532SAlexandre Belloni { 7852eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 7862eeaa532SAlexandre Belloni u8 buf[2]; 7872eeaa532SAlexandre Belloni int temp, prev = 0; 7882eeaa532SAlexandre Belloni int ret; 7892eeaa532SAlexandre Belloni 7902eeaa532SAlexandre Belloni ret = regmap_bulk_read(rv3032->regmap, RV3032_TLSB, buf, sizeof(buf)); 7912eeaa532SAlexandre Belloni if (ret) 7922eeaa532SAlexandre Belloni return ret; 7932eeaa532SAlexandre Belloni 7942eeaa532SAlexandre Belloni temp = sign_extend32(buf[1], 7) << 4; 7952eeaa532SAlexandre Belloni temp |= FIELD_GET(RV3032_TLSB_TEMP, buf[0]); 7962eeaa532SAlexandre Belloni 7972eeaa532SAlexandre Belloni /* No blocking or shadowing on RV3032_TLSB and RV3032_TMSB */ 7982eeaa532SAlexandre Belloni do { 7992eeaa532SAlexandre Belloni prev = temp; 8002eeaa532SAlexandre Belloni 8012eeaa532SAlexandre Belloni ret = regmap_bulk_read(rv3032->regmap, RV3032_TLSB, buf, sizeof(buf)); 8022eeaa532SAlexandre Belloni if (ret) 8032eeaa532SAlexandre Belloni return ret; 8042eeaa532SAlexandre Belloni 8052eeaa532SAlexandre Belloni temp = sign_extend32(buf[1], 7) << 4; 8062eeaa532SAlexandre Belloni temp |= FIELD_GET(RV3032_TLSB_TEMP, buf[0]); 8072eeaa532SAlexandre Belloni } while (temp != prev); 8082eeaa532SAlexandre Belloni 8092eeaa532SAlexandre Belloni *mC = (temp * 1000) / 16; 8102eeaa532SAlexandre Belloni 8112eeaa532SAlexandre Belloni return 0; 8122eeaa532SAlexandre Belloni } 8132eeaa532SAlexandre Belloni 8142eeaa532SAlexandre Belloni static umode_t rv3032_hwmon_is_visible(const void *data, enum hwmon_sensor_types type, 8152eeaa532SAlexandre Belloni u32 attr, int channel) 8162eeaa532SAlexandre Belloni { 8172eeaa532SAlexandre Belloni if (type != hwmon_temp) 8182eeaa532SAlexandre Belloni return 0; 8192eeaa532SAlexandre Belloni 8202eeaa532SAlexandre Belloni switch (attr) { 8212eeaa532SAlexandre Belloni case hwmon_temp_input: 8222eeaa532SAlexandre Belloni return 0444; 8232eeaa532SAlexandre Belloni default: 8242eeaa532SAlexandre Belloni return 0; 8252eeaa532SAlexandre Belloni } 8262eeaa532SAlexandre Belloni } 8272eeaa532SAlexandre Belloni 8282eeaa532SAlexandre Belloni static int rv3032_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 8292eeaa532SAlexandre Belloni u32 attr, int channel, long *temp) 8302eeaa532SAlexandre Belloni { 8312eeaa532SAlexandre Belloni int err; 8322eeaa532SAlexandre Belloni 8332eeaa532SAlexandre Belloni switch (attr) { 8342eeaa532SAlexandre Belloni case hwmon_temp_input: 8352eeaa532SAlexandre Belloni err = rv3032_hwmon_read_temp(dev, temp); 8362eeaa532SAlexandre Belloni break; 8372eeaa532SAlexandre Belloni default: 8382eeaa532SAlexandre Belloni err = -EOPNOTSUPP; 8392eeaa532SAlexandre Belloni break; 8402eeaa532SAlexandre Belloni } 8412eeaa532SAlexandre Belloni 8422eeaa532SAlexandre Belloni return err; 8432eeaa532SAlexandre Belloni } 8442eeaa532SAlexandre Belloni 8452eeaa532SAlexandre Belloni static const struct hwmon_channel_info *rv3032_hwmon_info[] = { 8462eeaa532SAlexandre Belloni HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), 8472eeaa532SAlexandre Belloni HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST), 8482eeaa532SAlexandre Belloni NULL 8492eeaa532SAlexandre Belloni }; 8502eeaa532SAlexandre Belloni 8512eeaa532SAlexandre Belloni static const struct hwmon_ops rv3032_hwmon_hwmon_ops = { 8522eeaa532SAlexandre Belloni .is_visible = rv3032_hwmon_is_visible, 8532eeaa532SAlexandre Belloni .read = rv3032_hwmon_read, 8542eeaa532SAlexandre Belloni }; 8552eeaa532SAlexandre Belloni 8562eeaa532SAlexandre Belloni static const struct hwmon_chip_info rv3032_hwmon_chip_info = { 8572eeaa532SAlexandre Belloni .ops = &rv3032_hwmon_hwmon_ops, 8582eeaa532SAlexandre Belloni .info = rv3032_hwmon_info, 8592eeaa532SAlexandre Belloni }; 8602eeaa532SAlexandre Belloni 8612eeaa532SAlexandre Belloni static void rv3032_hwmon_register(struct device *dev) 8622eeaa532SAlexandre Belloni { 8632eeaa532SAlexandre Belloni struct rv3032_data *rv3032 = dev_get_drvdata(dev); 8642eeaa532SAlexandre Belloni 8652eeaa532SAlexandre Belloni if (!IS_REACHABLE(CONFIG_HWMON)) 8662eeaa532SAlexandre Belloni return; 8672eeaa532SAlexandre Belloni 8682eeaa532SAlexandre Belloni devm_hwmon_device_register_with_info(dev, "rv3032", rv3032, &rv3032_hwmon_chip_info, NULL); 8692eeaa532SAlexandre Belloni } 8702eeaa532SAlexandre Belloni 87119588d50SAlexandre Belloni static const struct rtc_class_ops rv3032_rtc_ops = { 8722eeaa532SAlexandre Belloni .read_time = rv3032_get_time, 8732eeaa532SAlexandre Belloni .set_time = rv3032_set_time, 8742eeaa532SAlexandre Belloni .read_offset = rv3032_read_offset, 8752eeaa532SAlexandre Belloni .set_offset = rv3032_set_offset, 8762eeaa532SAlexandre Belloni .ioctl = rv3032_ioctl, 87719588d50SAlexandre Belloni .read_alarm = rv3032_get_alarm, 87819588d50SAlexandre Belloni .set_alarm = rv3032_set_alarm, 87919588d50SAlexandre Belloni .alarm_irq_enable = rv3032_alarm_irq_enable, 8806084eac3SAlexandre Belloni .param_get = rv3032_param_get, 8816084eac3SAlexandre Belloni .param_set = rv3032_param_set, 8822eeaa532SAlexandre Belloni }; 8832eeaa532SAlexandre Belloni 8842eeaa532SAlexandre Belloni static const struct regmap_config regmap_config = { 8852eeaa532SAlexandre Belloni .reg_bits = 8, 8862eeaa532SAlexandre Belloni .val_bits = 8, 8872eeaa532SAlexandre Belloni .max_register = 0xCA, 8882eeaa532SAlexandre Belloni }; 8892eeaa532SAlexandre Belloni 8902eeaa532SAlexandre Belloni static int rv3032_probe(struct i2c_client *client) 8912eeaa532SAlexandre Belloni { 8922eeaa532SAlexandre Belloni struct rv3032_data *rv3032; 8932eeaa532SAlexandre Belloni int ret, status; 8942eeaa532SAlexandre Belloni struct nvmem_config nvmem_cfg = { 8952eeaa532SAlexandre Belloni .name = "rv3032_nvram", 8962eeaa532SAlexandre Belloni .word_size = 1, 8972eeaa532SAlexandre Belloni .stride = 1, 8982eeaa532SAlexandre Belloni .size = 16, 8992eeaa532SAlexandre Belloni .type = NVMEM_TYPE_BATTERY_BACKED, 9002eeaa532SAlexandre Belloni .reg_read = rv3032_nvram_read, 9012eeaa532SAlexandre Belloni .reg_write = rv3032_nvram_write, 9022eeaa532SAlexandre Belloni }; 9032eeaa532SAlexandre Belloni struct nvmem_config eeprom_cfg = { 9042eeaa532SAlexandre Belloni .name = "rv3032_eeprom", 9052eeaa532SAlexandre Belloni .word_size = 1, 9062eeaa532SAlexandre Belloni .stride = 1, 9072eeaa532SAlexandre Belloni .size = 32, 9082eeaa532SAlexandre Belloni .type = NVMEM_TYPE_EEPROM, 9092eeaa532SAlexandre Belloni .reg_read = rv3032_eeprom_read, 9102eeaa532SAlexandre Belloni .reg_write = rv3032_eeprom_write, 9112eeaa532SAlexandre Belloni }; 9122eeaa532SAlexandre Belloni 9132eeaa532SAlexandre Belloni rv3032 = devm_kzalloc(&client->dev, sizeof(struct rv3032_data), 9142eeaa532SAlexandre Belloni GFP_KERNEL); 9152eeaa532SAlexandre Belloni if (!rv3032) 9162eeaa532SAlexandre Belloni return -ENOMEM; 9172eeaa532SAlexandre Belloni 9182eeaa532SAlexandre Belloni rv3032->regmap = devm_regmap_init_i2c(client, ®map_config); 9192eeaa532SAlexandre Belloni if (IS_ERR(rv3032->regmap)) 9202eeaa532SAlexandre Belloni return PTR_ERR(rv3032->regmap); 9212eeaa532SAlexandre Belloni 9222eeaa532SAlexandre Belloni i2c_set_clientdata(client, rv3032); 9232eeaa532SAlexandre Belloni 9242eeaa532SAlexandre Belloni ret = regmap_read(rv3032->regmap, RV3032_STATUS, &status); 9252eeaa532SAlexandre Belloni if (ret < 0) 9262eeaa532SAlexandre Belloni return ret; 9272eeaa532SAlexandre Belloni 9282eeaa532SAlexandre Belloni rv3032->rtc = devm_rtc_allocate_device(&client->dev); 9292eeaa532SAlexandre Belloni if (IS_ERR(rv3032->rtc)) 9302eeaa532SAlexandre Belloni return PTR_ERR(rv3032->rtc); 9312eeaa532SAlexandre Belloni 9322eeaa532SAlexandre Belloni if (client->irq > 0) { 933c4b12f89SAlexandre Belloni unsigned long irqflags = IRQF_TRIGGER_LOW; 934c4b12f89SAlexandre Belloni 935c4b12f89SAlexandre Belloni if (dev_fwnode(&client->dev)) 936c4b12f89SAlexandre Belloni irqflags = 0; 937c4b12f89SAlexandre Belloni 9382eeaa532SAlexandre Belloni ret = devm_request_threaded_irq(&client->dev, client->irq, 9392eeaa532SAlexandre Belloni NULL, rv3032_handle_irq, 940c4b12f89SAlexandre Belloni irqflags | IRQF_ONESHOT, 9412eeaa532SAlexandre Belloni "rv3032", rv3032); 9422eeaa532SAlexandre Belloni if (ret) { 9432eeaa532SAlexandre Belloni dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); 9442eeaa532SAlexandre Belloni client->irq = 0; 9452eeaa532SAlexandre Belloni } 9462eeaa532SAlexandre Belloni } 94719588d50SAlexandre Belloni if (!client->irq) 94819588d50SAlexandre Belloni clear_bit(RTC_FEATURE_ALARM, rv3032->rtc->features); 9492eeaa532SAlexandre Belloni 9502eeaa532SAlexandre Belloni ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL1, 9512eeaa532SAlexandre Belloni RV3032_CTRL1_WADA, RV3032_CTRL1_WADA); 9522eeaa532SAlexandre Belloni if (ret) 9532eeaa532SAlexandre Belloni return ret; 9542eeaa532SAlexandre Belloni 9552eeaa532SAlexandre Belloni rv3032_trickle_charger_setup(&client->dev, rv3032); 9562eeaa532SAlexandre Belloni 9576084eac3SAlexandre Belloni set_bit(RTC_FEATURE_BACKUP_SWITCH_MODE, rv3032->rtc->features); 958ac86964fSAlexandre Belloni set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rv3032->rtc->features); 9596084eac3SAlexandre Belloni 9602eeaa532SAlexandre Belloni rv3032->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 9612eeaa532SAlexandre Belloni rv3032->rtc->range_max = RTC_TIMESTAMP_END_2099; 9622eeaa532SAlexandre Belloni rv3032->rtc->ops = &rv3032_rtc_ops; 963fdcfd854SBartosz Golaszewski ret = devm_rtc_register_device(rv3032->rtc); 9642eeaa532SAlexandre Belloni if (ret) 9652eeaa532SAlexandre Belloni return ret; 9662eeaa532SAlexandre Belloni 967767fbb71SAlexandre Belloni nvmem_cfg.priv = rv3032->regmap; 9683a905c2dSBartosz Golaszewski devm_rtc_nvmem_register(rv3032->rtc, &nvmem_cfg); 9692eeaa532SAlexandre Belloni eeprom_cfg.priv = rv3032; 9703a905c2dSBartosz Golaszewski devm_rtc_nvmem_register(rv3032->rtc, &eeprom_cfg); 9712eeaa532SAlexandre Belloni 9722eeaa532SAlexandre Belloni rv3032->rtc->max_user_freq = 1; 9732eeaa532SAlexandre Belloni 9742eeaa532SAlexandre Belloni #ifdef CONFIG_COMMON_CLK 9752eeaa532SAlexandre Belloni rv3032_clkout_register_clk(rv3032, client); 9762eeaa532SAlexandre Belloni #endif 9772eeaa532SAlexandre Belloni 9782eeaa532SAlexandre Belloni rv3032_hwmon_register(&client->dev); 9792eeaa532SAlexandre Belloni 9802eeaa532SAlexandre Belloni return 0; 9812eeaa532SAlexandre Belloni } 9822eeaa532SAlexandre Belloni 983*2d433e9cSAlexandre Belloni static const struct acpi_device_id rv3032_i2c_acpi_match[] = { 984*2d433e9cSAlexandre Belloni { "MCRY3032" }, 985*2d433e9cSAlexandre Belloni { } 986*2d433e9cSAlexandre Belloni }; 987*2d433e9cSAlexandre Belloni MODULE_DEVICE_TABLE(acpi, rv3032_i2c_acpi_match); 988*2d433e9cSAlexandre Belloni 98994428ac9SAlexandre Belloni static const __maybe_unused struct of_device_id rv3032_of_match[] = { 9902eeaa532SAlexandre Belloni { .compatible = "microcrystal,rv3032", }, 9912eeaa532SAlexandre Belloni { } 9922eeaa532SAlexandre Belloni }; 9932eeaa532SAlexandre Belloni MODULE_DEVICE_TABLE(of, rv3032_of_match); 9942eeaa532SAlexandre Belloni 9952eeaa532SAlexandre Belloni static struct i2c_driver rv3032_driver = { 9962eeaa532SAlexandre Belloni .driver = { 9972eeaa532SAlexandre Belloni .name = "rtc-rv3032", 998*2d433e9cSAlexandre Belloni .acpi_match_table = rv3032_i2c_acpi_match, 9992eeaa532SAlexandre Belloni .of_match_table = of_match_ptr(rv3032_of_match), 10002eeaa532SAlexandre Belloni }, 10012eeaa532SAlexandre Belloni .probe_new = rv3032_probe, 10022eeaa532SAlexandre Belloni }; 10032eeaa532SAlexandre Belloni module_i2c_driver(rv3032_driver); 10042eeaa532SAlexandre Belloni 10052eeaa532SAlexandre Belloni MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>"); 10062eeaa532SAlexandre Belloni MODULE_DESCRIPTION("Micro Crystal RV3032 RTC driver"); 10072eeaa532SAlexandre Belloni MODULE_LICENSE("GPL v2"); 1008