^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 rtc driver for the Dallas DS1511
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2007 Andrew Sharp <andy.sharp@lsi.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Real time clock driver for the Dallas 1511 chip, which also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * contains a watchdog timer. There is a tiny amount of code that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * platform code could use to mess with the watchdog device a little
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * bit, but not a full watchdog driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/bcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) enum ds1511reg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) DS1511_SEC = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) DS1511_MIN = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) DS1511_HOUR = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) DS1511_DOW = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) DS1511_DOM = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) DS1511_MONTH = 0x5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) DS1511_YEAR = 0x6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) DS1511_CENTURY = 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) DS1511_AM1_SEC = 0x8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) DS1511_AM2_MIN = 0x9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) DS1511_AM3_HOUR = 0xa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) DS1511_AM4_DATE = 0xb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) DS1511_WD_MSEC = 0xc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) DS1511_WD_SEC = 0xd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) DS1511_CONTROL_A = 0xe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) DS1511_CONTROL_B = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) DS1511_RAMADDR_LSB = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) DS1511_RAMDATA = 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define DS1511_BLF1 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DS1511_BLF2 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DS1511_PRS 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define DS1511_PAB 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define DS1511_TDF 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define DS1511_KSF 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define DS1511_WDF 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define DS1511_IRQF 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define DS1511_TE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define DS1511_CS 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define DS1511_BME 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define DS1511_TPE 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define DS1511_TIE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define DS1511_KIE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define DS1511_WDE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define DS1511_WDS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define DS1511_RAM_MAX 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define RTC_CMD DS1511_CONTROL_B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define RTC_CMD1 DS1511_CONTROL_A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define RTC_ALARM_SEC DS1511_AM1_SEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define RTC_ALARM_MIN DS1511_AM2_MIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define RTC_ALARM_HOUR DS1511_AM3_HOUR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define RTC_ALARM_DATE DS1511_AM4_DATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define RTC_SEC DS1511_SEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define RTC_MIN DS1511_MIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define RTC_HOUR DS1511_HOUR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define RTC_DOW DS1511_DOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define RTC_DOM DS1511_DOM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define RTC_MON DS1511_MONTH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define RTC_YEAR DS1511_YEAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define RTC_CENTURY DS1511_CENTURY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define RTC_TIE DS1511_TIE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define RTC_TE DS1511_TE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct rtc_plat_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct rtc_device *rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) void __iomem *ioaddr; /* virtual base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) unsigned int irqen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int alrm_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int alrm_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int alrm_hour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int alrm_mday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static DEFINE_SPINLOCK(ds1511_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static __iomem char *ds1511_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static u32 reg_spacing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static noinline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) rtc_write(uint8_t val, uint32_t reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) writeb(val, ds1511_base + (reg * reg_spacing));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) rtc_write_alarm(uint8_t val, enum ds1511reg reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) rtc_write((val | 0x80), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static noinline uint8_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) rtc_read(enum ds1511reg reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return readb(ds1511_base + (reg * reg_spacing));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) rtc_disable_update(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) rtc_enable_update(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * #define DS1511_WDOG_RESET_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * Uncomment this if you want to use these routines in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * some platform code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #ifdef DS1511_WDOG_RESET_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * just enough code to set the watchdog timer so that it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * will reboot the system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ds1511_wdog_set(unsigned long deciseconds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * the wdog timer can take 99.99 seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) deciseconds %= 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * set the wdog values in the wdog registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) rtc_write(bin2bcd(deciseconds % 100), DS1511_WD_MSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) rtc_write(bin2bcd(deciseconds / 100), DS1511_WD_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * set wdog enable and wdog 'steering' bit to issue a reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) rtc_write(rtc_read(RTC_CMD) | DS1511_WDE | DS1511_WDS, RTC_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ds1511_wdog_disable(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * clear wdog enable and wdog 'steering' bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) rtc_write(rtc_read(RTC_CMD) & ~(DS1511_WDE | DS1511_WDS), RTC_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * clear the wdog counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) rtc_write(0, DS1511_WD_MSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) rtc_write(0, DS1511_WD_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * set the rtc chip's idea of the time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * stupidly, some callers call with year unmolested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * and some call with year = year - 1900. thanks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) u8 mon, day, dow, hrs, min, sec, yrs, cen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * won't have to change this for a while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (rtc_tm->tm_year < 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) rtc_tm->tm_year += 1900;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (rtc_tm->tm_year < 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) yrs = rtc_tm->tm_year % 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) cen = rtc_tm->tm_year / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) day = rtc_tm->tm_mday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dow = rtc_tm->tm_wday & 0x7; /* automatic BCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) hrs = rtc_tm->tm_hour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) min = rtc_tm->tm_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) sec = rtc_tm->tm_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if ((mon > 12) || (day == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if ((hrs >= 24) || (min >= 60) || (sec >= 60))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * each register is a different number of valid bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) sec = bin2bcd(sec) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) min = bin2bcd(min) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) hrs = bin2bcd(hrs) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) day = bin2bcd(day) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) mon = bin2bcd(mon) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) yrs = bin2bcd(yrs) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) cen = bin2bcd(cen) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) spin_lock_irqsave(&ds1511_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) rtc_disable_update();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) rtc_write(cen, RTC_CENTURY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) rtc_write(yrs, RTC_YEAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) rtc_write((rtc_read(RTC_MON) & 0xe0) | mon, RTC_MON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) rtc_write(day, RTC_DOM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) rtc_write(hrs, RTC_HOUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) rtc_write(min, RTC_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) rtc_write(sec, RTC_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) rtc_write(dow, RTC_DOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) rtc_enable_update();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) spin_unlock_irqrestore(&ds1511_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) unsigned int century;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) spin_lock_irqsave(&ds1511_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) rtc_disable_update();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) rtc_tm->tm_sec = rtc_read(RTC_SEC) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) rtc_tm->tm_min = rtc_read(RTC_MIN) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) rtc_tm->tm_hour = rtc_read(RTC_HOUR) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) rtc_tm->tm_mday = rtc_read(RTC_DOM) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) rtc_tm->tm_wday = rtc_read(RTC_DOW) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) rtc_tm->tm_mon = rtc_read(RTC_MON) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) rtc_tm->tm_year = rtc_read(RTC_YEAR) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) century = rtc_read(RTC_CENTURY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) rtc_enable_update();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) spin_unlock_irqrestore(&ds1511_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) rtc_tm->tm_wday = bcd2bin(rtc_tm->tm_wday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) century = bcd2bin(century) * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * Account for differences between how the RTC uses the values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * and how they are defined in a struct rtc_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) century += rtc_tm->tm_year;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) rtc_tm->tm_year = century - 1900;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) rtc_tm->tm_mon--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * write the alarm register settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * we only have the use to interrupt every second, otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * known as the update interrupt, or the interrupt if the whole
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * date/hours/mins/secs matches. the ds1511 has many more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * permutations, but the kernel doesn't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ds1511_rtc_update_alarm(struct rtc_plat_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) spin_lock_irqsave(&pdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) rtc_write(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 0x80 : bin2bcd(pdata->alrm_mday) & 0x3f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) RTC_ALARM_DATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) rtc_write(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 0x80 : bin2bcd(pdata->alrm_hour) & 0x3f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) RTC_ALARM_HOUR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) rtc_write(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 0x80 : bin2bcd(pdata->alrm_min) & 0x7f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) RTC_ALARM_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) rtc_write(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 0x80 : bin2bcd(pdata->alrm_sec) & 0x7f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) RTC_ALARM_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) rtc_write(rtc_read(RTC_CMD) | (pdata->irqen ? RTC_TIE : 0), RTC_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) rtc_read(RTC_CMD1); /* clear interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) spin_unlock_irqrestore(&pdata->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct rtc_plat_data *pdata = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (pdata->irq <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) pdata->alrm_mday = alrm->time.tm_mday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) pdata->alrm_hour = alrm->time.tm_hour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pdata->alrm_min = alrm->time.tm_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) pdata->alrm_sec = alrm->time.tm_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (alrm->enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) pdata->irqen |= RTC_AF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ds1511_rtc_update_alarm(pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct rtc_plat_data *pdata = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (pdata->irq <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) alrm->time.tm_sec = pdata->alrm_sec < 0 ? 0 : pdata->alrm_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) alrm->enabled = (pdata->irqen & RTC_AF) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ds1511_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct platform_device *pdev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) unsigned long events = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) spin_lock(&pdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * read and clear interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (rtc_read(RTC_CMD1) & DS1511_IRQF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) events = RTC_IRQF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (rtc_read(RTC_ALARM_SEC) & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) events |= RTC_UF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) events |= RTC_AF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) rtc_update_irq(pdata->rtc, 1, events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) spin_unlock(&pdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return events ? IRQ_HANDLED : IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static int ds1511_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct rtc_plat_data *pdata = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (pdata->irq <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) pdata->irqen |= RTC_AF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) pdata->irqen &= ~RTC_AF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) ds1511_rtc_update_alarm(pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static const struct rtc_class_ops ds1511_rtc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .read_time = ds1511_rtc_read_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .set_time = ds1511_rtc_set_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .read_alarm = ds1511_rtc_read_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .set_alarm = ds1511_rtc_set_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .alarm_irq_enable = ds1511_rtc_alarm_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static int ds1511_nvram_read(void *priv, unsigned int pos, void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) rtc_write(pos, DS1511_RAMADDR_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) *(char *)buf++ = rtc_read(DS1511_RAMDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int ds1511_nvram_write(void *priv, unsigned int pos, void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) rtc_write(pos, DS1511_RAMADDR_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) rtc_write(*(char *)buf++, DS1511_RAMDATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int ds1511_rtc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct rtc_plat_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct nvmem_config ds1511_nvmem_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) .name = "ds1511_nvram",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) .word_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .stride = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .size = DS1511_RAM_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .reg_read = ds1511_nvram_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .reg_write = ds1511_nvram_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .priv = &pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ds1511_base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (IS_ERR(ds1511_base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return PTR_ERR(ds1511_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) pdata->ioaddr = ds1511_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) pdata->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * turn on the clock and the crystal, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) rtc_write(DS1511_BME, RTC_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) rtc_write(0, RTC_CMD1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * clear the wdog counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) rtc_write(0, DS1511_WD_MSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) rtc_write(0, DS1511_WD_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * start the clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) rtc_enable_update();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * check for a dying bat-tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (rtc_read(RTC_CMD1) & DS1511_BLF1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dev_warn(&pdev->dev, "voltage-low detected.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) spin_lock_init(&pdata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) platform_set_drvdata(pdev, pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (IS_ERR(pdata->rtc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return PTR_ERR(pdata->rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) pdata->rtc->ops = &ds1511_rtc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) pdata->rtc->nvram_old_abi = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ret = rtc_register_device(pdata->rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) rtc_nvmem_register(pdata->rtc, &ds1511_nvmem_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * if the platform has an interrupt in mind for this device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * then by all means, set it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (pdata->irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) rtc_read(RTC_CMD1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) IRQF_SHARED, pdev->name, pdev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) dev_warn(&pdev->dev, "interrupt not available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) pdata->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return 0;
^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) /* work with hotplug and coldplug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) MODULE_ALIAS("platform:ds1511");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static struct platform_driver ds1511_rtc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .probe = ds1511_rtc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) .name = "ds1511",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) module_platform_driver(ds1511_rtc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) MODULE_DESCRIPTION("Dallas DS1511 RTC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) MODULE_LICENSE("GPL");