^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * An I2C and SPI driver for the NXP PCF2127/29 RTC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2013 Til-Technologies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Renaud Cerrato <r.cerrato@til-technologies.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Watchdog and tamper functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Author: Bruno Thomsen <bruno.thomsen@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * based on the other drivers in this same directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Datasheet: http://cache.nxp.com/documents/data_sheet/PCF2127.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/bcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/watchdog.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* Control register 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define PCF2127_REG_CTRL1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define PCF2127_BIT_CTRL1_TSF1 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* Control register 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PCF2127_REG_CTRL2 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PCF2127_BIT_CTRL2_AIE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define PCF2127_BIT_CTRL2_TSIE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PCF2127_BIT_CTRL2_AF BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PCF2127_BIT_CTRL2_TSF2 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PCF2127_BIT_CTRL2_WDTF BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Control register 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define PCF2127_REG_CTRL3 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PCF2127_BIT_CTRL3_BLIE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PCF2127_BIT_CTRL3_BIE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define PCF2127_BIT_CTRL3_BLF BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define PCF2127_BIT_CTRL3_BF BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define PCF2127_BIT_CTRL3_BTSE BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* Time and date registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define PCF2127_REG_SC 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PCF2127_BIT_SC_OSF BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define PCF2127_REG_MN 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PCF2127_REG_HR 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define PCF2127_REG_DM 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define PCF2127_REG_DW 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define PCF2127_REG_MO 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PCF2127_REG_YR 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* Alarm registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PCF2127_REG_ALARM_SC 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define PCF2127_REG_ALARM_MN 0x0B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define PCF2127_REG_ALARM_HR 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define PCF2127_REG_ALARM_DM 0x0D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define PCF2127_REG_ALARM_DW 0x0E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PCF2127_BIT_ALARM_AE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Watchdog registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define PCF2127_REG_WD_CTL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define PCF2127_BIT_WD_CTL_TF0 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PCF2127_BIT_WD_CTL_TF1 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define PCF2127_BIT_WD_CTL_CD0 BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define PCF2127_BIT_WD_CTL_CD1 BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define PCF2127_REG_WD_VAL 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Tamper timestamp registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define PCF2127_REG_TS_CTRL 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define PCF2127_BIT_TS_CTRL_TSOFF BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define PCF2127_BIT_TS_CTRL_TSM BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define PCF2127_REG_TS_SC 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define PCF2127_REG_TS_MN 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define PCF2127_REG_TS_HR 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define PCF2127_REG_TS_DM 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define PCF2127_REG_TS_MO 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define PCF2127_REG_TS_YR 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * RAM registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * PCF2127 has 512 bytes general-purpose static RAM (SRAM) that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * battery backed and can survive a power outage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * PCF2129 doesn't have this feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define PCF2127_REG_RAM_ADDR_MSB 0x1A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define PCF2127_REG_RAM_WRT_CMD 0x1C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define PCF2127_REG_RAM_RD_CMD 0x1D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Watchdog timer value constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define PCF2127_WD_VAL_STOP 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define PCF2127_WD_VAL_MIN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define PCF2127_WD_VAL_MAX 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define PCF2127_WD_VAL_DEFAULT 60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct pcf2127 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct rtc_device *rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct watchdog_device wdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * In the routines that deal directly with the pcf2127 hardware, we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Avoid reading CTRL2 register as it causes WD_VAL register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * value to reset to 0 which means watchdog is stopped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_CTRL3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) (buf + PCF2127_REG_CTRL3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ARRAY_SIZE(buf) - PCF2127_REG_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dev_err(dev, "%s: read error\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (buf[PCF2127_REG_CTRL3] & PCF2127_BIT_CTRL3_BLF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) dev_info(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) "low voltage detected, check/replace RTC battery.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Clock integrity is not guaranteed when OSF flag is set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (buf[PCF2127_REG_SC] & PCF2127_BIT_SC_OSF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * no need clear the flag here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * it will be cleared once the new date is saved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) "oscillator stop detected, date/time is not reliable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) dev_dbg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) "%s: raw data is cr3=%02x, sec=%02x, min=%02x, hr=%02x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "mday=%02x, wday=%02x, mon=%02x, year=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) __func__, buf[PCF2127_REG_CTRL3], buf[PCF2127_REG_SC],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) buf[PCF2127_REG_MN], buf[PCF2127_REG_HR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) buf[PCF2127_REG_DM], buf[PCF2127_REG_DW],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) buf[PCF2127_REG_MO], buf[PCF2127_REG_YR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F); /* rtc hr 0-23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) tm->tm_wday = buf[PCF2127_REG_DW] & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) tm->tm_year += 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) "mday=%d, mon=%d, year=%d, wday=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) tm->tm_sec, tm->tm_min, tm->tm_hour,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsigned char buf[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int i = 0, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) "mday=%d, mon=%d, year=%d, wday=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) tm->tm_sec, tm->tm_min, tm->tm_hour,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* hours, minutes and seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) buf[i++] = bin2bcd(tm->tm_sec); /* this will also clear OSF flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) buf[i++] = bin2bcd(tm->tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) buf[i++] = bin2bcd(tm->tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) buf[i++] = bin2bcd(tm->tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) buf[i++] = tm->tm_wday & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* month, 1 - 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) buf[i++] = bin2bcd(tm->tm_mon + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* year */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) buf[i++] = bin2bcd(tm->tm_year - 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* write register's data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) err = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_SC, buf, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) "%s: err=%d", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int pcf2127_rtc_ioctl(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int val, touser = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case RTC_VL_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (val & PCF2127_BIT_CTRL3_BLF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) touser |= RTC_VL_BACKUP_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (val & PCF2127_BIT_CTRL3_BF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) touser |= RTC_VL_BACKUP_SWITCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return put_user(touser, (unsigned int __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case RTC_VL_CLR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) PCF2127_BIT_CTRL3_BF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static const struct rtc_class_ops pcf2127_rtc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .ioctl = pcf2127_rtc_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .read_time = pcf2127_rtc_read_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .set_time = pcf2127_rtc_set_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int pcf2127_nvmem_read(void *priv, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) void *val, size_t bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct pcf2127 *pcf2127 = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned char offsetbuf[] = { offset >> 8, offset };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_ADDR_MSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) offsetbuf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_RD_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) val, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static int pcf2127_nvmem_write(void *priv, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) void *val, size_t bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct pcf2127 *pcf2127 = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) unsigned char offsetbuf[] = { offset >> 8, offset };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_ADDR_MSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) offsetbuf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) val, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* watchdog driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static int pcf2127_wdt_ping(struct watchdog_device *wdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct pcf2127 *pcf2127 = watchdog_get_drvdata(wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return regmap_write(pcf2127->regmap, PCF2127_REG_WD_VAL, wdd->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * Restart watchdog timer if feature is active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * Note: Reading CTRL2 register causes watchdog to stop which is unfortunate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * since register also contain control/status flags for other features.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * Always call this function after reading CTRL2 register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int pcf2127_wdt_active_ping(struct watchdog_device *wdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (watchdog_active(wdd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ret = pcf2127_wdt_ping(wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dev_err(wdd->parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) "%s: watchdog restart failed, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int pcf2127_wdt_start(struct watchdog_device *wdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return pcf2127_wdt_ping(wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int pcf2127_wdt_stop(struct watchdog_device *wdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct pcf2127 *pcf2127 = watchdog_get_drvdata(wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return regmap_write(pcf2127->regmap, PCF2127_REG_WD_VAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) PCF2127_WD_VAL_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static int pcf2127_wdt_set_timeout(struct watchdog_device *wdd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) unsigned int new_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) dev_dbg(wdd->parent, "new watchdog timeout: %is (old: %is)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) new_timeout, wdd->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) wdd->timeout = new_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return pcf2127_wdt_active_ping(wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static const struct watchdog_info pcf2127_wdt_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .identity = "NXP PCF2127/PCF2129 Watchdog",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static const struct watchdog_ops pcf2127_watchdog_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .start = pcf2127_wdt_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .stop = pcf2127_wdt_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .ping = pcf2127_wdt_ping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .set_timeout = pcf2127_wdt_set_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static int pcf2127_watchdog_init(struct device *dev, struct pcf2127 *pcf2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) u32 wdd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (!IS_ENABLED(CONFIG_WATCHDOG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) !device_property_read_bool(dev, "reset-source"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) pcf2127->wdd.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) pcf2127->wdd.info = &pcf2127_wdt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) pcf2127->wdd.ops = &pcf2127_watchdog_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) pcf2127->wdd.min_timeout = PCF2127_WD_VAL_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) pcf2127->wdd.max_timeout = PCF2127_WD_VAL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pcf2127->wdd.timeout = PCF2127_WD_VAL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pcf2127->wdd.min_hw_heartbeat_ms = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pcf2127->wdd.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) watchdog_set_drvdata(&pcf2127->wdd, pcf2127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* Test if watchdog timer is started by bootloader */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ret = regmap_read(pcf2127->regmap, PCF2127_REG_WD_VAL, &wdd_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (wdd_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) set_bit(WDOG_HW_RUNNING, &pcf2127->wdd.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return devm_watchdog_register_device(dev, &pcf2127->wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* Alarm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static int pcf2127_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) unsigned int buf[5], ctrl2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL2, &ctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = pcf2127_wdt_active_ping(&pcf2127->wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_ALARM_SC, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) alrm->enabled = ctrl2 & PCF2127_BIT_CTRL2_AIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) alrm->pending = ctrl2 & PCF2127_BIT_CTRL2_AF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) alrm->time.tm_sec = bcd2bin(buf[0] & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) alrm->time.tm_min = bcd2bin(buf[1] & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) alrm->time.tm_hour = bcd2bin(buf[2] & 0x3F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) alrm->time.tm_mday = bcd2bin(buf[3] & 0x3F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int pcf2127_rtc_alarm_irq_enable(struct device *dev, u32 enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) PCF2127_BIT_CTRL2_AIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) enable ? PCF2127_BIT_CTRL2_AIE : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return pcf2127_wdt_active_ping(&pcf2127->wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static int pcf2127_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) uint8_t buf[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) PCF2127_BIT_CTRL2_AF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ret = pcf2127_wdt_active_ping(&pcf2127->wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) buf[0] = bin2bcd(alrm->time.tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) buf[1] = bin2bcd(alrm->time.tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) buf[2] = bin2bcd(alrm->time.tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) buf[3] = bin2bcd(alrm->time.tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) buf[4] = PCF2127_BIT_ALARM_AE; /* Do not match on week day */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_ALARM_SC, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return pcf2127_rtc_alarm_irq_enable(dev, alrm->enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static irqreturn_t pcf2127_rtc_irq(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) unsigned int ctrl2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL2, &ctrl2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (!(ctrl2 & PCF2127_BIT_CTRL2_AF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) regmap_write(pcf2127->regmap, PCF2127_REG_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ctrl2 & ~(PCF2127_BIT_CTRL2_AF | PCF2127_BIT_CTRL2_WDTF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) rtc_update_irq(pcf2127->rtc, 1, RTC_IRQF | RTC_AF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) pcf2127_wdt_active_ping(&pcf2127->wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static const struct rtc_class_ops pcf2127_rtc_alrm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .ioctl = pcf2127_rtc_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .read_time = pcf2127_rtc_read_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .set_time = pcf2127_rtc_set_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .read_alarm = pcf2127_rtc_read_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .set_alarm = pcf2127_rtc_set_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) .alarm_irq_enable = pcf2127_rtc_alarm_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* sysfs interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static ssize_t timestamp0_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct pcf2127 *pcf2127 = dev_get_drvdata(dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) PCF2127_BIT_CTRL1_TSF1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) dev_err(dev, "%s: update ctrl1 ret=%d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) PCF2127_BIT_CTRL2_TSF2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) dev_err(dev, "%s: update ctrl2 ret=%d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret = pcf2127_wdt_active_ping(&pcf2127->wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static ssize_t timestamp0_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct pcf2127 *pcf2127 = dev_get_drvdata(dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct rtc_time tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) unsigned char data[25];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_CTRL1, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) sizeof(data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dev_err(dev, "%s: read error ret=%d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) dev_dbg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) "%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, ts_sc=%02x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) "ts_mn=%02x, ts_hr=%02x, ts_dm=%02x, ts_mo=%02x, ts_yr=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) __func__, data[PCF2127_REG_CTRL1], data[PCF2127_REG_CTRL2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) data[PCF2127_REG_CTRL3], data[PCF2127_REG_TS_SC],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) data[PCF2127_REG_TS_MN], data[PCF2127_REG_TS_HR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) data[PCF2127_REG_TS_DM], data[PCF2127_REG_TS_MO],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) data[PCF2127_REG_TS_YR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) ret = pcf2127_wdt_active_ping(&pcf2127->wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (!(data[PCF2127_REG_CTRL1] & PCF2127_BIT_CTRL1_TSF1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) !(data[PCF2127_REG_CTRL2] & PCF2127_BIT_CTRL2_TSF2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) tm.tm_sec = bcd2bin(data[PCF2127_REG_TS_SC] & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) tm.tm_min = bcd2bin(data[PCF2127_REG_TS_MN] & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) tm.tm_hour = bcd2bin(data[PCF2127_REG_TS_HR] & 0x3F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) tm.tm_mday = bcd2bin(data[PCF2127_REG_TS_DM] & 0x3F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* TS_MO register (month) value range: 1-12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) tm.tm_mon = bcd2bin(data[PCF2127_REG_TS_MO] & 0x1F) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) tm.tm_year = bcd2bin(data[PCF2127_REG_TS_YR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (tm.tm_year < 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) tm.tm_year += 100; /* assume we are in 1970...2069 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ret = rtc_valid_tm(&tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return sprintf(buf, "%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) (unsigned long long)rtc_tm_to_time64(&tm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static DEVICE_ATTR_RW(timestamp0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static struct attribute *pcf2127_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) &dev_attr_timestamp0.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static const struct attribute_group pcf2127_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) .attrs = pcf2127_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static int pcf2127_probe(struct device *dev, struct regmap *regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int alarm_irq, const char *name, bool has_nvmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct pcf2127 *pcf2127;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) dev_dbg(dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) pcf2127 = devm_kzalloc(dev, sizeof(*pcf2127), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (!pcf2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) pcf2127->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) dev_set_drvdata(dev, pcf2127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) pcf2127->rtc = devm_rtc_allocate_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (IS_ERR(pcf2127->rtc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return PTR_ERR(pcf2127->rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) pcf2127->rtc->ops = &pcf2127_rtc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) pcf2127->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) pcf2127->rtc->range_max = RTC_TIMESTAMP_END_2099;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) pcf2127->rtc->uie_unsupported = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (alarm_irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) ret = devm_request_threaded_irq(dev, alarm_irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) pcf2127_rtc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) IRQF_TRIGGER_LOW | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) dev_name(dev), dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) dev_err(dev, "failed to request alarm irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (alarm_irq > 0 || device_property_read_bool(dev, "wakeup-source")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) device_init_wakeup(dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pcf2127->rtc->ops = &pcf2127_rtc_alrm_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (has_nvmem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct nvmem_config nvmem_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) .priv = pcf2127,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) .reg_read = pcf2127_nvmem_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) .reg_write = pcf2127_nvmem_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) .size = 512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ret = rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * Watchdog timer enabled and reset pin /RST activated when timed out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * Select 1Hz clock source for watchdog timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * Note: Countdown timer disabled and not available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_WD_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) PCF2127_BIT_WD_CTL_CD1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) PCF2127_BIT_WD_CTL_CD0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) PCF2127_BIT_WD_CTL_TF1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) PCF2127_BIT_WD_CTL_TF0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) PCF2127_BIT_WD_CTL_CD1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) PCF2127_BIT_WD_CTL_CD0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) PCF2127_BIT_WD_CTL_TF1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) dev_err(dev, "%s: watchdog config (wd_ctl) failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) pcf2127_watchdog_init(dev, pcf2127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * Disable battery low/switch-over timestamp and interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * Clear battery interrupt flags which can block new trigger events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * Note: This is the default chip behaviour but added to ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * correct tamper timestamp and interrupt function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) PCF2127_BIT_CTRL3_BTSE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) PCF2127_BIT_CTRL3_BIE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) PCF2127_BIT_CTRL3_BLIE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) dev_err(dev, "%s: interrupt config (ctrl3) failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * Enable timestamp function and store timestamp of first trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * event until TSF1 and TFS2 interrupt flags are cleared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_TS_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) PCF2127_BIT_TS_CTRL_TSOFF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) PCF2127_BIT_TS_CTRL_TSM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) PCF2127_BIT_TS_CTRL_TSM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dev_err(dev, "%s: tamper detection config (ts_ctrl) failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * Enable interrupt generation when TSF1 or TSF2 timestamp flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * are set. Interrupt signal is an open-drain output and can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * left floating if unused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ret = regmap_update_bits(pcf2127->regmap, PCF2127_REG_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) PCF2127_BIT_CTRL2_TSIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) PCF2127_BIT_CTRL2_TSIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev_err(dev, "%s: tamper detection config (ctrl2) failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) ret = rtc_add_group(pcf2127->rtc, &pcf2127_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) dev_err(dev, "%s: tamper sysfs registering failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return rtc_register_device(pcf2127->rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static const struct of_device_id pcf2127_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) { .compatible = "nxp,pcf2127" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) { .compatible = "nxp,pcf2129" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) { .compatible = "nxp,pca2129" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) MODULE_DEVICE_TABLE(of, pcf2127_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) #if IS_ENABLED(CONFIG_I2C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int pcf2127_i2c_write(void *context, const void *data, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ret = i2c_master_send(client, data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (ret != count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static int pcf2127_i2c_gather_write(void *context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) const void *reg, size_t reg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) const void *val, size_t val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (WARN_ON(reg_size != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) buf = kmalloc(val_size + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) memcpy(buf, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) memcpy(buf + 1, val, val_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ret = i2c_master_send(client, buf, val_size + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (ret != val_size + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static int pcf2127_i2c_read(void *context, const void *reg, size_t reg_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) void *val, size_t val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (WARN_ON(reg_size != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ret = i2c_master_send(client, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ret = i2c_master_recv(client, val, val_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (ret != val_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * The reason we need this custom regmap_bus instead of using regmap_init_i2c()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * is that the STOP condition is required between set register address and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * read register data when reading from registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static const struct regmap_bus pcf2127_i2c_regmap = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) .write = pcf2127_i2c_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) .gather_write = pcf2127_i2c_gather_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) .read = pcf2127_i2c_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static struct i2c_driver pcf2127_i2c_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static int pcf2127_i2c_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static const struct regmap_config config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .max_register = 0x1d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) regmap = devm_regmap_init(&client->dev, &pcf2127_i2c_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) &client->dev, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) __func__, PTR_ERR(regmap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return pcf2127_probe(&client->dev, regmap, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pcf2127_i2c_driver.driver.name, id->driver_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static const struct i2c_device_id pcf2127_i2c_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) { "pcf2127", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) { "pcf2129", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) { "pca2129", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static struct i2c_driver pcf2127_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) .name = "rtc-pcf2127-i2c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) .of_match_table = of_match_ptr(pcf2127_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .probe = pcf2127_i2c_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) .id_table = pcf2127_i2c_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) static int pcf2127_i2c_register_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return i2c_add_driver(&pcf2127_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static void pcf2127_i2c_unregister_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) i2c_del_driver(&pcf2127_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static int pcf2127_i2c_register_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static void pcf2127_i2c_unregister_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) #if IS_ENABLED(CONFIG_SPI_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static struct spi_driver pcf2127_spi_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) static int pcf2127_spi_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static const struct regmap_config config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .read_flag_mask = 0xa0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .write_flag_mask = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .max_register = 0x1d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) regmap = devm_regmap_init_spi(spi, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) __func__, PTR_ERR(regmap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return pcf2127_probe(&spi->dev, regmap, spi->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) pcf2127_spi_driver.driver.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) spi_get_device_id(spi)->driver_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static const struct spi_device_id pcf2127_spi_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) { "pcf2127", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) { "pcf2129", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) { "pca2129", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) MODULE_DEVICE_TABLE(spi, pcf2127_spi_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static struct spi_driver pcf2127_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .name = "rtc-pcf2127-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .of_match_table = of_match_ptr(pcf2127_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) .probe = pcf2127_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .id_table = pcf2127_spi_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) static int pcf2127_spi_register_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return spi_register_driver(&pcf2127_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static void pcf2127_spi_unregister_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) spi_unregister_driver(&pcf2127_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static int pcf2127_spi_register_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static void pcf2127_spi_unregister_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int __init pcf2127_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) ret = pcf2127_i2c_register_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) pr_err("Failed to register pcf2127 i2c driver: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) ret = pcf2127_spi_register_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) pr_err("Failed to register pcf2127 spi driver: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) pcf2127_i2c_unregister_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) module_init(pcf2127_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static void __exit pcf2127_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) pcf2127_spi_unregister_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) pcf2127_i2c_unregister_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) module_exit(pcf2127_exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) MODULE_AUTHOR("Renaud Cerrato <r.cerrato@til-technologies.fr>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) MODULE_DESCRIPTION("NXP PCF2127/29 RTC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) MODULE_LICENSE("GPL v2");