diff options
| -rw-r--r-- | Documentation/devicetree/bindings/i2c/trivial-devices.txt | 1 | ||||
| -rw-r--r-- | drivers/rtc/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/rtc/rtc-ab-b5ze-s3.c | 802 |
4 files changed, 815 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index 9f41d05be3be..f9463b492f44 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt | |||
| @@ -9,6 +9,7 @@ document for it just like any other devices. | |||
| 9 | 9 | ||
| 10 | Compatible Vendor / Chip | 10 | Compatible Vendor / Chip |
| 11 | ========== ============= | 11 | ========== ============= |
| 12 | abracon,abb5zes3 AB-RTCMC-32.768kHz-B5ZE-S3: Real Time Clock/Calendar Module with I2C Interface | ||
| 12 | ad,ad7414 SMBus/I2C Digital Temperature Sensor in 6-Pin SOT with SMBus Alert and Over Temperature Pin | 13 | ad,ad7414 SMBus/I2C Digital Temperature Sensor in 6-Pin SOT with SMBus Alert and Over Temperature Pin |
| 13 | ad,adm9240 ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems | 14 | ad,adm9240 ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems |
| 14 | adi,adt7461 +/-1C TDM Extended Temp Range I.C | 15 | adi,adt7461 +/-1C TDM Extended Temp Range I.C |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index f15cddfeb897..1b19f327f35f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
| @@ -153,6 +153,17 @@ config RTC_DRV_88PM80X | |||
| 153 | This driver can also be built as a module. If so, the module | 153 | This driver can also be built as a module. If so, the module |
| 154 | will be called rtc-88pm80x. | 154 | will be called rtc-88pm80x. |
| 155 | 155 | ||
| 156 | config RTC_DRV_ABB5ZES3 | ||
| 157 | depends on I2C | ||
| 158 | select REGMAP_I2C | ||
| 159 | tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3" | ||
| 160 | help | ||
| 161 | If you say yes here you get support for the Abracon | ||
| 162 | AB-RTCMC-32.768kHz-B5ZE-S3 I2C RTC chip. | ||
| 163 | |||
| 164 | This driver can also be built as a module. If so, the module | ||
| 165 | will be called rtc-ab-b5ze-s3. | ||
| 166 | |||
| 156 | config RTC_DRV_AS3722 | 167 | config RTC_DRV_AS3722 |
| 157 | tristate "ams AS3722 RTC driver" | 168 | tristate "ams AS3722 RTC driver" |
| 158 | depends on MFD_AS3722 | 169 | depends on MFD_AS3722 |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index c8ef3e1e6ccd..855c4e364058 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
| @@ -24,6 +24,7 @@ obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o | |||
| 24 | obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o | 24 | obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o |
| 25 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o | 25 | obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o |
| 26 | obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o | 26 | obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o |
| 27 | obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o | ||
| 27 | obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o | 28 | obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o |
| 28 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | 29 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o |
| 29 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o | 30 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o |
diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c new file mode 100644 index 000000000000..bbbf06f55e17 --- /dev/null +++ b/drivers/rtc/rtc-ab-b5ze-s3.c | |||
| @@ -0,0 +1,802 @@ | |||
| 1 | /* | ||
| 2 | * rtc-ab-b5ze-s3 - Driver for Abracon AB-RTCMC-32.768Khz-B5ZE-S3 | ||
| 3 | * I2C RTC / Alarm chip | ||
| 4 | * | ||
| 5 | * Copyright (C) 2014, Arnaud EBALARD <arno@natisbad.org> | ||
| 6 | * | ||
| 7 | * Detailed datasheet of the chip is available here: | ||
| 8 | * | ||
| 9 | * http://www.abracon.com/realtimeclock/AB-RTCMC-32.768kHz-B5ZE-S3-Application-Manual.pdf | ||
| 10 | * | ||
| 11 | * This work is based on ISL12057 driver (drivers/rtc/rtc-isl12057.c). | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation; either version 2 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/mutex.h> | ||
| 26 | #include <linux/rtc.h> | ||
| 27 | #include <linux/i2c.h> | ||
| 28 | #include <linux/bcd.h> | ||
| 29 | #include <linux/of.h> | ||
| 30 | #include <linux/regmap.h> | ||
| 31 | #include <linux/interrupt.h> | ||
| 32 | |||
| 33 | #define DRV_NAME "rtc-ab-b5ze-s3" | ||
| 34 | |||
| 35 | /* Control section */ | ||
| 36 | #define ABB5ZES3_REG_CTRL1 0x00 /* Control 1 register */ | ||
| 37 | #define ABB5ZES3_REG_CTRL1_CIE BIT(0) /* Pulse interrupt enable */ | ||
| 38 | #define ABB5ZES3_REG_CTRL1_AIE BIT(1) /* Alarm interrupt enable */ | ||
| 39 | #define ABB5ZES3_REG_CTRL1_SIE BIT(2) /* Second interrupt enable */ | ||
| 40 | #define ABB5ZES3_REG_CTRL1_PM BIT(3) /* 24h/12h mode */ | ||
| 41 | #define ABB5ZES3_REG_CTRL1_SR BIT(4) /* Software reset */ | ||
| 42 | #define ABB5ZES3_REG_CTRL1_STOP BIT(5) /* RTC circuit enable */ | ||
| 43 | #define ABB5ZES3_REG_CTRL1_CAP BIT(7) | ||
| 44 | |||
| 45 | #define ABB5ZES3_REG_CTRL2 0x01 /* Control 2 register */ | ||
| 46 | #define ABB5ZES3_REG_CTRL2_CTBIE BIT(0) /* Countdown timer B int. enable */ | ||
| 47 | #define ABB5ZES3_REG_CTRL2_CTAIE BIT(1) /* Countdown timer A int. enable */ | ||
| 48 | #define ABB5ZES3_REG_CTRL2_WTAIE BIT(2) /* Watchdog timer A int. enable */ | ||
| 49 | #define ABB5ZES3_REG_CTRL2_AF BIT(3) /* Alarm interrupt status */ | ||
| 50 | #define ABB5ZES3_REG_CTRL2_SF BIT(4) /* Second interrupt status */ | ||
| 51 | #define ABB5ZES3_REG_CTRL2_CTBF BIT(5) /* Countdown timer B int. status */ | ||
| 52 | #define ABB5ZES3_REG_CTRL2_CTAF BIT(6) /* Countdown timer A int. status */ | ||
| 53 | #define ABB5ZES3_REG_CTRL2_WTAF BIT(7) /* Watchdog timer A int. status */ | ||
| 54 | |||
| 55 | #define ABB5ZES3_REG_CTRL3 0x02 /* Control 3 register */ | ||
| 56 | #define ABB5ZES3_REG_CTRL3_PM2 BIT(7) /* Power Management bit 2 */ | ||
| 57 | #define ABB5ZES3_REG_CTRL3_PM1 BIT(6) /* Power Management bit 1 */ | ||
| 58 | #define ABB5ZES3_REG_CTRL3_PM0 BIT(5) /* Power Management bit 0 */ | ||
| 59 | #define ABB5ZES3_REG_CTRL3_BSF BIT(3) /* Battery switchover int. status */ | ||
| 60 | #define ABB5ZES3_REG_CTRL3_BLF BIT(2) /* Battery low int. status */ | ||
| 61 | #define ABB5ZES3_REG_CTRL3_BSIE BIT(1) /* Battery switchover int. enable */ | ||
| 62 | #define ABB5ZES3_REG_CTRL3_BLIE BIT(0) /* Battery low int. enable */ | ||
| 63 | |||
| 64 | #define ABB5ZES3_CTRL_SEC_LEN 3 | ||
| 65 | |||
| 66 | /* RTC section */ | ||
| 67 | #define ABB5ZES3_REG_RTC_SC 0x03 /* RTC Seconds register */ | ||
| 68 | #define ABB5ZES3_REG_RTC_SC_OSC BIT(7) /* Clock integrity status */ | ||
| 69 | #define ABB5ZES3_REG_RTC_MN 0x04 /* RTC Minutes register */ | ||
| 70 | #define ABB5ZES3_REG_RTC_HR 0x05 /* RTC Hours register */ | ||
| 71 | #define ABB5ZES3_REG_RTC_HR_PM BIT(5) /* RTC Hours PM bit */ | ||
| 72 | #define ABB5ZES3_REG_RTC_DT 0x06 /* RTC Date register */ | ||
| 73 | #define ABB5ZES3_REG_RTC_DW 0x07 /* RTC Day of the week register */ | ||
| 74 | #define ABB5ZES3_REG_RTC_MO 0x08 /* RTC Month register */ | ||
| 75 | #define ABB5ZES3_REG_RTC_YR 0x09 /* RTC Year register */ | ||
| 76 | |||
| 77 | #define ABB5ZES3_RTC_SEC_LEN 7 | ||
| 78 | |||
| 79 | /* Alarm section (enable bits are all active low) */ | ||
| 80 | #define ABB5ZES3_REG_ALRM_MN 0x0A /* Alarm - minute register */ | ||
| 81 | #define ABB5ZES3_REG_ALRM_MN_AE BIT(7) /* Minute enable */ | ||
| 82 | #define ABB5ZES3_REG_ALRM_HR 0x0B /* Alarm - hours register */ | ||
| 83 | #define ABB5ZES3_REG_ALRM_HR_AE BIT(7) /* Hour enable */ | ||
| 84 | #define ABB5ZES3_REG_ALRM_DT 0x0C /* Alarm - date register */ | ||
| 85 | #define ABB5ZES3_REG_ALRM_DT_AE BIT(7) /* Date (day of the month) enable */ | ||
| 86 | #define ABB5ZES3_REG_ALRM_DW 0x0D /* Alarm - day of the week reg. */ | ||
| 87 | #define ABB5ZES3_REG_ALRM_DW_AE BIT(7) /* Day of the week enable */ | ||
| 88 | |||
| 89 | #define ABB5ZES3_ALRM_SEC_LEN 4 | ||
| 90 | |||
| 91 | /* Frequency offset section */ | ||
| 92 | #define ABB5ZES3_REG_FREQ_OF 0x0E /* Frequency offset register */ | ||
| 93 | #define ABB5ZES3_REG_FREQ_OF_MODE 0x0E /* Offset mode: 2 hours / minute */ | ||
| 94 | |||
| 95 | /* CLOCKOUT section */ | ||
| 96 | #define ABB5ZES3_REG_TIM_CLK 0x0F /* Timer & Clockout register */ | ||
| 97 | #define ABB5ZES3_REG_TIM_CLK_TAM BIT(7) /* Permanent/pulsed timer A/int. 2 */ | ||
| 98 | #define ABB5ZES3_REG_TIM_CLK_TBM BIT(6) /* Permanent/pulsed timer B */ | ||
| 99 | #define ABB5ZES3_REG_TIM_CLK_COF2 BIT(5) /* Clkout Freq bit 2 */ | ||
| 100 | #define ABB5ZES3_REG_TIM_CLK_COF1 BIT(4) /* Clkout Freq bit 1 */ | ||
| 101 | #define ABB5ZES3_REG_TIM_CLK_COF0 BIT(3) /* Clkout Freq bit 0 */ | ||
| 102 | #define ABB5ZES3_REG_TIM_CLK_TAC1 BIT(2) /* Timer A: - 01 : countdown */ | ||
| 103 | #define ABB5ZES3_REG_TIM_CLK_TAC0 BIT(1) /* - 10 : timer */ | ||
| 104 | #define ABB5ZES3_REG_TIM_CLK_TBC BIT(0) /* Timer B enable */ | ||
| 105 | |||
| 106 | /* Timer A Section */ | ||
| 107 | #define ABB5ZES3_REG_TIMA_CLK 0x10 /* Timer A clock register */ | ||
| 108 | #define ABB5ZES3_REG_TIMA_CLK_TAQ2 BIT(2) /* Freq bit 2 */ | ||
| 109 | #define ABB5ZES3_REG_TIMA_CLK_TAQ1 BIT(1) /* Freq bit 1 */ | ||
| 110 | #define ABB5ZES3_REG_TIMA_CLK_TAQ0 BIT(0) /* Freq bit 0 */ | ||
| 111 | #define ABB5ZES3_REG_TIMA 0x11 /* Timer A register */ | ||
| 112 | |||
| 113 | #define ABB5ZES3_TIMA_SEC_LEN 2 | ||
| 114 | |||
| 115 | /* Timer B Section */ | ||
| 116 | #define ABB5ZES3_REG_TIMB_CLK 0x12 /* Timer B clock register */ | ||
| 117 | #define ABB5ZES3_REG_TIMB_CLK_TBW2 BIT(6) | ||
| 118 | #define ABB5ZES3_REG_TIMB_CLK_TBW1 BIT(5) | ||
| 119 | #define ABB5ZES3_REG_TIMB_CLK_TBW0 BIT(4) | ||
| 120 | #define ABB5ZES3_REG_TIMB_CLK_TAQ2 BIT(2) | ||
| 121 | #define ABB5ZES3_REG_TIMB_CLK_TAQ1 BIT(1) | ||
| 122 | #define ABB5ZES3_REG_TIMB_CLK_TAQ0 BIT(0) | ||
| 123 | #define ABB5ZES3_REG_TIMB 0x13 /* Timer B register */ | ||
| 124 | #define ABB5ZES3_TIMB_SEC_LEN 2 | ||
| 125 | |||
| 126 | #define ABB5ZES3_MEM_MAP_LEN 0x14 | ||
| 127 | |||
| 128 | struct abb5zes3_rtc_data { | ||
| 129 | struct rtc_device *rtc; | ||
| 130 | struct regmap *regmap; | ||
| 131 | struct mutex lock; | ||
| 132 | |||
| 133 | int irq; | ||
| 134 | |||
| 135 | bool battery_low; | ||
| 136 | }; | ||
| 137 | |||
| 138 | /* | ||
| 139 | * Try and match register bits w/ fixed null values to see whether we | ||
| 140 | * are dealing with an ABB5ZES3. Note: this function is called early | ||
| 141 | * during init and hence does need mutex protection. | ||
| 142 | */ | ||
| 143 | static int abb5zes3_i2c_validate_chip(struct regmap *regmap) | ||
| 144 | { | ||
| 145 | u8 regs[ABB5ZES3_MEM_MAP_LEN]; | ||
| 146 | static const u8 mask[ABB5ZES3_MEM_MAP_LEN] = { 0x00, 0x00, 0x10, 0x00, | ||
| 147 | 0x80, 0xc0, 0xc0, 0xf8, | ||
| 148 | 0xe0, 0x00, 0x00, 0x40, | ||
| 149 | 0x40, 0x78, 0x00, 0x00, | ||
| 150 | 0xf8, 0x00, 0x88, 0x00 }; | ||
| 151 | int ret, i; | ||
| 152 | |||
| 153 | ret = regmap_bulk_read(regmap, 0, regs, ABB5ZES3_MEM_MAP_LEN); | ||
| 154 | if (ret) | ||
| 155 | return ret; | ||
| 156 | |||
| 157 | for (i = 0; i < ABB5ZES3_MEM_MAP_LEN; ++i) { | ||
| 158 | if (regs[i] & mask[i]) /* check if bits are cleared */ | ||
| 159 | return -ENODEV; | ||
| 160 | } | ||
| 161 | |||
| 162 | return 0; | ||
| 163 | } | ||
| 164 | |||
| 165 | /* Clear alarm status bit. */ | ||
| 166 | static int _abb5zes3_rtc_clear_alarm(struct device *dev) | ||
| 167 | { | ||
| 168 | struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); | ||
| 169 | int ret; | ||
| 170 | |||
| 171 | ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_CTRL2, | ||
| 172 | ABB5ZES3_REG_CTRL2_AF, 0); | ||
| 173 | if (ret) | ||
| 174 | dev_err(dev, "%s: clearing alarm failed (%d)\n", __func__, ret); | ||
| 175 | |||
| 176 | return ret; | ||
| 177 | } | ||
| 178 | |||
| 179 | /* Enable or disable alarm (i.e. alarm interrupt generation) */ | ||
| 180 | static int _abb5zes3_rtc_update_alarm(struct device *dev, bool enable) | ||
| 181 | { | ||
| 182 | struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); | ||
| 183 | int ret; | ||
| 184 | |||
| 185 | ret = regmap_update_bits(data->regmap, ABB5ZES3_REG_CTRL1, | ||
| 186 | ABB5ZES3_REG_CTRL1_AIE, | ||
| 187 | enable ? ABB5ZES3_REG_CTRL1_AIE : 0); | ||
| 188 | if (ret) | ||
| 189 | dev_err(dev, "%s: writing alarm INT failed (%d)\n", | ||
| 190 | __func__, ret); | ||
| 191 | |||
| 192 | return ret; | ||
| 193 | } | ||
| 194 | |||
| 195 | /* | ||
| 196 | * Note: we only read, so regmap inner lock protection is sufficient, i.e. | ||
| 197 | * we do not need driver's main lock protection. | ||
| 198 | */ | ||
| 199 | static int _abb5zes3_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
| 200 | { | ||
| 201 | struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); | ||
| 202 | u8 regs[ABB5ZES3_REG_RTC_SC + ABB5ZES3_RTC_SEC_LEN]; | ||
| 203 | int ret; | ||
| 204 | |||
| 205 | /* | ||
| 206 | * As we need to read CTRL1 register anyway to access 24/12h | ||
| 207 | * mode bit, we do a single bulk read of both control and RTC | ||
| 208 | * sections (they are consecutive). This also ease indexing | ||
| 209 | * of register values after bulk read. | ||
| 210 | */ | ||
| 211 | ret = regmap_bulk_read(data->regmap, ABB5ZES3_REG_CTRL1, regs, | ||
| 212 | sizeof(regs)); | ||
| 213 | if (ret) { | ||
| 214 | dev_err(dev, "%s: reading RTC time failed (%d)\n", | ||
| 215 | __func__, ret); | ||
| 216 | goto err; | ||
| 217 | } | ||
| 218 | |||
| 219 | /* If clock integrity is not guaranteed, do not return a time value */ | ||
| 220 | if (regs[ABB5ZES3_REG_RTC_SC] & ABB5ZES3_REG_RTC_SC_OSC) { | ||
| 221 | ret = -ENODATA; | ||
| 222 | goto err; | ||
| 223 | } | ||
| 224 | |||
| 225 | tm->tm_sec = bcd2bin(regs[ABB5ZES3_REG_RTC_SC] & 0x7F); | ||
| 226 | tm->tm_min = bcd2bin(regs[ABB5ZES3_REG_RTC_MN]); | ||
| 227 | |||
| 228 | if (regs[ABB5ZES3_REG_CTRL1] & ABB5ZES3_REG_CTRL1_PM) { /* 12hr mode */ | ||
| 229 | tm->tm_hour = bcd2bin(regs[ABB5ZES3_REG_RTC_HR] & 0x1f); | ||
| 230 | if (regs[ABB5ZES3_REG_RTC_HR] & ABB5ZES3_REG_RTC_HR_PM) /* PM */ | ||
| 231 | tm->tm_hour += 12; | ||
| 232 | } else { /* 24hr mode */ | ||
| 233 | tm->tm_hour = bcd2bin(regs[ABB5ZES3_REG_RTC_HR]); | ||
| 234 | } | ||
| 235 | |||
| 236 | tm->tm_mday = bcd2bin(regs[ABB5ZES3_REG_RTC_DT]); | ||
| 237 | tm->tm_wday = bcd2bin(regs[ABB5ZES3_REG_RTC_DW]); | ||
| 238 | tm->tm_mon = bcd2bin(regs[ABB5ZES3_REG_RTC_MO]) - 1; /* starts at 1 */ | ||
| 239 | tm->tm_year = bcd2bin(regs[ABB5ZES3_REG_RTC_YR]) + 100; | ||
| 240 | |||
| 241 | ret = rtc_valid_tm(tm); | ||
| 242 | |||
| 243 | err: | ||
| 244 | return ret; | ||
| 245 | } | ||
| 246 | |||
| 247 | static int abb5zes3_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
| 248 | { | ||
| 249 | struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); | ||
| 250 | u8 regs[ABB5ZES3_REG_RTC_SC + ABB5ZES3_RTC_SEC_LEN]; | ||
| 251 | int ret; | ||
| 252 | |||
| 253 | /* | ||
| 254 | * Year register is 8-bit wide and bcd-coded, i.e records values | ||
| 255 | * between 0 and 99. tm_year is an offset from 1900 and we are | ||
| 256 | * interested in the 2000-2099 range, so any value less than 100 | ||
| 257 | * is invalid. | ||
| 258 | */ | ||
| 259 | if (tm->tm_year < 100) | ||
| 260 | return -EINVAL; | ||
| 261 | |||
| 262 | regs[ABB5ZES3_REG_RTC_SC] = bin2bcd(tm->tm_sec); /* MSB=0 clears OSC */ | ||
| 263 | regs[ABB5ZES3_REG_RTC_MN] = bin2bcd(tm->tm_min); | ||
| 264 | regs[ABB5ZES3_REG_RTC_HR] = bin2bcd(tm->tm_hour); /* 24-hour format */ | ||
| 265 | regs[ABB5ZES3_REG_RTC_DT] = bin2bcd(tm->tm_mday); | ||
| 266 | regs[ABB5ZES3_REG_RTC_DW] = bin2bcd(tm->tm_wday); | ||
| 267 | regs[ABB5ZES3_REG_RTC_MO] = bin2bcd(tm->tm_mon + 1); | ||
| 268 | regs[ABB5ZES3_REG_RTC_YR] = bin2bcd(tm->tm_year - 100); | ||
| 269 | |||
| 270 | mutex_lock(&data->lock); | ||
| 271 | ret = regmap_bulk_write(data->regmap, ABB5ZES3_REG_RTC_SC, | ||
| 272 | regs + ABB5ZES3_REG_RTC_SC, | ||
| 273 | ABB5ZES3_RTC_SEC_LEN); | ||
| 274 | mutex_unlock(&data->lock); | ||
| 275 | |||
| 276 | |||
| 277 | return ret; | ||
| 278 | } | ||
| 279 | |||
| 280 | static int abb5zes3_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
| 281 | { | ||
| 282 | struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); | ||
| 283 | struct rtc_time rtc_tm, *alarm_tm = &alarm->time; | ||
| 284 | unsigned long rtc_secs, alarm_secs; | ||
| 285 | u8 regs[ABB5ZES3_ALRM_SEC_LEN]; | ||
| 286 | unsigned int reg; | ||
| 287 | int ret; | ||
| 288 | |||
| 289 | mutex_lock(&data->lock); | ||
| 290 | ret = regmap_bulk_read(data->regmap, ABB5ZES3_REG_ALRM_MN, regs, | ||
| 291 | ABB5ZES3_ALRM_SEC_LEN); | ||
| 292 | if (ret) { | ||
| 293 | dev_err(dev, "%s: reading alarm section failed (%d)\n", | ||
| 294 | __func__, ret); | ||
| 295 | goto err; | ||
| 296 | } | ||
| 297 | |||
| 298 | alarm_tm->tm_sec = 0; | ||
| 299 | alarm_tm->tm_min = bcd2bin(regs[0] & 0x7f); | ||
| 300 | alarm_tm->tm_hour = bcd2bin(regs[1] & 0x3f); | ||
| 301 | alarm_tm->tm_mday = bcd2bin(regs[2] & 0x3f); | ||
| 302 | alarm_tm->tm_wday = -1; | ||
| 303 | |||
| 304 | /* | ||
| 305 | * The alarm section does not store year/month. We use the ones in rtc | ||
| 306 | * section as a basis and increment month and then year if needed to get | ||
| 307 | * alarm after current time. | ||
| 308 | */ | ||
| 309 | ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); | ||
| 310 | if (ret) | ||
| 311 | goto err; | ||
| 312 | |||
| 313 | alarm_tm->tm_year = rtc_tm.tm_year; | ||
| 314 | alarm_tm->tm_mon = rtc_tm.tm_mon; | ||
| 315 | |||
| 316 | ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); | ||
| 317 | if (ret) | ||
| 318 | goto err; | ||
| 319 | |||
| 320 | ret = rtc_tm_to_time(alarm_tm, &alarm_secs); | ||
| 321 | if (ret) | ||
| 322 | goto err; | ||
| 323 | |||
| 324 | if (alarm_secs < rtc_secs) { | ||
| 325 | if (alarm_tm->tm_mon == 11) { | ||
| 326 | alarm_tm->tm_mon = 0; | ||
| 327 | alarm_tm->tm_year += 1; | ||
| 328 | } else { | ||
| 329 | alarm_tm->tm_mon += 1; | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | ret = regmap_read(data->regmap, ABB5ZES3_REG_CTRL1, ®); | ||
| 334 | if (ret) { | ||
| 335 | dev_err(dev, "%s: reading ctrl reg failed (%d)\n", | ||
| 336 | __func__, ret); | ||
| 337 | goto err; | ||
| 338 | } | ||
| 339 | |||
| 340 | alarm->enabled = !!(reg & ABB5ZES3_REG_CTRL1_AIE); | ||
| 341 | |||
| 342 | err: | ||
| 343 | mutex_unlock(&data->lock); | ||
| 344 | |||
| 345 | return ret; | ||
| 346 | } | ||
| 347 | |||
| 348 | /* ALARM is only accurate to the minute (not the second) */ | ||
| 349 | static int abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | ||
| 350 | { | ||
| 351 | struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); | ||
| 352 | struct rtc_time *alarm_tm = &alarm->time; | ||
| 353 | unsigned long rtc_secs, alarm_secs; | ||
| 354 | u8 regs[ABB5ZES3_ALRM_SEC_LEN]; | ||
| 355 | struct rtc_time rtc_tm; | ||
| 356 | int ret, enable = 1; | ||
| 357 | |||
| 358 | mutex_lock(&data->lock); | ||
| 359 | ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); | ||
| 360 | if (ret) | ||
| 361 | goto err; | ||
| 362 | |||
| 363 | ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); | ||
| 364 | if (ret) | ||
| 365 | goto err; | ||
| 366 | |||
| 367 | ret = rtc_tm_to_time(alarm_tm, &alarm_secs); | ||
| 368 | if (ret) | ||
| 369 | goto err; | ||
| 370 | |||
| 371 | /* If alarm time is before current time, disable the alarm */ | ||
| 372 | if (!alarm->enabled || alarm_secs <= rtc_secs) { | ||
| 373 | enable = 0; | ||
| 374 | } else { | ||
| 375 | /* | ||
| 376 | * Chip only support alarms up to one month in the future. Let's | ||
| 377 | * return an error if we get something after that limit. | ||
| 378 | * Comparison is done by incrementing rtc_tm month field by one | ||
| 379 | * and checking alarm value is still below. | ||
| 380 | */ | ||
| 381 | if (rtc_tm.tm_mon == 11) { /* handle year wrapping */ | ||
| 382 | rtc_tm.tm_mon = 0; | ||
| 383 | rtc_tm.tm_year += 1; | ||
| 384 | } else { | ||
| 385 | rtc_tm.tm_mon += 1; | ||
| 386 | } | ||
| 387 | |||
| 388 | ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); | ||
| 389 | if (ret) | ||
| 390 | goto err; | ||
| 391 | |||
| 392 | if (alarm_secs > rtc_secs) { | ||
| 393 | dev_err(dev, "%s: alarm maximum is one month in the " | ||
| 394 | "future (%d)\n", __func__, ret); | ||
| 395 | ret = -EINVAL; | ||
| 396 | goto err; | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | /* Disable the alarm before modifying it */ | ||
| 401 | ret = _abb5zes3_rtc_update_alarm(dev, 0); | ||
| 402 | if (ret < 0) { | ||
| 403 | dev_err(dev, "%s: unable to disable the alarm (%d)\n", | ||
| 404 | __func__, ret); | ||
| 405 | goto err; | ||
| 406 | } | ||
| 407 | |||
| 408 | /* Program alarm registers */ | ||
| 409 | regs[0] = bin2bcd(alarm_tm->tm_min) & 0x7f; /* minute */ | ||
| 410 | regs[1] = bin2bcd(alarm_tm->tm_hour) & 0x3f; /* hour */ | ||
| 411 | regs[2] = bin2bcd(alarm_tm->tm_mday) & 0x3f; /* day of the month */ | ||
| 412 | regs[3] = ABB5ZES3_REG_ALRM_DW_AE; /* do not match day of the week */ | ||
| 413 | |||
| 414 | ret = regmap_bulk_write(data->regmap, ABB5ZES3_REG_ALRM_MN, regs, | ||
| 415 | ABB5ZES3_ALRM_SEC_LEN); | ||
| 416 | if (ret < 0) { | ||
| 417 | dev_err(dev, "%s: writing ALARM section failed (%d)\n", | ||
| 418 | __func__, ret); | ||
| 419 | goto err; | ||
| 420 | } | ||
| 421 | |||
| 422 | /* Enable or disable alarm */ | ||
| 423 | ret = _abb5zes3_rtc_update_alarm(dev, enable); | ||
| 424 | |||
| 425 | err: | ||
| 426 | mutex_unlock(&data->lock); | ||
| 427 | |||
| 428 | return ret; | ||
| 429 | } | ||
| 430 | |||
| 431 | |||
| 432 | /* Enable or disable battery low irq generation */ | ||
| 433 | static inline int _abb5zes3_rtc_battery_low_irq_enable(struct regmap *regmap, | ||
| 434 | bool enable) | ||
| 435 | { | ||
| 436 | return regmap_update_bits(regmap, ABB5ZES3_REG_CTRL3, | ||
| 437 | ABB5ZES3_REG_CTRL3_BLIE, | ||
| 438 | enable ? ABB5ZES3_REG_CTRL3_BLIE : 0); | ||
| 439 | } | ||
| 440 | |||
| 441 | /* | ||
| 442 | * Check current RTC status and enable/disable what needs to be. Return 0 if | ||
| 443 | * everything went ok and a negative value upon error. Note: this function | ||
| 444 | * is called early during init and hence does need mutex protection. | ||
| 445 | */ | ||
| 446 | static int abb5zes3_rtc_check_setup(struct device *dev) | ||
| 447 | { | ||
| 448 | struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); | ||
| 449 | struct regmap *regmap = data->regmap; | ||
| 450 | unsigned int reg; | ||
| 451 | int ret; | ||
| 452 | u8 mask; | ||
| 453 | |||
| 454 | /* | ||
| 455 | * By default, the devices generates a 32.768KHz signal on IRQ#1 pin. It | ||
| 456 | * is disabled here to prevent polluting the interrupt line and | ||
| 457 | * uselessly triggering the IRQ handler we install for alarm and battery | ||
| 458 | * low events. Note: this is done before clearing int. status below | ||
| 459 | * in this function. | ||
| 460 | * We also disable all timers and set timer interrupt to permanent (not | ||
| 461 | * pulsed). | ||
| 462 | */ | ||
| 463 | mask = (ABB5ZES3_REG_TIM_CLK_TBC | ABB5ZES3_REG_TIM_CLK_TAC0 | | ||
| 464 | ABB5ZES3_REG_TIM_CLK_TAC1 | ABB5ZES3_REG_TIM_CLK_COF0 | | ||
| 465 | ABB5ZES3_REG_TIM_CLK_COF1 | ABB5ZES3_REG_TIM_CLK_COF2 | | ||
| 466 | ABB5ZES3_REG_TIM_CLK_TBM | ABB5ZES3_REG_TIM_CLK_TAM); | ||
| 467 | ret = regmap_update_bits(regmap, ABB5ZES3_REG_TIM_CLK, mask, | ||
| 468 | ABB5ZES3_REG_TIM_CLK_COF0 | ABB5ZES3_REG_TIM_CLK_COF1 | | ||
| 469 | ABB5ZES3_REG_TIM_CLK_COF2); | ||
| 470 | if (ret < 0) { | ||
| 471 | dev_err(dev, "%s: unable to initialize clkout register (%d)\n", | ||
| 472 | __func__, ret); | ||
| 473 | return ret; | ||
| 474 | } | ||
| 475 | |||
| 476 | /* | ||
| 477 | * Each component of the alarm (MN, HR, DT, DW) can be enabled/disabled | ||
| 478 | * individually by clearing/setting MSB of each associated register. So, | ||
| 479 | * we set all alarm enable bits to disable current alarm setting. | ||
| 480 | */ | ||
| 481 | mask = (ABB5ZES3_REG_ALRM_MN_AE | ABB5ZES3_REG_ALRM_HR_AE | | ||
| 482 | ABB5ZES3_REG_ALRM_DT_AE | ABB5ZES3_REG_ALRM_DW_AE); | ||
| 483 | ret = regmap_update_bits(regmap, ABB5ZES3_REG_CTRL2, mask, mask); | ||
| 484 | if (ret < 0) { | ||
| 485 | dev_err(dev, "%s: unable to disable alarm setting (%d)\n", | ||
| 486 | __func__, ret); | ||
| 487 | return ret; | ||
| 488 | } | ||
| 489 | |||
| 490 | /* Set Control 1 register (RTC enabled, 24hr mode, all int. disabled) */ | ||
| 491 | mask = (ABB5ZES3_REG_CTRL1_CIE | ABB5ZES3_REG_CTRL1_AIE | | ||
| 492 | ABB5ZES3_REG_CTRL1_SIE | ABB5ZES3_REG_CTRL1_PM | | ||
| 493 | ABB5ZES3_REG_CTRL1_CAP | ABB5ZES3_REG_CTRL1_STOP); | ||
| 494 | ret = regmap_update_bits(regmap, ABB5ZES3_REG_CTRL1, mask, 0); | ||
| 495 | if (ret < 0) { | ||
| 496 | dev_err(dev, "%s: unable to initialize CTRL1 register (%d)\n", | ||
| 497 | __func__, ret); | ||
| 498 | return ret; | ||
| 499 | } | ||
| 500 | |||
| 501 | /* | ||
| 502 | * Set Control 2 register (timer int. disabled, alarm status cleared). | ||
| 503 | * WTAF is read-only and cleared automatically by reading the register. | ||
| 504 | */ | ||
| 505 | mask = (ABB5ZES3_REG_CTRL2_CTBIE | ABB5ZES3_REG_CTRL2_CTAIE | | ||
| 506 | ABB5ZES3_REG_CTRL2_WTAIE | ABB5ZES3_REG_CTRL2_AF | | ||
| 507 | ABB5ZES3_REG_CTRL2_SF | ABB5ZES3_REG_CTRL2_CTBF | | ||
| 508 | ABB5ZES3_REG_CTRL2_CTAF); | ||
| 509 | ret = regmap_update_bits(regmap, ABB5ZES3_REG_CTRL2, mask, 0); | ||
| 510 | if (ret < 0) { | ||
| 511 | dev_err(dev, "%s: unable to initialize CTRL2 register (%d)\n", | ||
| 512 | __func__, ret); | ||
| 513 | return ret; | ||
| 514 | } | ||
| 515 | |||
| 516 | /* | ||
| 517 | * Enable battery low detection function and battery switchover function | ||
| 518 | * (standard mode). Disable associated interrupts. Clear battery | ||
| 519 | * switchover flag but not battery low flag. The latter is checked | ||
| 520 | * later below. | ||
| 521 | */ | ||
| 522 | mask = (ABB5ZES3_REG_CTRL3_PM0 | ABB5ZES3_REG_CTRL3_PM1 | | ||
| 523 | ABB5ZES3_REG_CTRL3_PM2 | ABB5ZES3_REG_CTRL3_BLIE | | ||
| 524 | ABB5ZES3_REG_CTRL3_BSIE| ABB5ZES3_REG_CTRL3_BSF); | ||
| 525 | ret = regmap_update_bits(regmap, ABB5ZES3_REG_CTRL3, mask, 0); | ||
| 526 | if (ret < 0) { | ||
| 527 | dev_err(dev, "%s: unable to initialize CTRL3 register (%d)\n", | ||
| 528 | __func__, ret); | ||
| 529 | return ret; | ||
| 530 | } | ||
| 531 | |||
| 532 | /* Check oscillator integrity flag */ | ||
| 533 | ret = regmap_read(regmap, ABB5ZES3_REG_RTC_SC, ®); | ||
| 534 | if (ret < 0) { | ||
| 535 | dev_err(dev, "%s: unable to read osc. integrity flag (%d)\n", | ||
| 536 | __func__, ret); | ||
| 537 | return ret; | ||
| 538 | } | ||
| 539 | |||
| 540 | if (reg & ABB5ZES3_REG_RTC_SC_OSC) { | ||
| 541 | dev_err(dev, "clock integrity not guaranteed. Osc. has stopped " | ||
| 542 | "or has been interrupted.\n"); | ||
| 543 | dev_err(dev, "change battery (if not already done) and " | ||
| 544 | "then set time to reset osc. failure flag.\n"); | ||
| 545 | } | ||
| 546 | |||
| 547 | /* | ||
| 548 | * Check battery low flag at startup: this allows reporting battery | ||
| 549 | * is low at startup when IRQ line is not connected. Note: we record | ||
| 550 | * current status to avoid reenabling this interrupt later in probe | ||
| 551 | * function if battery is low. | ||
| 552 | */ | ||
| 553 | ret = regmap_read(regmap, ABB5ZES3_REG_CTRL3, ®); | ||
| 554 | if (ret < 0) { | ||
| 555 | dev_err(dev, "%s: unable to read battery low flag (%d)\n", | ||
| 556 | __func__, ret); | ||
| 557 | return ret; | ||
| 558 | } | ||
| 559 | |||
| 560 | data->battery_low = reg & ABB5ZES3_REG_CTRL3_BLF; | ||
| 561 | if (data->battery_low) { | ||
| 562 | dev_err(dev, "RTC battery is low; please, consider " | ||
| 563 | "changing it!\n"); | ||
| 564 | |||
| 565 | ret = _abb5zes3_rtc_battery_low_irq_enable(regmap, false); | ||
| 566 | if (ret) | ||
| 567 | dev_err(dev, "%s: disabling battery low interrupt " | ||
| 568 | "generation failed (%d)\n", __func__, ret); | ||
| 569 | } | ||
| 570 | |||
| 571 | return ret; | ||
| 572 | } | ||
| 573 | |||
| 574 | static int abb5zes3_rtc_alarm_irq_enable(struct device *dev, | ||
| 575 | unsigned int enable) | ||
| 576 | { | ||
| 577 | struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(dev); | ||
| 578 | int ret = 0; | ||
| 579 | |||
| 580 | if (rtc_data->irq) { | ||
| 581 | mutex_lock(&rtc_data->lock); | ||
| 582 | ret = _abb5zes3_rtc_update_alarm(dev, enable); | ||
| 583 | mutex_unlock(&rtc_data->lock); | ||
| 584 | } | ||
| 585 | |||
| 586 | return ret; | ||
| 587 | } | ||
| 588 | |||
| 589 | static irqreturn_t _abb5zes3_rtc_interrupt(int irq, void *data) | ||
| 590 | { | ||
| 591 | struct i2c_client *client = data; | ||
| 592 | struct device *dev = &client->dev; | ||
| 593 | struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(dev); | ||
| 594 | struct rtc_device *rtc = rtc_data->rtc; | ||
| 595 | u8 regs[ABB5ZES3_CTRL_SEC_LEN]; | ||
| 596 | int ret, handled = IRQ_NONE; | ||
| 597 | |||
| 598 | ret = regmap_bulk_read(rtc_data->regmap, 0, regs, | ||
| 599 | ABB5ZES3_CTRL_SEC_LEN); | ||
| 600 | if (ret) { | ||
| 601 | dev_err(dev, "%s: unable to read control section (%d)!\n", | ||
| 602 | __func__, ret); | ||
| 603 | return handled; | ||
| 604 | } | ||
| 605 | |||
| 606 | /* | ||
| 607 | * Check battery low detection flag and disable battery low interrupt | ||
| 608 | * generation if flag is set (interrupt can only be cleared when | ||
| 609 | * battery is replaced). | ||
| 610 | */ | ||
| 611 | if (regs[ABB5ZES3_REG_CTRL3] & ABB5ZES3_REG_CTRL3_BLF) { | ||
| 612 | dev_err(dev, "RTC battery is low; please change it!\n"); | ||
| 613 | |||
| 614 | _abb5zes3_rtc_battery_low_irq_enable(rtc_data->regmap, false); | ||
| 615 | |||
| 616 | handled = IRQ_HANDLED; | ||
| 617 | } | ||
| 618 | |||
| 619 | /* Check alarm flag */ | ||
| 620 | if (regs[ABB5ZES3_REG_CTRL2] & ABB5ZES3_REG_CTRL2_AF) { | ||
| 621 | dev_dbg(dev, "RTC alarm!\n"); | ||
| 622 | |||
| 623 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); | ||
| 624 | |||
| 625 | /* Acknowledge and disable the alarm */ | ||
| 626 | _abb5zes3_rtc_clear_alarm(dev); | ||
| 627 | _abb5zes3_rtc_update_alarm(dev, 0); | ||
| 628 | |||
| 629 | handled = IRQ_HANDLED; | ||
| 630 | } | ||
| 631 | |||
| 632 | return handled; | ||
| 633 | } | ||
| 634 | |||
| 635 | static const struct rtc_class_ops rtc_ops = { | ||
| 636 | .read_time = _abb5zes3_rtc_read_time, | ||
| 637 | .set_time = abb5zes3_rtc_set_time, | ||
| 638 | .read_alarm = abb5zes3_rtc_read_alarm, | ||
| 639 | .set_alarm = abb5zes3_rtc_set_alarm, | ||
| 640 | .alarm_irq_enable = abb5zes3_rtc_alarm_irq_enable, | ||
| 641 | }; | ||
| 642 | |||
| 643 | static struct regmap_config abb5zes3_rtc_regmap_config = { | ||
| 644 | .reg_bits = 8, | ||
| 645 | .val_bits = 8, | ||
| 646 | }; | ||
| 647 | |||
| 648 | static int abb5zes3_probe(struct i2c_client *client, | ||
| 649 | const struct i2c_device_id *id) | ||
| 650 | { | ||
| 651 | struct abb5zes3_rtc_data *data = NULL; | ||
| 652 | struct device *dev = &client->dev; | ||
| 653 | struct regmap *regmap; | ||
| 654 | int ret; | ||
| 655 | |||
| 656 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | | ||
| 657 | I2C_FUNC_SMBUS_BYTE_DATA | | ||
| 658 | I2C_FUNC_SMBUS_I2C_BLOCK)) { | ||
| 659 | ret = -ENODEV; | ||
| 660 | goto err; | ||
| 661 | } | ||
| 662 | |||
| 663 | regmap = devm_regmap_init_i2c(client, &abb5zes3_rtc_regmap_config); | ||
| 664 | if (IS_ERR(regmap)) { | ||
| 665 | ret = PTR_ERR(regmap); | ||
| 666 | dev_err(dev, "%s: regmap allocation failed: %d\n", | ||
| 667 | __func__, ret); | ||
| 668 | goto err; | ||
| 669 | } | ||
| 670 | |||
| 671 | ret = abb5zes3_i2c_validate_chip(regmap); | ||
| 672 | if (ret) | ||
| 673 | goto err; | ||
| 674 | |||
| 675 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | ||
| 676 | if (!data) { | ||
| 677 | ret = -ENOMEM; | ||
| 678 | goto err; | ||
| 679 | } | ||
| 680 | |||
| 681 | mutex_init(&data->lock); | ||
| 682 | data->regmap = regmap; | ||
| 683 | dev_set_drvdata(dev, data); | ||
| 684 | |||
| 685 | ret = abb5zes3_rtc_check_setup(dev); | ||
| 686 | if (ret) | ||
| 687 | goto err; | ||
| 688 | |||
| 689 | if (client->irq > 0) { | ||
| 690 | ret = devm_request_threaded_irq(dev, client->irq, NULL, | ||
| 691 | _abb5zes3_rtc_interrupt, | ||
| 692 | IRQF_SHARED|IRQF_ONESHOT, | ||
| 693 | DRV_NAME, client); | ||
| 694 | if (!ret) { | ||
| 695 | device_init_wakeup(dev, true); | ||
| 696 | data->irq = client->irq; | ||
| 697 | dev_dbg(dev, "%s: irq %d used by RTC\n", __func__, | ||
| 698 | client->irq); | ||
| 699 | } else { | ||
| 700 | dev_err(dev, "%s: irq %d unavailable (%d)\n", | ||
| 701 | __func__, client->irq, ret); | ||
| 702 | goto err; | ||
| 703 | } | ||
| 704 | } | ||
| 705 | |||
| 706 | data->rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, | ||
| 707 | THIS_MODULE); | ||
| 708 | ret = PTR_ERR_OR_ZERO(data->rtc); | ||
| 709 | if (ret) { | ||
| 710 | dev_err(dev, "%s: unable to register RTC device (%d)\n", | ||
| 711 | __func__, ret); | ||
| 712 | goto err; | ||
| 713 | } | ||
| 714 | |||
| 715 | /* | ||
| 716 | * AB-B5Z5E only supports a coarse granularity alarm (one minute | ||
| 717 | * resolution up to one month) so we cannot support UIE mode | ||
| 718 | * using the device's alarm. Note it should be feasible to support | ||
| 719 | * such a feature using one of the two timers the device provides. | ||
| 720 | */ | ||
| 721 | data->rtc->uie_unsupported = 1; | ||
| 722 | |||
| 723 | /* Enable battery low detection interrupt if battery not already low */ | ||
| 724 | if (!data->battery_low && data->irq) { | ||
| 725 | ret = _abb5zes3_rtc_battery_low_irq_enable(regmap, true); | ||
| 726 | if (ret) { | ||
| 727 | dev_err(dev, "%s: enabling battery low interrupt " | ||
| 728 | "generation failed (%d)\n", __func__, ret); | ||
| 729 | goto err; | ||
| 730 | } | ||
| 731 | } | ||
| 732 | |||
| 733 | err: | ||
| 734 | if (ret && data && data->irq) | ||
| 735 | device_init_wakeup(dev, false); | ||
| 736 | return ret; | ||
| 737 | } | ||
| 738 | |||
| 739 | static int abb5zes3_remove(struct i2c_client *client) | ||
| 740 | { | ||
| 741 | struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(&client->dev); | ||
| 742 | |||
| 743 | if (rtc_data->irq > 0) | ||
| 744 | device_init_wakeup(&client->dev, false); | ||
| 745 | |||
| 746 | return 0; | ||
| 747 | } | ||
| 748 | |||
| 749 | #ifdef CONFIG_PM_SLEEP | ||
| 750 | static int abb5zes3_rtc_suspend(struct device *dev) | ||
| 751 | { | ||
| 752 | struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(dev); | ||
| 753 | |||
| 754 | if (device_may_wakeup(dev)) | ||
| 755 | return enable_irq_wake(rtc_data->irq); | ||
| 756 | |||
| 757 | return 0; | ||
| 758 | } | ||
| 759 | |||
| 760 | static int abb5zes3_rtc_resume(struct device *dev) | ||
| 761 | { | ||
| 762 | struct abb5zes3_rtc_data *rtc_data = dev_get_drvdata(dev); | ||
| 763 | |||
| 764 | if (device_may_wakeup(dev)) | ||
| 765 | return disable_irq_wake(rtc_data->irq); | ||
| 766 | |||
| 767 | return 0; | ||
| 768 | } | ||
| 769 | #endif | ||
| 770 | |||
| 771 | static SIMPLE_DEV_PM_OPS(abb5zes3_rtc_pm_ops, abb5zes3_rtc_suspend, | ||
| 772 | abb5zes3_rtc_resume); | ||
| 773 | |||
| 774 | #ifdef CONFIG_OF | ||
| 775 | static const struct of_device_id abb5zes3_dt_match[] = { | ||
| 776 | { .compatible = "abracon,abb5zes3" }, | ||
| 777 | { }, | ||
| 778 | }; | ||
| 779 | #endif | ||
| 780 | |||
| 781 | static const struct i2c_device_id abb5zes3_id[] = { | ||
| 782 | { "abb5zes3", 0 }, | ||
| 783 | { } | ||
| 784 | }; | ||
| 785 | MODULE_DEVICE_TABLE(i2c, abb5zes3_id); | ||
| 786 | |||
| 787 | static struct i2c_driver abb5zes3_driver = { | ||
| 788 | .driver = { | ||
| 789 | .name = DRV_NAME, | ||
| 790 | .owner = THIS_MODULE, | ||
| 791 | .pm = &abb5zes3_rtc_pm_ops, | ||
| 792 | .of_match_table = of_match_ptr(abb5zes3_dt_match), | ||
| 793 | }, | ||
| 794 | .probe = abb5zes3_probe, | ||
| 795 | .remove = abb5zes3_remove, | ||
| 796 | .id_table = abb5zes3_id, | ||
| 797 | }; | ||
| 798 | module_i2c_driver(abb5zes3_driver); | ||
| 799 | |||
| 800 | MODULE_AUTHOR("Arnaud EBALARD <arno@natisbad.org>"); | ||
| 801 | MODULE_DESCRIPTION("Abracon AB-RTCMC-32.768kHz-B5ZE-S3 RTC/Alarm driver"); | ||
| 802 | MODULE_LICENSE("GPL"); | ||
