1182ae2bbSAlexandre Belloni // SPDX-License-Identifier: GPL-2.0 21e3929efSAlexandre Belloni /* 31e3929efSAlexandre Belloni * RTC driver for the Micro Crystal RV8803 41e3929efSAlexandre Belloni * 51e3929efSAlexandre Belloni * Copyright (C) 2015 Micro Crystal SA 67d1e5bfeSAlexandre Belloni * Alexandre Belloni <alexandre.belloni@bootlin.com> 71e3929efSAlexandre Belloni * 81e3929efSAlexandre Belloni */ 91e3929efSAlexandre Belloni 101e3929efSAlexandre Belloni #include <linux/bcd.h> 111e3929efSAlexandre Belloni #include <linux/bitops.h> 12c27fee16SAhmad Fatoum #include <linux/bitfield.h> 13a1e98e09SBenoît Thébaudeau #include <linux/log2.h> 141e3929efSAlexandre Belloni #include <linux/i2c.h> 151e3929efSAlexandre Belloni #include <linux/interrupt.h> 161e3929efSAlexandre Belloni #include <linux/kernel.h> 171e3929efSAlexandre Belloni #include <linux/module.h> 18740ad8f4SJavier Martinez Canillas #include <linux/of_device.h> 191e3929efSAlexandre Belloni #include <linux/rtc.h> 201e3929efSAlexandre Belloni 21d522649eSBenoît Thébaudeau #define RV8803_I2C_TRY_COUNT 4 22d522649eSBenoît Thébaudeau 231e3929efSAlexandre Belloni #define RV8803_SEC 0x00 241e3929efSAlexandre Belloni #define RV8803_MIN 0x01 251e3929efSAlexandre Belloni #define RV8803_HOUR 0x02 261e3929efSAlexandre Belloni #define RV8803_WEEK 0x03 271e3929efSAlexandre Belloni #define RV8803_DAY 0x04 281e3929efSAlexandre Belloni #define RV8803_MONTH 0x05 291e3929efSAlexandre Belloni #define RV8803_YEAR 0x06 301e3929efSAlexandre Belloni #define RV8803_RAM 0x07 311e3929efSAlexandre Belloni #define RV8803_ALARM_MIN 0x08 321e3929efSAlexandre Belloni #define RV8803_ALARM_HOUR 0x09 331e3929efSAlexandre Belloni #define RV8803_ALARM_WEEK_OR_DAY 0x0A 341e3929efSAlexandre Belloni #define RV8803_EXT 0x0D 351e3929efSAlexandre Belloni #define RV8803_FLAG 0x0E 361e3929efSAlexandre Belloni #define RV8803_CTRL 0x0F 37c27fee16SAhmad Fatoum #define RV8803_OSC_OFFSET 0x2C 381e3929efSAlexandre Belloni 391e3929efSAlexandre Belloni #define RV8803_EXT_WADA BIT(6) 401e3929efSAlexandre Belloni 411e3929efSAlexandre Belloni #define RV8803_FLAG_V1F BIT(0) 421e3929efSAlexandre Belloni #define RV8803_FLAG_V2F BIT(1) 431e3929efSAlexandre Belloni #define RV8803_FLAG_AF BIT(3) 441e3929efSAlexandre Belloni #define RV8803_FLAG_TF BIT(4) 451e3929efSAlexandre Belloni #define RV8803_FLAG_UF BIT(5) 461e3929efSAlexandre Belloni 471e3929efSAlexandre Belloni #define RV8803_CTRL_RESET BIT(0) 481e3929efSAlexandre Belloni 491e3929efSAlexandre Belloni #define RV8803_CTRL_EIE BIT(2) 501e3929efSAlexandre Belloni #define RV8803_CTRL_AIE BIT(3) 511e3929efSAlexandre Belloni #define RV8803_CTRL_TIE BIT(4) 521e3929efSAlexandre Belloni #define RV8803_CTRL_UIE BIT(5) 531e3929efSAlexandre Belloni 54c27fee16SAhmad Fatoum #define RX8803_CTRL_CSEL GENMASK(7, 6) 55c27fee16SAhmad Fatoum 561cd71376SOleksij Rempel #define RX8900_BACKUP_CTRL 0x18 571cd71376SOleksij Rempel #define RX8900_FLAG_SWOFF BIT(2) 581cd71376SOleksij Rempel #define RX8900_FLAG_VDETOFF BIT(3) 591cd71376SOleksij Rempel 601cd71376SOleksij Rempel enum rv8803_type { 611cd71376SOleksij Rempel rv_8803, 62c27fee16SAhmad Fatoum rx_8803, 635c0189a8SFabio Estevam rx_8804, 641cd71376SOleksij Rempel rx_8900 651cd71376SOleksij Rempel }; 661cd71376SOleksij Rempel 671e3929efSAlexandre Belloni struct rv8803_data { 681e3929efSAlexandre Belloni struct i2c_client *client; 691e3929efSAlexandre Belloni struct rtc_device *rtc; 709d1fa4c3SOleksij Rempel struct mutex flags_lock; 711e3929efSAlexandre Belloni u8 ctrl; 728c798e1eSAhmad Fatoum u8 backup; 731cd71376SOleksij Rempel enum rv8803_type type; 741e3929efSAlexandre Belloni }; 751e3929efSAlexandre Belloni 76d522649eSBenoît Thébaudeau static int rv8803_read_reg(const struct i2c_client *client, u8 reg) 77d522649eSBenoît Thébaudeau { 78d522649eSBenoît Thébaudeau int try = RV8803_I2C_TRY_COUNT; 79d522649eSBenoît Thébaudeau s32 ret; 80d522649eSBenoît Thébaudeau 81d522649eSBenoît Thébaudeau /* 82d522649eSBenoît Thébaudeau * There is a 61µs window during which the RTC does not acknowledge I2C 83d522649eSBenoît Thébaudeau * transfers. In that case, ensure that there are multiple attempts. 84d522649eSBenoît Thébaudeau */ 85d522649eSBenoît Thébaudeau do 86d522649eSBenoît Thébaudeau ret = i2c_smbus_read_byte_data(client, reg); 87d522649eSBenoît Thébaudeau while ((ret == -ENXIO || ret == -EIO) && --try); 88d522649eSBenoît Thébaudeau if (ret < 0) 89d522649eSBenoît Thébaudeau dev_err(&client->dev, "Unable to read register 0x%02x\n", reg); 90d522649eSBenoît Thébaudeau 91d522649eSBenoît Thébaudeau return ret; 92d522649eSBenoît Thébaudeau } 93d522649eSBenoît Thébaudeau 94d522649eSBenoît Thébaudeau static int rv8803_read_regs(const struct i2c_client *client, 95d522649eSBenoît Thébaudeau u8 reg, u8 count, u8 *values) 96d522649eSBenoît Thébaudeau { 97d522649eSBenoît Thébaudeau int try = RV8803_I2C_TRY_COUNT; 98d522649eSBenoît Thébaudeau s32 ret; 99d522649eSBenoît Thébaudeau 100d522649eSBenoît Thébaudeau do 101d522649eSBenoît Thébaudeau ret = i2c_smbus_read_i2c_block_data(client, reg, count, values); 102d522649eSBenoît Thébaudeau while ((ret == -ENXIO || ret == -EIO) && --try); 103d522649eSBenoît Thébaudeau if (ret != count) { 104d522649eSBenoît Thébaudeau dev_err(&client->dev, 105d522649eSBenoît Thébaudeau "Unable to read registers 0x%02x..0x%02x\n", 106d522649eSBenoît Thébaudeau reg, reg + count - 1); 107d522649eSBenoît Thébaudeau return ret < 0 ? ret : -EIO; 108d522649eSBenoît Thébaudeau } 109d522649eSBenoît Thébaudeau 110d522649eSBenoît Thébaudeau return 0; 111d522649eSBenoît Thébaudeau } 112d522649eSBenoît Thébaudeau 113d522649eSBenoît Thébaudeau static int rv8803_write_reg(const struct i2c_client *client, u8 reg, u8 value) 114d522649eSBenoît Thébaudeau { 115d522649eSBenoît Thébaudeau int try = RV8803_I2C_TRY_COUNT; 116d522649eSBenoît Thébaudeau s32 ret; 117d522649eSBenoît Thébaudeau 118d522649eSBenoît Thébaudeau do 119d522649eSBenoît Thébaudeau ret = i2c_smbus_write_byte_data(client, reg, value); 120d522649eSBenoît Thébaudeau while ((ret == -ENXIO || ret == -EIO) && --try); 121d522649eSBenoît Thébaudeau if (ret) 122d522649eSBenoît Thébaudeau dev_err(&client->dev, "Unable to write register 0x%02x\n", reg); 123d522649eSBenoît Thébaudeau 124d522649eSBenoît Thébaudeau return ret; 125d522649eSBenoît Thébaudeau } 126d522649eSBenoît Thébaudeau 127d522649eSBenoît Thébaudeau static int rv8803_write_regs(const struct i2c_client *client, 128d522649eSBenoît Thébaudeau u8 reg, u8 count, const u8 *values) 129d522649eSBenoît Thébaudeau { 130d522649eSBenoît Thébaudeau int try = RV8803_I2C_TRY_COUNT; 131d522649eSBenoît Thébaudeau s32 ret; 132d522649eSBenoît Thébaudeau 133d522649eSBenoît Thébaudeau do 134d522649eSBenoît Thébaudeau ret = i2c_smbus_write_i2c_block_data(client, reg, count, 135d522649eSBenoît Thébaudeau values); 136d522649eSBenoît Thébaudeau while ((ret == -ENXIO || ret == -EIO) && --try); 137d522649eSBenoît Thébaudeau if (ret) 138d522649eSBenoît Thébaudeau dev_err(&client->dev, 139d522649eSBenoît Thébaudeau "Unable to write registers 0x%02x..0x%02x\n", 140d522649eSBenoît Thébaudeau reg, reg + count - 1); 141d522649eSBenoît Thébaudeau 142d522649eSBenoît Thébaudeau return ret; 143d522649eSBenoît Thébaudeau } 144d522649eSBenoît Thébaudeau 145c27fee16SAhmad Fatoum static int rv8803_regs_init(struct rv8803_data *rv8803) 146c27fee16SAhmad Fatoum { 147c27fee16SAhmad Fatoum int ret; 148c27fee16SAhmad Fatoum 149c27fee16SAhmad Fatoum ret = rv8803_write_reg(rv8803->client, RV8803_OSC_OFFSET, 0x00); 150c27fee16SAhmad Fatoum if (ret) 151c27fee16SAhmad Fatoum return ret; 152c27fee16SAhmad Fatoum 153c27fee16SAhmad Fatoum ret = rv8803_write_reg(rv8803->client, RV8803_CTRL, 154c27fee16SAhmad Fatoum FIELD_PREP(RX8803_CTRL_CSEL, 1)); /* 2s */ 155c27fee16SAhmad Fatoum if (ret) 156c27fee16SAhmad Fatoum return ret; 157c27fee16SAhmad Fatoum 158c27fee16SAhmad Fatoum ret = rv8803_write_regs(rv8803->client, RV8803_ALARM_MIN, 3, 159c27fee16SAhmad Fatoum (u8[]){ 0, 0, 0 }); 160c27fee16SAhmad Fatoum if (ret) 161c27fee16SAhmad Fatoum return ret; 162c27fee16SAhmad Fatoum 163c27fee16SAhmad Fatoum return rv8803_write_reg(rv8803->client, RV8803_RAM, 0x00); 164c27fee16SAhmad Fatoum } 165c27fee16SAhmad Fatoum 166f8176e0bSAhmad Fatoum static int rv8803_regs_configure(struct rv8803_data *rv8803); 167f8176e0bSAhmad Fatoum 168f8176e0bSAhmad Fatoum static int rv8803_regs_reset(struct rv8803_data *rv8803) 169f8176e0bSAhmad Fatoum { 170c27fee16SAhmad Fatoum /* 171c27fee16SAhmad Fatoum * The RV-8803 resets all registers to POR defaults after voltage-loss, 172c27fee16SAhmad Fatoum * the Epson RTCs don't, so we manually reset the remainder here. 173c27fee16SAhmad Fatoum */ 174c27fee16SAhmad Fatoum if (rv8803->type == rx_8803 || rv8803->type == rx_8900) { 175c27fee16SAhmad Fatoum int ret = rv8803_regs_init(rv8803); 176c27fee16SAhmad Fatoum if (ret) 177c27fee16SAhmad Fatoum return ret; 178c27fee16SAhmad Fatoum } 179c27fee16SAhmad Fatoum 180f8176e0bSAhmad Fatoum return rv8803_regs_configure(rv8803); 181f8176e0bSAhmad Fatoum } 182f8176e0bSAhmad Fatoum 1831e3929efSAlexandre Belloni static irqreturn_t rv8803_handle_irq(int irq, void *dev_id) 1841e3929efSAlexandre Belloni { 1851e3929efSAlexandre Belloni struct i2c_client *client = dev_id; 1861e3929efSAlexandre Belloni struct rv8803_data *rv8803 = i2c_get_clientdata(client); 1871e3929efSAlexandre Belloni unsigned long events = 0; 188d522649eSBenoît Thébaudeau int flags; 1891e3929efSAlexandre Belloni 1909d1fa4c3SOleksij Rempel mutex_lock(&rv8803->flags_lock); 1911e3929efSAlexandre Belloni 192d522649eSBenoît Thébaudeau flags = rv8803_read_reg(client, RV8803_FLAG); 1931e3929efSAlexandre Belloni if (flags <= 0) { 1949d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 1951e3929efSAlexandre Belloni return IRQ_NONE; 1961e3929efSAlexandre Belloni } 1971e3929efSAlexandre Belloni 1981e3929efSAlexandre Belloni if (flags & RV8803_FLAG_V1F) 1991e3929efSAlexandre Belloni dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n"); 2001e3929efSAlexandre Belloni 2011e3929efSAlexandre Belloni if (flags & RV8803_FLAG_V2F) 2021e3929efSAlexandre Belloni dev_warn(&client->dev, "Voltage low, data loss detected.\n"); 2031e3929efSAlexandre Belloni 2041e3929efSAlexandre Belloni if (flags & RV8803_FLAG_TF) { 2051e3929efSAlexandre Belloni flags &= ~RV8803_FLAG_TF; 2061e3929efSAlexandre Belloni rv8803->ctrl &= ~RV8803_CTRL_TIE; 2071e3929efSAlexandre Belloni events |= RTC_PF; 2081e3929efSAlexandre Belloni } 2091e3929efSAlexandre Belloni 2101e3929efSAlexandre Belloni if (flags & RV8803_FLAG_AF) { 2111e3929efSAlexandre Belloni flags &= ~RV8803_FLAG_AF; 2121e3929efSAlexandre Belloni rv8803->ctrl &= ~RV8803_CTRL_AIE; 2131e3929efSAlexandre Belloni events |= RTC_AF; 2141e3929efSAlexandre Belloni } 2151e3929efSAlexandre Belloni 2161e3929efSAlexandre Belloni if (flags & RV8803_FLAG_UF) { 2171e3929efSAlexandre Belloni flags &= ~RV8803_FLAG_UF; 2181e3929efSAlexandre Belloni rv8803->ctrl &= ~RV8803_CTRL_UIE; 2191e3929efSAlexandre Belloni events |= RTC_UF; 2201e3929efSAlexandre Belloni } 2211e3929efSAlexandre Belloni 2221e3929efSAlexandre Belloni if (events) { 2231e3929efSAlexandre Belloni rtc_update_irq(rv8803->rtc, 1, events); 224d522649eSBenoît Thébaudeau rv8803_write_reg(client, RV8803_FLAG, flags); 225d522649eSBenoît Thébaudeau rv8803_write_reg(rv8803->client, RV8803_CTRL, rv8803->ctrl); 2261e3929efSAlexandre Belloni } 2271e3929efSAlexandre Belloni 2289d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 2291e3929efSAlexandre Belloni 2301e3929efSAlexandre Belloni return IRQ_HANDLED; 2311e3929efSAlexandre Belloni } 2321e3929efSAlexandre Belloni 2331e3929efSAlexandre Belloni static int rv8803_get_time(struct device *dev, struct rtc_time *tm) 2341e3929efSAlexandre Belloni { 2351e3929efSAlexandre Belloni struct rv8803_data *rv8803 = dev_get_drvdata(dev); 2361e3929efSAlexandre Belloni u8 date1[7]; 2371e3929efSAlexandre Belloni u8 date2[7]; 2381e3929efSAlexandre Belloni u8 *date = date1; 2391e3929efSAlexandre Belloni int ret, flags; 2401e3929efSAlexandre Belloni 241d522649eSBenoît Thébaudeau flags = rv8803_read_reg(rv8803->client, RV8803_FLAG); 2421e3929efSAlexandre Belloni if (flags < 0) 2431e3929efSAlexandre Belloni return flags; 2441e3929efSAlexandre Belloni 2451e3929efSAlexandre Belloni if (flags & RV8803_FLAG_V2F) { 2461e3929efSAlexandre Belloni dev_warn(dev, "Voltage low, data is invalid.\n"); 2471e3929efSAlexandre Belloni return -EINVAL; 2481e3929efSAlexandre Belloni } 2491e3929efSAlexandre Belloni 250d522649eSBenoît Thébaudeau ret = rv8803_read_regs(rv8803->client, RV8803_SEC, 7, date); 251d522649eSBenoît Thébaudeau if (ret) 252d522649eSBenoît Thébaudeau return ret; 2531e3929efSAlexandre Belloni 2541e3929efSAlexandre Belloni if ((date1[RV8803_SEC] & 0x7f) == bin2bcd(59)) { 255d522649eSBenoît Thébaudeau ret = rv8803_read_regs(rv8803->client, RV8803_SEC, 7, date2); 256d522649eSBenoît Thébaudeau if (ret) 257d522649eSBenoît Thébaudeau return ret; 2581e3929efSAlexandre Belloni 2591e3929efSAlexandre Belloni if ((date2[RV8803_SEC] & 0x7f) != bin2bcd(59)) 2601e3929efSAlexandre Belloni date = date2; 2611e3929efSAlexandre Belloni } 2621e3929efSAlexandre Belloni 2631e3929efSAlexandre Belloni tm->tm_sec = bcd2bin(date[RV8803_SEC] & 0x7f); 2641e3929efSAlexandre Belloni tm->tm_min = bcd2bin(date[RV8803_MIN] & 0x7f); 2651e3929efSAlexandre Belloni tm->tm_hour = bcd2bin(date[RV8803_HOUR] & 0x3f); 266a1e98e09SBenoît Thébaudeau tm->tm_wday = ilog2(date[RV8803_WEEK] & 0x7f); 2671e3929efSAlexandre Belloni tm->tm_mday = bcd2bin(date[RV8803_DAY] & 0x3f); 2681e3929efSAlexandre Belloni tm->tm_mon = bcd2bin(date[RV8803_MONTH] & 0x1f) - 1; 2691e3929efSAlexandre Belloni tm->tm_year = bcd2bin(date[RV8803_YEAR]) + 100; 2701e3929efSAlexandre Belloni 27196acb25cSBenoît Thébaudeau return 0; 2721e3929efSAlexandre Belloni } 2731e3929efSAlexandre Belloni 2741e3929efSAlexandre Belloni static int rv8803_set_time(struct device *dev, struct rtc_time *tm) 2751e3929efSAlexandre Belloni { 2761e3929efSAlexandre Belloni struct rv8803_data *rv8803 = dev_get_drvdata(dev); 2771e3929efSAlexandre Belloni u8 date[7]; 278d3700b6bSBenoît Thébaudeau int ctrl, flags, ret; 2791e3929efSAlexandre Belloni 280d3700b6bSBenoît Thébaudeau ctrl = rv8803_read_reg(rv8803->client, RV8803_CTRL); 281d3700b6bSBenoît Thébaudeau if (ctrl < 0) 282d3700b6bSBenoît Thébaudeau return ctrl; 283d3700b6bSBenoît Thébaudeau 284d3700b6bSBenoît Thébaudeau /* Stop the clock */ 285d3700b6bSBenoît Thébaudeau ret = rv8803_write_reg(rv8803->client, RV8803_CTRL, 286d3700b6bSBenoît Thébaudeau ctrl | RV8803_CTRL_RESET); 287d3700b6bSBenoît Thébaudeau if (ret) 288d3700b6bSBenoît Thébaudeau return ret; 289d3700b6bSBenoît Thébaudeau 2901e3929efSAlexandre Belloni date[RV8803_SEC] = bin2bcd(tm->tm_sec); 2911e3929efSAlexandre Belloni date[RV8803_MIN] = bin2bcd(tm->tm_min); 2921e3929efSAlexandre Belloni date[RV8803_HOUR] = bin2bcd(tm->tm_hour); 2931e3929efSAlexandre Belloni date[RV8803_WEEK] = 1 << (tm->tm_wday); 2941e3929efSAlexandre Belloni date[RV8803_DAY] = bin2bcd(tm->tm_mday); 2951e3929efSAlexandre Belloni date[RV8803_MONTH] = bin2bcd(tm->tm_mon + 1); 2961e3929efSAlexandre Belloni date[RV8803_YEAR] = bin2bcd(tm->tm_year - 100); 2971e3929efSAlexandre Belloni 298d522649eSBenoît Thébaudeau ret = rv8803_write_regs(rv8803->client, RV8803_SEC, 7, date); 299d522649eSBenoît Thébaudeau if (ret) 3001e3929efSAlexandre Belloni return ret; 3011e3929efSAlexandre Belloni 302d3700b6bSBenoît Thébaudeau /* Restart the clock */ 303d3700b6bSBenoît Thébaudeau ret = rv8803_write_reg(rv8803->client, RV8803_CTRL, 304d3700b6bSBenoît Thébaudeau ctrl & ~RV8803_CTRL_RESET); 305d3700b6bSBenoît Thébaudeau if (ret) 306d3700b6bSBenoît Thébaudeau return ret; 307d3700b6bSBenoît Thébaudeau 3089d1fa4c3SOleksij Rempel mutex_lock(&rv8803->flags_lock); 3091e3929efSAlexandre Belloni 310d522649eSBenoît Thébaudeau flags = rv8803_read_reg(rv8803->client, RV8803_FLAG); 3111e3929efSAlexandre Belloni if (flags < 0) { 3129d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 3131e3929efSAlexandre Belloni return flags; 3141e3929efSAlexandre Belloni } 3151e3929efSAlexandre Belloni 316f8176e0bSAhmad Fatoum if (flags & RV8803_FLAG_V2F) { 317f8176e0bSAhmad Fatoum ret = rv8803_regs_reset(rv8803); 318bb42b7e9SYang Yingliang if (ret) { 319bb42b7e9SYang Yingliang mutex_unlock(&rv8803->flags_lock); 320f8176e0bSAhmad Fatoum return ret; 321f8176e0bSAhmad Fatoum } 322bb42b7e9SYang Yingliang } 323f8176e0bSAhmad Fatoum 324d522649eSBenoît Thébaudeau ret = rv8803_write_reg(rv8803->client, RV8803_FLAG, 3256f367788SBenoît Thébaudeau flags & ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F)); 3261e3929efSAlexandre Belloni 3279d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 3281e3929efSAlexandre Belloni 3291e3929efSAlexandre Belloni return ret; 3301e3929efSAlexandre Belloni } 3311e3929efSAlexandre Belloni 3321e3929efSAlexandre Belloni static int rv8803_get_alarm(struct device *dev, struct rtc_wkalrm *alrm) 3331e3929efSAlexandre Belloni { 3341e3929efSAlexandre Belloni struct rv8803_data *rv8803 = dev_get_drvdata(dev); 3351e3929efSAlexandre Belloni struct i2c_client *client = rv8803->client; 3361e3929efSAlexandre Belloni u8 alarmvals[3]; 3371e3929efSAlexandre Belloni int flags, ret; 3381e3929efSAlexandre Belloni 339d522649eSBenoît Thébaudeau ret = rv8803_read_regs(client, RV8803_ALARM_MIN, 3, alarmvals); 340d522649eSBenoît Thébaudeau if (ret) 341d522649eSBenoît Thébaudeau return ret; 3421e3929efSAlexandre Belloni 343d522649eSBenoît Thébaudeau flags = rv8803_read_reg(client, RV8803_FLAG); 3441e3929efSAlexandre Belloni if (flags < 0) 3451e3929efSAlexandre Belloni return flags; 3461e3929efSAlexandre Belloni 3471e3929efSAlexandre Belloni alrm->time.tm_sec = 0; 3481e3929efSAlexandre Belloni alrm->time.tm_min = bcd2bin(alarmvals[0] & 0x7f); 3491e3929efSAlexandre Belloni alrm->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f); 3501e3929efSAlexandre Belloni alrm->time.tm_mday = bcd2bin(alarmvals[2] & 0x3f); 3511e3929efSAlexandre Belloni 3521e3929efSAlexandre Belloni alrm->enabled = !!(rv8803->ctrl & RV8803_CTRL_AIE); 3531e3929efSAlexandre Belloni alrm->pending = (flags & RV8803_FLAG_AF) && alrm->enabled; 3541e3929efSAlexandre Belloni 3551e3929efSAlexandre Belloni return 0; 3561e3929efSAlexandre Belloni } 3571e3929efSAlexandre Belloni 3581e3929efSAlexandre Belloni static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 3591e3929efSAlexandre Belloni { 3601e3929efSAlexandre Belloni struct i2c_client *client = to_i2c_client(dev); 3611e3929efSAlexandre Belloni struct rv8803_data *rv8803 = dev_get_drvdata(dev); 3621e3929efSAlexandre Belloni u8 alarmvals[3]; 3631e3929efSAlexandre Belloni u8 ctrl[2]; 3641e3929efSAlexandre Belloni int ret, err; 3651e3929efSAlexandre Belloni 3661e3929efSAlexandre Belloni /* The alarm has no seconds, round up to nearest minute */ 3671e3929efSAlexandre Belloni if (alrm->time.tm_sec) { 3681e3929efSAlexandre Belloni time64_t alarm_time = rtc_tm_to_time64(&alrm->time); 3691e3929efSAlexandre Belloni 3701e3929efSAlexandre Belloni alarm_time += 60 - alrm->time.tm_sec; 3711e3929efSAlexandre Belloni rtc_time64_to_tm(alarm_time, &alrm->time); 3721e3929efSAlexandre Belloni } 3731e3929efSAlexandre Belloni 3749d1fa4c3SOleksij Rempel mutex_lock(&rv8803->flags_lock); 3751e3929efSAlexandre Belloni 376d522649eSBenoît Thébaudeau ret = rv8803_read_regs(client, RV8803_FLAG, 2, ctrl); 377d522649eSBenoît Thébaudeau if (ret) { 3789d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 379d522649eSBenoît Thébaudeau return ret; 3801e3929efSAlexandre Belloni } 3811e3929efSAlexandre Belloni 3821e3929efSAlexandre Belloni alarmvals[0] = bin2bcd(alrm->time.tm_min); 3831e3929efSAlexandre Belloni alarmvals[1] = bin2bcd(alrm->time.tm_hour); 3841e3929efSAlexandre Belloni alarmvals[2] = bin2bcd(alrm->time.tm_mday); 3851e3929efSAlexandre Belloni 3861e3929efSAlexandre Belloni if (rv8803->ctrl & (RV8803_CTRL_AIE | RV8803_CTRL_UIE)) { 3871e3929efSAlexandre Belloni rv8803->ctrl &= ~(RV8803_CTRL_AIE | RV8803_CTRL_UIE); 388d522649eSBenoît Thébaudeau err = rv8803_write_reg(rv8803->client, RV8803_CTRL, 3891e3929efSAlexandre Belloni rv8803->ctrl); 3901e3929efSAlexandre Belloni if (err) { 3919d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 3921e3929efSAlexandre Belloni return err; 3931e3929efSAlexandre Belloni } 3941e3929efSAlexandre Belloni } 3951e3929efSAlexandre Belloni 39603a86cdaSDominique Martinet ctrl[0] &= ~RV8803_FLAG_AF; 39703a86cdaSDominique Martinet err = rv8803_write_reg(rv8803->client, RV8803_FLAG, ctrl[0]); 3989d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 3991e3929efSAlexandre Belloni if (err) 4001e3929efSAlexandre Belloni return err; 4011e3929efSAlexandre Belloni 402d522649eSBenoît Thébaudeau err = rv8803_write_regs(rv8803->client, RV8803_ALARM_MIN, 3, alarmvals); 4031e3929efSAlexandre Belloni if (err) 4041e3929efSAlexandre Belloni return err; 4051e3929efSAlexandre Belloni 4061e3929efSAlexandre Belloni if (alrm->enabled) { 4071e3929efSAlexandre Belloni if (rv8803->rtc->uie_rtctimer.enabled) 4081e3929efSAlexandre Belloni rv8803->ctrl |= RV8803_CTRL_UIE; 4091e3929efSAlexandre Belloni if (rv8803->rtc->aie_timer.enabled) 4101e3929efSAlexandre Belloni rv8803->ctrl |= RV8803_CTRL_AIE; 4111e3929efSAlexandre Belloni 412d522649eSBenoît Thébaudeau err = rv8803_write_reg(rv8803->client, RV8803_CTRL, 4131e3929efSAlexandre Belloni rv8803->ctrl); 4141e3929efSAlexandre Belloni if (err) 4151e3929efSAlexandre Belloni return err; 4161e3929efSAlexandre Belloni } 4171e3929efSAlexandre Belloni 4181e3929efSAlexandre Belloni return 0; 4191e3929efSAlexandre Belloni } 4201e3929efSAlexandre Belloni 4211e3929efSAlexandre Belloni static int rv8803_alarm_irq_enable(struct device *dev, unsigned int enabled) 4221e3929efSAlexandre Belloni { 4231e3929efSAlexandre Belloni struct i2c_client *client = to_i2c_client(dev); 4241e3929efSAlexandre Belloni struct rv8803_data *rv8803 = dev_get_drvdata(dev); 4251e3929efSAlexandre Belloni int ctrl, flags, err; 4261e3929efSAlexandre Belloni 4271e3929efSAlexandre Belloni ctrl = rv8803->ctrl; 4281e3929efSAlexandre Belloni 4291e3929efSAlexandre Belloni if (enabled) { 4301e3929efSAlexandre Belloni if (rv8803->rtc->uie_rtctimer.enabled) 4311e3929efSAlexandre Belloni ctrl |= RV8803_CTRL_UIE; 4321e3929efSAlexandre Belloni if (rv8803->rtc->aie_timer.enabled) 4331e3929efSAlexandre Belloni ctrl |= RV8803_CTRL_AIE; 4341e3929efSAlexandre Belloni } else { 4351e3929efSAlexandre Belloni if (!rv8803->rtc->uie_rtctimer.enabled) 4361e3929efSAlexandre Belloni ctrl &= ~RV8803_CTRL_UIE; 4371e3929efSAlexandre Belloni if (!rv8803->rtc->aie_timer.enabled) 4381e3929efSAlexandre Belloni ctrl &= ~RV8803_CTRL_AIE; 4391e3929efSAlexandre Belloni } 4401e3929efSAlexandre Belloni 4419d1fa4c3SOleksij Rempel mutex_lock(&rv8803->flags_lock); 442d522649eSBenoît Thébaudeau flags = rv8803_read_reg(client, RV8803_FLAG); 4431e3929efSAlexandre Belloni if (flags < 0) { 4449d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 4451e3929efSAlexandre Belloni return flags; 4461e3929efSAlexandre Belloni } 4471e3929efSAlexandre Belloni flags &= ~(RV8803_FLAG_AF | RV8803_FLAG_UF); 448d522649eSBenoît Thébaudeau err = rv8803_write_reg(client, RV8803_FLAG, flags); 4499d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 4501e3929efSAlexandre Belloni if (err) 4511e3929efSAlexandre Belloni return err; 4521e3929efSAlexandre Belloni 4531e3929efSAlexandre Belloni if (ctrl != rv8803->ctrl) { 4541e3929efSAlexandre Belloni rv8803->ctrl = ctrl; 455d522649eSBenoît Thébaudeau err = rv8803_write_reg(client, RV8803_CTRL, rv8803->ctrl); 4561e3929efSAlexandre Belloni if (err) 4571e3929efSAlexandre Belloni return err; 4581e3929efSAlexandre Belloni } 4591e3929efSAlexandre Belloni 4601e3929efSAlexandre Belloni return 0; 4611e3929efSAlexandre Belloni } 4621e3929efSAlexandre Belloni 4631e3929efSAlexandre Belloni static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 4641e3929efSAlexandre Belloni { 4651e3929efSAlexandre Belloni struct i2c_client *client = to_i2c_client(dev); 4661e3929efSAlexandre Belloni struct rv8803_data *rv8803 = dev_get_drvdata(dev); 467bcd17c50SAlexandre Belloni unsigned int vl = 0; 4681e3929efSAlexandre Belloni int flags, ret = 0; 4691e3929efSAlexandre Belloni 4701e3929efSAlexandre Belloni switch (cmd) { 4711e3929efSAlexandre Belloni case RTC_VL_READ: 472d522649eSBenoît Thébaudeau flags = rv8803_read_reg(client, RV8803_FLAG); 4731e3929efSAlexandre Belloni if (flags < 0) 4741e3929efSAlexandre Belloni return flags; 4751e3929efSAlexandre Belloni 476bcd17c50SAlexandre Belloni if (flags & RV8803_FLAG_V1F) { 4771e3929efSAlexandre Belloni dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n"); 478bcd17c50SAlexandre Belloni vl = RTC_VL_ACCURACY_LOW; 479bcd17c50SAlexandre Belloni } 4801e3929efSAlexandre Belloni 4811e3929efSAlexandre Belloni if (flags & RV8803_FLAG_V2F) 482bcd17c50SAlexandre Belloni vl |= RTC_VL_DATA_INVALID; 4831e3929efSAlexandre Belloni 484bcd17c50SAlexandre Belloni return put_user(vl, (unsigned int __user *)arg); 4851e3929efSAlexandre Belloni 4861e3929efSAlexandre Belloni case RTC_VL_CLR: 4879d1fa4c3SOleksij Rempel mutex_lock(&rv8803->flags_lock); 488d522649eSBenoît Thébaudeau flags = rv8803_read_reg(client, RV8803_FLAG); 4891e3929efSAlexandre Belloni if (flags < 0) { 4909d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 4911e3929efSAlexandre Belloni return flags; 4921e3929efSAlexandre Belloni } 4931e3929efSAlexandre Belloni 4947e890a0fSAlexandre Belloni flags &= ~RV8803_FLAG_V1F; 495d522649eSBenoît Thébaudeau ret = rv8803_write_reg(client, RV8803_FLAG, flags); 4969d1fa4c3SOleksij Rempel mutex_unlock(&rv8803->flags_lock); 497d522649eSBenoît Thébaudeau if (ret) 4981e3929efSAlexandre Belloni return ret; 4991e3929efSAlexandre Belloni 5001e3929efSAlexandre Belloni return 0; 5011e3929efSAlexandre Belloni 5021e3929efSAlexandre Belloni default: 5031e3929efSAlexandre Belloni return -ENOIOCTLCMD; 5041e3929efSAlexandre Belloni } 5051e3929efSAlexandre Belloni } 5061e3929efSAlexandre Belloni 50716d70a78SAlexandre Belloni static int rv8803_nvram_write(void *priv, unsigned int offset, void *val, 50816d70a78SAlexandre Belloni size_t bytes) 5091e3929efSAlexandre Belloni { 510179b4bccSLiu Shixin return rv8803_write_reg(priv, RV8803_RAM, *(u8 *)val); 5111e3929efSAlexandre Belloni } 5121e3929efSAlexandre Belloni 51316d70a78SAlexandre Belloni static int rv8803_nvram_read(void *priv, unsigned int offset, 51416d70a78SAlexandre Belloni void *val, size_t bytes) 5151e3929efSAlexandre Belloni { 5161e3929efSAlexandre Belloni int ret; 5171e3929efSAlexandre Belloni 51816d70a78SAlexandre Belloni ret = rv8803_read_reg(priv, RV8803_RAM); 5191e3929efSAlexandre Belloni if (ret < 0) 5201e3929efSAlexandre Belloni return ret; 5211e3929efSAlexandre Belloni 52216d70a78SAlexandre Belloni *(u8 *)val = ret; 5231e3929efSAlexandre Belloni 52416d70a78SAlexandre Belloni return 0; 5251e3929efSAlexandre Belloni } 5261e3929efSAlexandre Belloni 52745909e5cSAlexandre Belloni static const struct rtc_class_ops rv8803_rtc_ops = { 5281e3929efSAlexandre Belloni .read_time = rv8803_get_time, 5291e3929efSAlexandre Belloni .set_time = rv8803_set_time, 5301e3929efSAlexandre Belloni .ioctl = rv8803_ioctl, 53145909e5cSAlexandre Belloni .read_alarm = rv8803_get_alarm, 53245909e5cSAlexandre Belloni .set_alarm = rv8803_set_alarm, 53345909e5cSAlexandre Belloni .alarm_irq_enable = rv8803_alarm_irq_enable, 5341e3929efSAlexandre Belloni }; 5351e3929efSAlexandre Belloni 5361cd71376SOleksij Rempel static int rx8900_trickle_charger_init(struct rv8803_data *rv8803) 5371cd71376SOleksij Rempel { 5381cd71376SOleksij Rempel struct i2c_client *client = rv8803->client; 5391cd71376SOleksij Rempel struct device_node *node = client->dev.of_node; 5401cd71376SOleksij Rempel int err; 5411cd71376SOleksij Rempel u8 flags; 5421cd71376SOleksij Rempel 5431cd71376SOleksij Rempel if (!node) 5441cd71376SOleksij Rempel return 0; 5451cd71376SOleksij Rempel 5461cd71376SOleksij Rempel if (rv8803->type != rx_8900) 5471cd71376SOleksij Rempel return 0; 5481cd71376SOleksij Rempel 5491cd71376SOleksij Rempel err = i2c_smbus_read_byte_data(rv8803->client, RX8900_BACKUP_CTRL); 5501cd71376SOleksij Rempel if (err < 0) 5511cd71376SOleksij Rempel return err; 5521cd71376SOleksij Rempel 5538c798e1eSAhmad Fatoum flags = (u8)err; 5548c798e1eSAhmad Fatoum flags &= ~(RX8900_FLAG_VDETOFF | RX8900_FLAG_SWOFF); 5558c798e1eSAhmad Fatoum flags |= rv8803->backup; 5561cd71376SOleksij Rempel 5571cd71376SOleksij Rempel return i2c_smbus_write_byte_data(rv8803->client, RX8900_BACKUP_CTRL, 5581cd71376SOleksij Rempel flags); 5591cd71376SOleksij Rempel } 5601cd71376SOleksij Rempel 5618c798e1eSAhmad Fatoum /* configure registers with values different than the Power-On reset defaults */ 5628c798e1eSAhmad Fatoum static int rv8803_regs_configure(struct rv8803_data *rv8803) 5638c798e1eSAhmad Fatoum { 5648c798e1eSAhmad Fatoum int err; 5658c798e1eSAhmad Fatoum 5668c798e1eSAhmad Fatoum err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA); 5678c798e1eSAhmad Fatoum if (err) 5688c798e1eSAhmad Fatoum return err; 5698c798e1eSAhmad Fatoum 5708c798e1eSAhmad Fatoum err = rx8900_trickle_charger_init(rv8803); 5718c798e1eSAhmad Fatoum if (err) { 5728c798e1eSAhmad Fatoum dev_err(&rv8803->client->dev, "failed to init charger\n"); 5738c798e1eSAhmad Fatoum return err; 5748c798e1eSAhmad Fatoum } 5758c798e1eSAhmad Fatoum 5768c798e1eSAhmad Fatoum return 0; 5778c798e1eSAhmad Fatoum } 5788c798e1eSAhmad Fatoum 579*84c2fb38SUwe Kleine-König static const struct i2c_device_id rv8803_id[] = { 580*84c2fb38SUwe Kleine-König { "rv8803", rv_8803 }, 581*84c2fb38SUwe Kleine-König { "rv8804", rx_8804 }, 582*84c2fb38SUwe Kleine-König { "rx8803", rx_8803 }, 583*84c2fb38SUwe Kleine-König { "rx8900", rx_8900 }, 584*84c2fb38SUwe Kleine-König { } 585*84c2fb38SUwe Kleine-König }; 586*84c2fb38SUwe Kleine-König MODULE_DEVICE_TABLE(i2c, rv8803_id); 587*84c2fb38SUwe Kleine-König 588*84c2fb38SUwe Kleine-König static int rv8803_probe(struct i2c_client *client) 5891e3929efSAlexandre Belloni { 5905cb17269SWolfram Sang struct i2c_adapter *adapter = client->adapter; 5911e3929efSAlexandre Belloni struct rv8803_data *rv8803; 592d522649eSBenoît Thébaudeau int err, flags; 593c07fd9deSAlexandre Belloni struct nvmem_config nvmem_cfg = { 594c07fd9deSAlexandre Belloni .name = "rv8803_nvram", 595c07fd9deSAlexandre Belloni .word_size = 1, 596c07fd9deSAlexandre Belloni .stride = 1, 597c07fd9deSAlexandre Belloni .size = 1, 598c07fd9deSAlexandre Belloni .reg_read = rv8803_nvram_read, 599c07fd9deSAlexandre Belloni .reg_write = rv8803_nvram_write, 600c07fd9deSAlexandre Belloni .priv = client, 601c07fd9deSAlexandre Belloni }; 6021e3929efSAlexandre Belloni 6031e3929efSAlexandre Belloni if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 6041e3929efSAlexandre Belloni I2C_FUNC_SMBUS_I2C_BLOCK)) { 6051e3929efSAlexandre Belloni dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n"); 6061e3929efSAlexandre Belloni return -EIO; 6071e3929efSAlexandre Belloni } 6081e3929efSAlexandre Belloni 6091e3929efSAlexandre Belloni rv8803 = devm_kzalloc(&client->dev, sizeof(struct rv8803_data), 6101e3929efSAlexandre Belloni GFP_KERNEL); 6111e3929efSAlexandre Belloni if (!rv8803) 6121e3929efSAlexandre Belloni return -ENOMEM; 6131e3929efSAlexandre Belloni 6149d1fa4c3SOleksij Rempel mutex_init(&rv8803->flags_lock); 6151e3929efSAlexandre Belloni rv8803->client = client; 616*84c2fb38SUwe Kleine-König if (client->dev.of_node) { 617740ad8f4SJavier Martinez Canillas rv8803->type = (enum rv8803_type) 618740ad8f4SJavier Martinez Canillas of_device_get_match_data(&client->dev); 619*84c2fb38SUwe Kleine-König } else { 620*84c2fb38SUwe Kleine-König const struct i2c_device_id *id = i2c_match_id(rv8803_id, client); 621*84c2fb38SUwe Kleine-König 6221cd71376SOleksij Rempel rv8803->type = id->driver_data; 623*84c2fb38SUwe Kleine-König } 6241e3929efSAlexandre Belloni i2c_set_clientdata(client, rv8803); 6251e3929efSAlexandre Belloni 626d522649eSBenoît Thébaudeau flags = rv8803_read_reg(client, RV8803_FLAG); 6271e3929efSAlexandre Belloni if (flags < 0) 6281e3929efSAlexandre Belloni return flags; 6291e3929efSAlexandre Belloni 6301e3929efSAlexandre Belloni if (flags & RV8803_FLAG_V1F) 6311e3929efSAlexandre Belloni dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n"); 6321e3929efSAlexandre Belloni 6331e3929efSAlexandre Belloni if (flags & RV8803_FLAG_V2F) 6341e3929efSAlexandre Belloni dev_warn(&client->dev, "Voltage low, data loss detected.\n"); 6351e3929efSAlexandre Belloni 6361e3929efSAlexandre Belloni if (flags & RV8803_FLAG_AF) 6371e3929efSAlexandre Belloni dev_warn(&client->dev, "An alarm maybe have been missed.\n"); 6381e3929efSAlexandre Belloni 6397133eca1SAlexandre Belloni rv8803->rtc = devm_rtc_allocate_device(&client->dev); 64044c638ceSAlexandre Belloni if (IS_ERR(rv8803->rtc)) 6417133eca1SAlexandre Belloni return PTR_ERR(rv8803->rtc); 6427133eca1SAlexandre Belloni 6431e3929efSAlexandre Belloni if (client->irq > 0) { 6441e3929efSAlexandre Belloni err = devm_request_threaded_irq(&client->dev, client->irq, 6451e3929efSAlexandre Belloni NULL, rv8803_handle_irq, 6461e3929efSAlexandre Belloni IRQF_TRIGGER_LOW | IRQF_ONESHOT, 6471e3929efSAlexandre Belloni "rv8803", client); 6481e3929efSAlexandre Belloni if (err) { 6491e3929efSAlexandre Belloni dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); 6501e3929efSAlexandre Belloni client->irq = 0; 6511e3929efSAlexandre Belloni } 6521e3929efSAlexandre Belloni } 65345909e5cSAlexandre Belloni if (!client->irq) 65445909e5cSAlexandre Belloni clear_bit(RTC_FEATURE_ALARM, rv8803->rtc->features); 6551e3929efSAlexandre Belloni 6568c798e1eSAhmad Fatoum if (of_property_read_bool(client->dev.of_node, "epson,vdet-disable")) 6578c798e1eSAhmad Fatoum rv8803->backup |= RX8900_FLAG_VDETOFF; 6588c798e1eSAhmad Fatoum 6598c798e1eSAhmad Fatoum if (of_property_read_bool(client->dev.of_node, "trickle-diode-disable")) 6608c798e1eSAhmad Fatoum rv8803->backup |= RX8900_FLAG_SWOFF; 6618c798e1eSAhmad Fatoum 6628c798e1eSAhmad Fatoum err = rv8803_regs_configure(rv8803); 6631e3929efSAlexandre Belloni if (err) 6641e3929efSAlexandre Belloni return err; 6651e3929efSAlexandre Belloni 666ce1ae8ebSAlexandre Belloni rv8803->rtc->ops = &rv8803_rtc_ops; 6672e17f8b9SAlexandre Belloni rv8803->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 6682e17f8b9SAlexandre Belloni rv8803->rtc->range_max = RTC_TIMESTAMP_END_2099; 669fdcfd854SBartosz Golaszewski err = devm_rtc_register_device(rv8803->rtc); 670ce1ae8ebSAlexandre Belloni if (err) 671ce1ae8ebSAlexandre Belloni return err; 672ce1ae8ebSAlexandre Belloni 6733a905c2dSBartosz Golaszewski devm_rtc_nvmem_register(rv8803->rtc, &nvmem_cfg); 674ce1ae8ebSAlexandre Belloni 6751e3929efSAlexandre Belloni rv8803->rtc->max_user_freq = 1; 6761e3929efSAlexandre Belloni 6771e3929efSAlexandre Belloni return 0; 6781e3929efSAlexandre Belloni } 6791e3929efSAlexandre Belloni 680da826321SAlexandre Belloni static const __maybe_unused struct of_device_id rv8803_of_match[] = { 681740ad8f4SJavier Martinez Canillas { 682740ad8f4SJavier Martinez Canillas .compatible = "microcrystal,rv8803", 683c856618dSAlexandre Belloni .data = (void *)rv_8803 684740ad8f4SJavier Martinez Canillas }, 685740ad8f4SJavier Martinez Canillas { 686ac771ed7SAlexandre Belloni .compatible = "epson,rx8803", 687c27fee16SAhmad Fatoum .data = (void *)rx_8803 688ac771ed7SAlexandre Belloni }, 689ac771ed7SAlexandre Belloni { 6905c0189a8SFabio Estevam .compatible = "epson,rx8804", 6915c0189a8SFabio Estevam .data = (void *)rx_8804 6925c0189a8SFabio Estevam }, 6935c0189a8SFabio Estevam { 694740ad8f4SJavier Martinez Canillas .compatible = "epson,rx8900", 695740ad8f4SJavier Martinez Canillas .data = (void *)rx_8900 696740ad8f4SJavier Martinez Canillas }, 697740ad8f4SJavier Martinez Canillas { } 698740ad8f4SJavier Martinez Canillas }; 699740ad8f4SJavier Martinez Canillas MODULE_DEVICE_TABLE(of, rv8803_of_match); 700740ad8f4SJavier Martinez Canillas 7011e3929efSAlexandre Belloni static struct i2c_driver rv8803_driver = { 7021e3929efSAlexandre Belloni .driver = { 7031e3929efSAlexandre Belloni .name = "rtc-rv8803", 704740ad8f4SJavier Martinez Canillas .of_match_table = of_match_ptr(rv8803_of_match), 7051e3929efSAlexandre Belloni }, 706*84c2fb38SUwe Kleine-König .probe_new = rv8803_probe, 7071e3929efSAlexandre Belloni .id_table = rv8803_id, 7081e3929efSAlexandre Belloni }; 7091e3929efSAlexandre Belloni module_i2c_driver(rv8803_driver); 7101e3929efSAlexandre Belloni 7117d1e5bfeSAlexandre Belloni MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>"); 7121e3929efSAlexandre Belloni MODULE_DESCRIPTION("Micro Crystal RV8803 RTC driver"); 7131e3929efSAlexandre Belloni MODULE_LICENSE("GPL v2"); 714