Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");