xref: /openbmc/linux/drivers/rtc/rtc-r7301.c (revision d0034a7a4ac7fae708146ac0059b9c47a1543f0d)
109c434b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
20b6a8f5cSAkinobu Mita /*
30b6a8f5cSAkinobu Mita  * EPSON TOYOCOM RTC-7301SF/DG Driver
40b6a8f5cSAkinobu Mita  *
50b6a8f5cSAkinobu Mita  * Copyright (c) 2016 Akinobu Mita <akinobu.mita@gmail.com>
60b6a8f5cSAkinobu Mita  *
70b6a8f5cSAkinobu Mita  * Based on rtc-rp5c01.c
80b6a8f5cSAkinobu Mita  *
90b6a8f5cSAkinobu Mita  * Datasheet: http://www5.epsondevice.com/en/products/parallel/rtc7301sf.html
100b6a8f5cSAkinobu Mita  */
110b6a8f5cSAkinobu Mita 
120b6a8f5cSAkinobu Mita #include <linux/io.h>
130b6a8f5cSAkinobu Mita #include <linux/kernel.h>
140b6a8f5cSAkinobu Mita #include <linux/module.h>
15ac316725SRandy Dunlap #include <linux/mod_devicetable.h>
160b6a8f5cSAkinobu Mita #include <linux/delay.h>
170b6a8f5cSAkinobu Mita #include <linux/regmap.h>
180b6a8f5cSAkinobu Mita #include <linux/platform_device.h>
190b6a8f5cSAkinobu Mita #include <linux/rtc.h>
200b6a8f5cSAkinobu Mita 
210b6a8f5cSAkinobu Mita #define DRV_NAME "rtc-r7301"
220b6a8f5cSAkinobu Mita 
230b6a8f5cSAkinobu Mita #define RTC7301_1_SEC		0x0	/* Bank 0 and Band 1 */
240b6a8f5cSAkinobu Mita #define RTC7301_10_SEC		0x1	/* Bank 0 and Band 1 */
250b6a8f5cSAkinobu Mita #define RTC7301_AE		BIT(3)
260b6a8f5cSAkinobu Mita #define RTC7301_1_MIN		0x2	/* Bank 0 and Band 1 */
270b6a8f5cSAkinobu Mita #define RTC7301_10_MIN		0x3	/* Bank 0 and Band 1 */
280b6a8f5cSAkinobu Mita #define RTC7301_1_HOUR		0x4	/* Bank 0 and Band 1 */
290b6a8f5cSAkinobu Mita #define RTC7301_10_HOUR		0x5	/* Bank 0 and Band 1 */
300b6a8f5cSAkinobu Mita #define RTC7301_DAY_OF_WEEK	0x6	/* Bank 0 and Band 1 */
310b6a8f5cSAkinobu Mita #define RTC7301_1_DAY		0x7	/* Bank 0 and Band 1 */
320b6a8f5cSAkinobu Mita #define RTC7301_10_DAY		0x8	/* Bank 0 and Band 1 */
330b6a8f5cSAkinobu Mita #define RTC7301_1_MONTH		0x9	/* Bank 0 */
340b6a8f5cSAkinobu Mita #define RTC7301_10_MONTH	0xa	/* Bank 0 */
350b6a8f5cSAkinobu Mita #define RTC7301_1_YEAR		0xb	/* Bank 0 */
360b6a8f5cSAkinobu Mita #define RTC7301_10_YEAR		0xc	/* Bank 0 */
370b6a8f5cSAkinobu Mita #define RTC7301_100_YEAR	0xd	/* Bank 0 */
380b6a8f5cSAkinobu Mita #define RTC7301_1000_YEAR	0xe	/* Bank 0 */
390b6a8f5cSAkinobu Mita #define RTC7301_ALARM_CONTROL	0xe	/* Bank 1 */
400b6a8f5cSAkinobu Mita #define RTC7301_ALARM_CONTROL_AIE	BIT(0)
410b6a8f5cSAkinobu Mita #define RTC7301_ALARM_CONTROL_AF	BIT(1)
420b6a8f5cSAkinobu Mita #define RTC7301_TIMER_CONTROL	0xe	/* Bank 2 */
430b6a8f5cSAkinobu Mita #define RTC7301_TIMER_CONTROL_TIE	BIT(0)
440b6a8f5cSAkinobu Mita #define RTC7301_TIMER_CONTROL_TF	BIT(1)
450b6a8f5cSAkinobu Mita #define RTC7301_CONTROL		0xf	/* All banks */
460b6a8f5cSAkinobu Mita #define RTC7301_CONTROL_BUSY		BIT(0)
470b6a8f5cSAkinobu Mita #define RTC7301_CONTROL_STOP		BIT(1)
480b6a8f5cSAkinobu Mita #define RTC7301_CONTROL_BANK_SEL_0	BIT(2)
490b6a8f5cSAkinobu Mita #define RTC7301_CONTROL_BANK_SEL_1	BIT(3)
500b6a8f5cSAkinobu Mita 
510b6a8f5cSAkinobu Mita struct rtc7301_priv {
520b6a8f5cSAkinobu Mita 	struct regmap *regmap;
530b6a8f5cSAkinobu Mita 	int irq;
540b6a8f5cSAkinobu Mita 	spinlock_t lock;
550b6a8f5cSAkinobu Mita 	u8 bank;
560b6a8f5cSAkinobu Mita };
570b6a8f5cSAkinobu Mita 
580b6a8f5cSAkinobu Mita static const struct regmap_config rtc7301_regmap_config = {
590b6a8f5cSAkinobu Mita 	.reg_bits = 32,
600b6a8f5cSAkinobu Mita 	.val_bits = 8,
610b6a8f5cSAkinobu Mita 	.reg_stride = 4,
620b6a8f5cSAkinobu Mita };
630b6a8f5cSAkinobu Mita 
rtc7301_read(struct rtc7301_priv * priv,unsigned int reg)640b6a8f5cSAkinobu Mita static u8 rtc7301_read(struct rtc7301_priv *priv, unsigned int reg)
650b6a8f5cSAkinobu Mita {
660b6a8f5cSAkinobu Mita 	int reg_stride = regmap_get_reg_stride(priv->regmap);
670b6a8f5cSAkinobu Mita 	unsigned int val;
680b6a8f5cSAkinobu Mita 
690b6a8f5cSAkinobu Mita 	regmap_read(priv->regmap, reg_stride * reg, &val);
700b6a8f5cSAkinobu Mita 
710b6a8f5cSAkinobu Mita 	return val & 0xf;
720b6a8f5cSAkinobu Mita }
730b6a8f5cSAkinobu Mita 
rtc7301_write(struct rtc7301_priv * priv,u8 val,unsigned int reg)740b6a8f5cSAkinobu Mita static void rtc7301_write(struct rtc7301_priv *priv, u8 val, unsigned int reg)
750b6a8f5cSAkinobu Mita {
760b6a8f5cSAkinobu Mita 	int reg_stride = regmap_get_reg_stride(priv->regmap);
770b6a8f5cSAkinobu Mita 
780b6a8f5cSAkinobu Mita 	regmap_write(priv->regmap, reg_stride * reg, val);
790b6a8f5cSAkinobu Mita }
800b6a8f5cSAkinobu Mita 
rtc7301_update_bits(struct rtc7301_priv * priv,unsigned int reg,u8 mask,u8 val)810b6a8f5cSAkinobu Mita static void rtc7301_update_bits(struct rtc7301_priv *priv, unsigned int reg,
820b6a8f5cSAkinobu Mita 				u8 mask, u8 val)
830b6a8f5cSAkinobu Mita {
840b6a8f5cSAkinobu Mita 	int reg_stride = regmap_get_reg_stride(priv->regmap);
850b6a8f5cSAkinobu Mita 
860b6a8f5cSAkinobu Mita 	regmap_update_bits(priv->regmap, reg_stride * reg, mask, val);
870b6a8f5cSAkinobu Mita }
880b6a8f5cSAkinobu Mita 
rtc7301_wait_while_busy(struct rtc7301_priv * priv)890b6a8f5cSAkinobu Mita static int rtc7301_wait_while_busy(struct rtc7301_priv *priv)
900b6a8f5cSAkinobu Mita {
910b6a8f5cSAkinobu Mita 	int retries = 100;
920b6a8f5cSAkinobu Mita 
930b6a8f5cSAkinobu Mita 	while (retries-- > 0) {
940b6a8f5cSAkinobu Mita 		u8 val;
950b6a8f5cSAkinobu Mita 
960b6a8f5cSAkinobu Mita 		val = rtc7301_read(priv, RTC7301_CONTROL);
970b6a8f5cSAkinobu Mita 		if (!(val & RTC7301_CONTROL_BUSY))
980b6a8f5cSAkinobu Mita 			return 0;
990b6a8f5cSAkinobu Mita 
100cd8c0bb2SJia-Ju Bai 		udelay(300);
1010b6a8f5cSAkinobu Mita 	}
1020b6a8f5cSAkinobu Mita 
1030b6a8f5cSAkinobu Mita 	return -ETIMEDOUT;
1040b6a8f5cSAkinobu Mita }
1050b6a8f5cSAkinobu Mita 
rtc7301_stop(struct rtc7301_priv * priv)1060b6a8f5cSAkinobu Mita static void rtc7301_stop(struct rtc7301_priv *priv)
1070b6a8f5cSAkinobu Mita {
1080b6a8f5cSAkinobu Mita 	rtc7301_update_bits(priv, RTC7301_CONTROL, RTC7301_CONTROL_STOP,
1090b6a8f5cSAkinobu Mita 			    RTC7301_CONTROL_STOP);
1100b6a8f5cSAkinobu Mita }
1110b6a8f5cSAkinobu Mita 
rtc7301_start(struct rtc7301_priv * priv)1120b6a8f5cSAkinobu Mita static void rtc7301_start(struct rtc7301_priv *priv)
1130b6a8f5cSAkinobu Mita {
1140b6a8f5cSAkinobu Mita 	rtc7301_update_bits(priv, RTC7301_CONTROL, RTC7301_CONTROL_STOP, 0);
1150b6a8f5cSAkinobu Mita }
1160b6a8f5cSAkinobu Mita 
rtc7301_select_bank(struct rtc7301_priv * priv,u8 bank)1170b6a8f5cSAkinobu Mita static void rtc7301_select_bank(struct rtc7301_priv *priv, u8 bank)
1180b6a8f5cSAkinobu Mita {
1190b6a8f5cSAkinobu Mita 	u8 val = 0;
1200b6a8f5cSAkinobu Mita 
1210b6a8f5cSAkinobu Mita 	if (bank == priv->bank)
1220b6a8f5cSAkinobu Mita 		return;
1230b6a8f5cSAkinobu Mita 
1240b6a8f5cSAkinobu Mita 	if (bank & BIT(0))
1250b6a8f5cSAkinobu Mita 		val |= RTC7301_CONTROL_BANK_SEL_0;
1260b6a8f5cSAkinobu Mita 	if (bank & BIT(1))
1270b6a8f5cSAkinobu Mita 		val |= RTC7301_CONTROL_BANK_SEL_1;
1280b6a8f5cSAkinobu Mita 
1290b6a8f5cSAkinobu Mita 	rtc7301_update_bits(priv, RTC7301_CONTROL,
1300b6a8f5cSAkinobu Mita 			    RTC7301_CONTROL_BANK_SEL_0 |
1310b6a8f5cSAkinobu Mita 			    RTC7301_CONTROL_BANK_SEL_1, val);
1320b6a8f5cSAkinobu Mita 
1330b6a8f5cSAkinobu Mita 	priv->bank = bank;
1340b6a8f5cSAkinobu Mita }
1350b6a8f5cSAkinobu Mita 
rtc7301_get_time(struct rtc7301_priv * priv,struct rtc_time * tm,bool alarm)1360b6a8f5cSAkinobu Mita static void rtc7301_get_time(struct rtc7301_priv *priv, struct rtc_time *tm,
1370b6a8f5cSAkinobu Mita 			     bool alarm)
1380b6a8f5cSAkinobu Mita {
1390b6a8f5cSAkinobu Mita 	int year;
1400b6a8f5cSAkinobu Mita 
1410b6a8f5cSAkinobu Mita 	tm->tm_sec = rtc7301_read(priv, RTC7301_1_SEC);
1420b6a8f5cSAkinobu Mita 	tm->tm_sec += (rtc7301_read(priv, RTC7301_10_SEC) & ~RTC7301_AE) * 10;
1430b6a8f5cSAkinobu Mita 	tm->tm_min = rtc7301_read(priv, RTC7301_1_MIN);
1440b6a8f5cSAkinobu Mita 	tm->tm_min += (rtc7301_read(priv, RTC7301_10_MIN) & ~RTC7301_AE) * 10;
1450b6a8f5cSAkinobu Mita 	tm->tm_hour = rtc7301_read(priv, RTC7301_1_HOUR);
1460b6a8f5cSAkinobu Mita 	tm->tm_hour += (rtc7301_read(priv, RTC7301_10_HOUR) & ~RTC7301_AE) * 10;
1470b6a8f5cSAkinobu Mita 	tm->tm_mday = rtc7301_read(priv, RTC7301_1_DAY);
1480b6a8f5cSAkinobu Mita 	tm->tm_mday += (rtc7301_read(priv, RTC7301_10_DAY) & ~RTC7301_AE) * 10;
1490b6a8f5cSAkinobu Mita 
1500b6a8f5cSAkinobu Mita 	if (alarm) {
1510b6a8f5cSAkinobu Mita 		tm->tm_wday = -1;
1520b6a8f5cSAkinobu Mita 		tm->tm_mon = -1;
1530b6a8f5cSAkinobu Mita 		tm->tm_year = -1;
1540b6a8f5cSAkinobu Mita 		tm->tm_yday = -1;
1550b6a8f5cSAkinobu Mita 		tm->tm_isdst = -1;
1560b6a8f5cSAkinobu Mita 		return;
1570b6a8f5cSAkinobu Mita 	}
1580b6a8f5cSAkinobu Mita 
1590b6a8f5cSAkinobu Mita 	tm->tm_wday = (rtc7301_read(priv, RTC7301_DAY_OF_WEEK) & ~RTC7301_AE);
1600b6a8f5cSAkinobu Mita 	tm->tm_mon = rtc7301_read(priv, RTC7301_10_MONTH) * 10 +
1610b6a8f5cSAkinobu Mita 		     rtc7301_read(priv, RTC7301_1_MONTH) - 1;
1620b6a8f5cSAkinobu Mita 	year = rtc7301_read(priv, RTC7301_1000_YEAR) * 1000 +
1630b6a8f5cSAkinobu Mita 	       rtc7301_read(priv, RTC7301_100_YEAR) * 100 +
1640b6a8f5cSAkinobu Mita 	       rtc7301_read(priv, RTC7301_10_YEAR) * 10 +
1650b6a8f5cSAkinobu Mita 	       rtc7301_read(priv, RTC7301_1_YEAR);
1660b6a8f5cSAkinobu Mita 
1670b6a8f5cSAkinobu Mita 	tm->tm_year = year - 1900;
1680b6a8f5cSAkinobu Mita }
1690b6a8f5cSAkinobu Mita 
rtc7301_write_time(struct rtc7301_priv * priv,struct rtc_time * tm,bool alarm)1700b6a8f5cSAkinobu Mita static void rtc7301_write_time(struct rtc7301_priv *priv, struct rtc_time *tm,
1710b6a8f5cSAkinobu Mita 			       bool alarm)
1720b6a8f5cSAkinobu Mita {
1730b6a8f5cSAkinobu Mita 	int year;
1740b6a8f5cSAkinobu Mita 
1750b6a8f5cSAkinobu Mita 	rtc7301_write(priv, tm->tm_sec % 10, RTC7301_1_SEC);
1760b6a8f5cSAkinobu Mita 	rtc7301_write(priv, tm->tm_sec / 10, RTC7301_10_SEC);
1770b6a8f5cSAkinobu Mita 
1780b6a8f5cSAkinobu Mita 	rtc7301_write(priv, tm->tm_min % 10, RTC7301_1_MIN);
1790b6a8f5cSAkinobu Mita 	rtc7301_write(priv, tm->tm_min / 10, RTC7301_10_MIN);
1800b6a8f5cSAkinobu Mita 
1810b6a8f5cSAkinobu Mita 	rtc7301_write(priv, tm->tm_hour % 10, RTC7301_1_HOUR);
1820b6a8f5cSAkinobu Mita 	rtc7301_write(priv, tm->tm_hour / 10, RTC7301_10_HOUR);
1830b6a8f5cSAkinobu Mita 
1840b6a8f5cSAkinobu Mita 	rtc7301_write(priv, tm->tm_mday % 10, RTC7301_1_DAY);
1850b6a8f5cSAkinobu Mita 	rtc7301_write(priv, tm->tm_mday / 10, RTC7301_10_DAY);
1860b6a8f5cSAkinobu Mita 
1870b6a8f5cSAkinobu Mita 	/* Don't care for alarm register */
1880b6a8f5cSAkinobu Mita 	rtc7301_write(priv, alarm ? RTC7301_AE : tm->tm_wday,
1890b6a8f5cSAkinobu Mita 		      RTC7301_DAY_OF_WEEK);
1900b6a8f5cSAkinobu Mita 
1910b6a8f5cSAkinobu Mita 	if (alarm)
1920b6a8f5cSAkinobu Mita 		return;
1930b6a8f5cSAkinobu Mita 
1940b6a8f5cSAkinobu Mita 	rtc7301_write(priv, (tm->tm_mon + 1) % 10, RTC7301_1_MONTH);
1950b6a8f5cSAkinobu Mita 	rtc7301_write(priv, (tm->tm_mon + 1) / 10, RTC7301_10_MONTH);
1960b6a8f5cSAkinobu Mita 
1970b6a8f5cSAkinobu Mita 	year = tm->tm_year + 1900;
1980b6a8f5cSAkinobu Mita 
1990b6a8f5cSAkinobu Mita 	rtc7301_write(priv, year % 10, RTC7301_1_YEAR);
2000b6a8f5cSAkinobu Mita 	rtc7301_write(priv, (year / 10) % 10, RTC7301_10_YEAR);
2010b6a8f5cSAkinobu Mita 	rtc7301_write(priv, (year / 100) % 10, RTC7301_100_YEAR);
2020b6a8f5cSAkinobu Mita 	rtc7301_write(priv, year / 1000, RTC7301_1000_YEAR);
2030b6a8f5cSAkinobu Mita }
2040b6a8f5cSAkinobu Mita 
rtc7301_alarm_irq(struct rtc7301_priv * priv,unsigned int enabled)2050b6a8f5cSAkinobu Mita static void rtc7301_alarm_irq(struct rtc7301_priv *priv, unsigned int enabled)
2060b6a8f5cSAkinobu Mita {
2070b6a8f5cSAkinobu Mita 	rtc7301_update_bits(priv, RTC7301_ALARM_CONTROL,
2080b6a8f5cSAkinobu Mita 			    RTC7301_ALARM_CONTROL_AF |
2090b6a8f5cSAkinobu Mita 			    RTC7301_ALARM_CONTROL_AIE,
2100b6a8f5cSAkinobu Mita 			    enabled ? RTC7301_ALARM_CONTROL_AIE : 0);
2110b6a8f5cSAkinobu Mita }
2120b6a8f5cSAkinobu Mita 
rtc7301_read_time(struct device * dev,struct rtc_time * tm)2130b6a8f5cSAkinobu Mita static int rtc7301_read_time(struct device *dev, struct rtc_time *tm)
2140b6a8f5cSAkinobu Mita {
2150b6a8f5cSAkinobu Mita 	struct rtc7301_priv *priv = dev_get_drvdata(dev);
2160b6a8f5cSAkinobu Mita 	unsigned long flags;
2170b6a8f5cSAkinobu Mita 	int err;
2180b6a8f5cSAkinobu Mita 
2190b6a8f5cSAkinobu Mita 	spin_lock_irqsave(&priv->lock, flags);
2200b6a8f5cSAkinobu Mita 
2210b6a8f5cSAkinobu Mita 	rtc7301_select_bank(priv, 0);
2220b6a8f5cSAkinobu Mita 
2230b6a8f5cSAkinobu Mita 	err = rtc7301_wait_while_busy(priv);
2240b6a8f5cSAkinobu Mita 	if (!err)
2250b6a8f5cSAkinobu Mita 		rtc7301_get_time(priv, tm, false);
2260b6a8f5cSAkinobu Mita 
2270b6a8f5cSAkinobu Mita 	spin_unlock_irqrestore(&priv->lock, flags);
2280b6a8f5cSAkinobu Mita 
22950a9a35aSAlexandre Belloni 	return err;
2300b6a8f5cSAkinobu Mita }
2310b6a8f5cSAkinobu Mita 
rtc7301_set_time(struct device * dev,struct rtc_time * tm)2320b6a8f5cSAkinobu Mita static int rtc7301_set_time(struct device *dev, struct rtc_time *tm)
2330b6a8f5cSAkinobu Mita {
2340b6a8f5cSAkinobu Mita 	struct rtc7301_priv *priv = dev_get_drvdata(dev);
2350b6a8f5cSAkinobu Mita 	unsigned long flags;
2360b6a8f5cSAkinobu Mita 
2370b6a8f5cSAkinobu Mita 	spin_lock_irqsave(&priv->lock, flags);
2380b6a8f5cSAkinobu Mita 
2390b6a8f5cSAkinobu Mita 	rtc7301_stop(priv);
240298c8545SJia-Ju Bai 	udelay(300);
2410b6a8f5cSAkinobu Mita 	rtc7301_select_bank(priv, 0);
2420b6a8f5cSAkinobu Mita 	rtc7301_write_time(priv, tm, false);
2430b6a8f5cSAkinobu Mita 	rtc7301_start(priv);
2440b6a8f5cSAkinobu Mita 
2450b6a8f5cSAkinobu Mita 	spin_unlock_irqrestore(&priv->lock, flags);
2460b6a8f5cSAkinobu Mita 
2470b6a8f5cSAkinobu Mita 	return 0;
2480b6a8f5cSAkinobu Mita }
2490b6a8f5cSAkinobu Mita 
rtc7301_read_alarm(struct device * dev,struct rtc_wkalrm * alarm)2500b6a8f5cSAkinobu Mita static int rtc7301_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
2510b6a8f5cSAkinobu Mita {
2520b6a8f5cSAkinobu Mita 	struct rtc7301_priv *priv = dev_get_drvdata(dev);
2530b6a8f5cSAkinobu Mita 	unsigned long flags;
2540b6a8f5cSAkinobu Mita 	u8 alrm_ctrl;
2550b6a8f5cSAkinobu Mita 
2560b6a8f5cSAkinobu Mita 	if (priv->irq <= 0)
2570b6a8f5cSAkinobu Mita 		return -EINVAL;
2580b6a8f5cSAkinobu Mita 
2590b6a8f5cSAkinobu Mita 	spin_lock_irqsave(&priv->lock, flags);
2600b6a8f5cSAkinobu Mita 
2610b6a8f5cSAkinobu Mita 	rtc7301_select_bank(priv, 1);
2620b6a8f5cSAkinobu Mita 	rtc7301_get_time(priv, &alarm->time, true);
2630b6a8f5cSAkinobu Mita 
2640b6a8f5cSAkinobu Mita 	alrm_ctrl = rtc7301_read(priv, RTC7301_ALARM_CONTROL);
2650b6a8f5cSAkinobu Mita 
2660b6a8f5cSAkinobu Mita 	alarm->enabled = !!(alrm_ctrl & RTC7301_ALARM_CONTROL_AIE);
2670b6a8f5cSAkinobu Mita 	alarm->pending = !!(alrm_ctrl & RTC7301_ALARM_CONTROL_AF);
2680b6a8f5cSAkinobu Mita 
2690b6a8f5cSAkinobu Mita 	spin_unlock_irqrestore(&priv->lock, flags);
2700b6a8f5cSAkinobu Mita 
2710b6a8f5cSAkinobu Mita 	return 0;
2720b6a8f5cSAkinobu Mita }
2730b6a8f5cSAkinobu Mita 
rtc7301_set_alarm(struct device * dev,struct rtc_wkalrm * alarm)2740b6a8f5cSAkinobu Mita static int rtc7301_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
2750b6a8f5cSAkinobu Mita {
2760b6a8f5cSAkinobu Mita 	struct rtc7301_priv *priv = dev_get_drvdata(dev);
2770b6a8f5cSAkinobu Mita 	unsigned long flags;
2780b6a8f5cSAkinobu Mita 
2790b6a8f5cSAkinobu Mita 	if (priv->irq <= 0)
2800b6a8f5cSAkinobu Mita 		return -EINVAL;
2810b6a8f5cSAkinobu Mita 
2820b6a8f5cSAkinobu Mita 	spin_lock_irqsave(&priv->lock, flags);
2830b6a8f5cSAkinobu Mita 
2840b6a8f5cSAkinobu Mita 	rtc7301_select_bank(priv, 1);
2850b6a8f5cSAkinobu Mita 	rtc7301_write_time(priv, &alarm->time, true);
2860b6a8f5cSAkinobu Mita 	rtc7301_alarm_irq(priv, alarm->enabled);
2870b6a8f5cSAkinobu Mita 
2880b6a8f5cSAkinobu Mita 	spin_unlock_irqrestore(&priv->lock, flags);
2890b6a8f5cSAkinobu Mita 
2900b6a8f5cSAkinobu Mita 	return 0;
2910b6a8f5cSAkinobu Mita }
2920b6a8f5cSAkinobu Mita 
rtc7301_alarm_irq_enable(struct device * dev,unsigned int enabled)2930b6a8f5cSAkinobu Mita static int rtc7301_alarm_irq_enable(struct device *dev, unsigned int enabled)
2940b6a8f5cSAkinobu Mita {
2950b6a8f5cSAkinobu Mita 	struct rtc7301_priv *priv = dev_get_drvdata(dev);
2960b6a8f5cSAkinobu Mita 	unsigned long flags;
2970b6a8f5cSAkinobu Mita 
2980b6a8f5cSAkinobu Mita 	if (priv->irq <= 0)
2990b6a8f5cSAkinobu Mita 		return -EINVAL;
3000b6a8f5cSAkinobu Mita 
3010b6a8f5cSAkinobu Mita 	spin_lock_irqsave(&priv->lock, flags);
3020b6a8f5cSAkinobu Mita 
3030b6a8f5cSAkinobu Mita 	rtc7301_select_bank(priv, 1);
3040b6a8f5cSAkinobu Mita 	rtc7301_alarm_irq(priv, enabled);
3050b6a8f5cSAkinobu Mita 
3060b6a8f5cSAkinobu Mita 	spin_unlock_irqrestore(&priv->lock, flags);
3070b6a8f5cSAkinobu Mita 
3080b6a8f5cSAkinobu Mita 	return 0;
3090b6a8f5cSAkinobu Mita }
3100b6a8f5cSAkinobu Mita 
3110b6a8f5cSAkinobu Mita static const struct rtc_class_ops rtc7301_rtc_ops = {
3120b6a8f5cSAkinobu Mita 	.read_time	= rtc7301_read_time,
3130b6a8f5cSAkinobu Mita 	.set_time	= rtc7301_set_time,
3140b6a8f5cSAkinobu Mita 	.read_alarm	= rtc7301_read_alarm,
3150b6a8f5cSAkinobu Mita 	.set_alarm	= rtc7301_set_alarm,
3160b6a8f5cSAkinobu Mita 	.alarm_irq_enable = rtc7301_alarm_irq_enable,
3170b6a8f5cSAkinobu Mita };
3180b6a8f5cSAkinobu Mita 
rtc7301_irq_handler(int irq,void * dev_id)3190b6a8f5cSAkinobu Mita static irqreturn_t rtc7301_irq_handler(int irq, void *dev_id)
3200b6a8f5cSAkinobu Mita {
3210b6a8f5cSAkinobu Mita 	struct rtc_device *rtc = dev_id;
3220b6a8f5cSAkinobu Mita 	struct rtc7301_priv *priv = dev_get_drvdata(rtc->dev.parent);
3230b6a8f5cSAkinobu Mita 	irqreturn_t ret = IRQ_NONE;
3240b6a8f5cSAkinobu Mita 	u8 alrm_ctrl;
3250b6a8f5cSAkinobu Mita 
326*be3df3f8SXiaofei Tan 	spin_lock(&priv->lock);
3270b6a8f5cSAkinobu Mita 
3280b6a8f5cSAkinobu Mita 	rtc7301_select_bank(priv, 1);
3290b6a8f5cSAkinobu Mita 
3300b6a8f5cSAkinobu Mita 	alrm_ctrl = rtc7301_read(priv, RTC7301_ALARM_CONTROL);
3310b6a8f5cSAkinobu Mita 	if (alrm_ctrl & RTC7301_ALARM_CONTROL_AF) {
3320b6a8f5cSAkinobu Mita 		ret = IRQ_HANDLED;
3330b6a8f5cSAkinobu Mita 		rtc7301_alarm_irq(priv, false);
3340b6a8f5cSAkinobu Mita 		rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
3350b6a8f5cSAkinobu Mita 	}
3360b6a8f5cSAkinobu Mita 
337*be3df3f8SXiaofei Tan 	spin_unlock(&priv->lock);
3380b6a8f5cSAkinobu Mita 
3390b6a8f5cSAkinobu Mita 	return ret;
3400b6a8f5cSAkinobu Mita }
3410b6a8f5cSAkinobu Mita 
rtc7301_init(struct rtc7301_priv * priv)3420b6a8f5cSAkinobu Mita static void rtc7301_init(struct rtc7301_priv *priv)
3430b6a8f5cSAkinobu Mita {
3440b6a8f5cSAkinobu Mita 	unsigned long flags;
3450b6a8f5cSAkinobu Mita 
3460b6a8f5cSAkinobu Mita 	spin_lock_irqsave(&priv->lock, flags);
3470b6a8f5cSAkinobu Mita 
3480b6a8f5cSAkinobu Mita 	rtc7301_select_bank(priv, 2);
3490b6a8f5cSAkinobu Mita 	rtc7301_write(priv, 0, RTC7301_TIMER_CONTROL);
3500b6a8f5cSAkinobu Mita 
3510b6a8f5cSAkinobu Mita 	spin_unlock_irqrestore(&priv->lock, flags);
3520b6a8f5cSAkinobu Mita }
3530b6a8f5cSAkinobu Mita 
rtc7301_rtc_probe(struct platform_device * dev)3540b6a8f5cSAkinobu Mita static int __init rtc7301_rtc_probe(struct platform_device *dev)
3550b6a8f5cSAkinobu Mita {
3560b6a8f5cSAkinobu Mita 	void __iomem *regs;
3570b6a8f5cSAkinobu Mita 	struct rtc7301_priv *priv;
3580b6a8f5cSAkinobu Mita 	struct rtc_device *rtc;
3590b6a8f5cSAkinobu Mita 	int ret;
3600b6a8f5cSAkinobu Mita 
3610b6a8f5cSAkinobu Mita 	priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
3620b6a8f5cSAkinobu Mita 	if (!priv)
3630b6a8f5cSAkinobu Mita 		return -ENOMEM;
3640b6a8f5cSAkinobu Mita 
36589576bebSMarkus Elfring 	regs = devm_platform_ioremap_resource(dev, 0);
3660b6a8f5cSAkinobu Mita 	if (IS_ERR(regs))
3670b6a8f5cSAkinobu Mita 		return PTR_ERR(regs);
3680b6a8f5cSAkinobu Mita 
3690b6a8f5cSAkinobu Mita 	priv->regmap = devm_regmap_init_mmio(&dev->dev, regs,
3700b6a8f5cSAkinobu Mita 					     &rtc7301_regmap_config);
3710b6a8f5cSAkinobu Mita 	if (IS_ERR(priv->regmap))
3720b6a8f5cSAkinobu Mita 		return PTR_ERR(priv->regmap);
3730b6a8f5cSAkinobu Mita 
3740b6a8f5cSAkinobu Mita 	priv->irq = platform_get_irq(dev, 0);
3750b6a8f5cSAkinobu Mita 
3760b6a8f5cSAkinobu Mita 	spin_lock_init(&priv->lock);
3770b6a8f5cSAkinobu Mita 	priv->bank = -1;
3780b6a8f5cSAkinobu Mita 
3790b6a8f5cSAkinobu Mita 	rtc7301_init(priv);
3800b6a8f5cSAkinobu Mita 
3810b6a8f5cSAkinobu Mita 	platform_set_drvdata(dev, priv);
3820b6a8f5cSAkinobu Mita 
3830b6a8f5cSAkinobu Mita 	rtc = devm_rtc_device_register(&dev->dev, DRV_NAME, &rtc7301_rtc_ops,
3840b6a8f5cSAkinobu Mita 				       THIS_MODULE);
3850b6a8f5cSAkinobu Mita 	if (IS_ERR(rtc))
3860b6a8f5cSAkinobu Mita 		return PTR_ERR(rtc);
3870b6a8f5cSAkinobu Mita 
3880b6a8f5cSAkinobu Mita 	if (priv->irq > 0) {
3890b6a8f5cSAkinobu Mita 		ret = devm_request_irq(&dev->dev, priv->irq,
3900b6a8f5cSAkinobu Mita 				       rtc7301_irq_handler, IRQF_SHARED,
3910b6a8f5cSAkinobu Mita 				       dev_name(&dev->dev), rtc);
3920b6a8f5cSAkinobu Mita 		if (ret) {
3930b6a8f5cSAkinobu Mita 			priv->irq = 0;
3940b6a8f5cSAkinobu Mita 			dev_err(&dev->dev, "unable to request IRQ\n");
3950b6a8f5cSAkinobu Mita 		} else {
3960b6a8f5cSAkinobu Mita 			device_set_wakeup_capable(&dev->dev, true);
3970b6a8f5cSAkinobu Mita 		}
3980b6a8f5cSAkinobu Mita 	}
3990b6a8f5cSAkinobu Mita 
4000b6a8f5cSAkinobu Mita 	return 0;
4010b6a8f5cSAkinobu Mita }
4020b6a8f5cSAkinobu Mita 
4030b6a8f5cSAkinobu Mita #ifdef CONFIG_PM_SLEEP
4040b6a8f5cSAkinobu Mita 
rtc7301_suspend(struct device * dev)4050b6a8f5cSAkinobu Mita static int rtc7301_suspend(struct device *dev)
4060b6a8f5cSAkinobu Mita {
4070b6a8f5cSAkinobu Mita 	struct rtc7301_priv *priv = dev_get_drvdata(dev);
4080b6a8f5cSAkinobu Mita 
4090b6a8f5cSAkinobu Mita 	if (device_may_wakeup(dev))
4100b6a8f5cSAkinobu Mita 		enable_irq_wake(priv->irq);
4110b6a8f5cSAkinobu Mita 
4120b6a8f5cSAkinobu Mita 	return 0;
4130b6a8f5cSAkinobu Mita }
4140b6a8f5cSAkinobu Mita 
rtc7301_resume(struct device * dev)4150b6a8f5cSAkinobu Mita static int rtc7301_resume(struct device *dev)
4160b6a8f5cSAkinobu Mita {
4170b6a8f5cSAkinobu Mita 	struct rtc7301_priv *priv = dev_get_drvdata(dev);
4180b6a8f5cSAkinobu Mita 
4190b6a8f5cSAkinobu Mita 	if (device_may_wakeup(dev))
4200b6a8f5cSAkinobu Mita 		disable_irq_wake(priv->irq);
4210b6a8f5cSAkinobu Mita 
4220b6a8f5cSAkinobu Mita 	return 0;
4230b6a8f5cSAkinobu Mita }
4240b6a8f5cSAkinobu Mita 
4250b6a8f5cSAkinobu Mita #endif
4260b6a8f5cSAkinobu Mita 
4270b6a8f5cSAkinobu Mita static SIMPLE_DEV_PM_OPS(rtc7301_pm_ops, rtc7301_suspend, rtc7301_resume);
4280b6a8f5cSAkinobu Mita 
4290b6a8f5cSAkinobu Mita static const struct of_device_id rtc7301_dt_match[] = {
4300b6a8f5cSAkinobu Mita 	{ .compatible = "epson,rtc7301sf" },
4310b6a8f5cSAkinobu Mita 	{ .compatible = "epson,rtc7301dg" },
4320b6a8f5cSAkinobu Mita 	{}
4330b6a8f5cSAkinobu Mita };
4340b6a8f5cSAkinobu Mita MODULE_DEVICE_TABLE(of, rtc7301_dt_match);
4350b6a8f5cSAkinobu Mita 
4360b6a8f5cSAkinobu Mita static struct platform_driver rtc7301_rtc_driver = {
4370b6a8f5cSAkinobu Mita 	.driver	= {
4380b6a8f5cSAkinobu Mita 		.name = DRV_NAME,
4390b6a8f5cSAkinobu Mita 		.of_match_table = rtc7301_dt_match,
4400b6a8f5cSAkinobu Mita 		.pm = &rtc7301_pm_ops,
4410b6a8f5cSAkinobu Mita 	},
4420b6a8f5cSAkinobu Mita };
4430b6a8f5cSAkinobu Mita 
4440b6a8f5cSAkinobu Mita module_platform_driver_probe(rtc7301_rtc_driver, rtc7301_rtc_probe);
4450b6a8f5cSAkinobu Mita 
4460b6a8f5cSAkinobu Mita MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
4470b6a8f5cSAkinobu Mita MODULE_LICENSE("GPL");
4480b6a8f5cSAkinobu Mita MODULE_DESCRIPTION("EPSON TOYOCOM RTC-7301SF/DG Driver");
4490b6a8f5cSAkinobu Mita MODULE_ALIAS("platform:rtc-r7301");
450