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