^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) * Haoyu HYM8563 RTC driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2013 MundoReader S.L.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Heiko Stuebner <heiko@sntech.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * based on rtc-HYM8563
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2010 ROCKCHIP, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/bcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define HYM8563_CTL1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define HYM8563_CTL1_TEST BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define HYM8563_CTL1_STOP BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define HYM8563_CTL1_TESTC BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define HYM8563_CTL2 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define HYM8563_CTL2_TI_TP BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define HYM8563_CTL2_AF BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define HYM8563_CTL2_TF BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define HYM8563_CTL2_AIE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define HYM8563_CTL2_TIE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define HYM8563_SEC 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define HYM8563_SEC_VL BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define HYM8563_SEC_MASK 0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define HYM8563_MIN 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define HYM8563_MIN_MASK 0x7f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define HYM8563_HOUR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define HYM8563_HOUR_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define HYM8563_DAY 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define HYM8563_DAY_MASK 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define HYM8563_WEEKDAY 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define HYM8563_WEEKDAY_MASK 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define HYM8563_MONTH 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define HYM8563_MONTH_CENTURY BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define HYM8563_MONTH_MASK 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define HYM8563_YEAR 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define HYM8563_ALM_MIN 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define HYM8563_ALM_HOUR 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define HYM8563_ALM_DAY 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define HYM8563_ALM_WEEK 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Each alarm check can be disabled by setting this bit in the register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define HYM8563_ALM_BIT_DISABLE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define HYM8563_CLKOUT 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define HYM8563_CLKOUT_ENABLE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define HYM8563_CLKOUT_32768 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define HYM8563_CLKOUT_1024 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define HYM8563_CLKOUT_32 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define HYM8563_CLKOUT_1 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define HYM8563_CLKOUT_MASK 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define HYM8563_TMR_CTL 0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define HYM8563_TMR_CTL_ENABLE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define HYM8563_TMR_CTL_4096 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define HYM8563_TMR_CTL_64 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define HYM8563_TMR_CTL_1 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define HYM8563_TMR_CTL_1_60 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define HYM8563_TMR_CTL_MASK 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define HYM8563_TMR_CNT 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct hym8563 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct rtc_device *rtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct clk_hw clkout_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * RTC handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) u8 buf[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ret = i2c_smbus_read_i2c_block_data(client, HYM8563_SEC, 7, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) tm->tm_sec = bcd2bin(buf[0] & HYM8563_SEC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) tm->tm_min = bcd2bin(buf[1] & HYM8563_MIN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) tm->tm_hour = bcd2bin(buf[2] & HYM8563_HOUR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) tm->tm_mday = bcd2bin(buf[3] & HYM8563_DAY_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) tm->tm_wday = bcd2bin(buf[4] & HYM8563_WEEKDAY_MASK); /* 0 = Sun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) tm->tm_mon = bcd2bin(buf[5] & HYM8563_MONTH_MASK) - 1; /* 0 = Jan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) tm->tm_year = bcd2bin(buf[6]) + 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u8 buf[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* Years >= 2100 are to far in the future, 19XX is to early */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (tm->tm_year < 100 || tm->tm_year >= 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) buf[0] = bin2bcd(tm->tm_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) buf[1] = bin2bcd(tm->tm_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) buf[2] = bin2bcd(tm->tm_hour);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) buf[3] = bin2bcd(tm->tm_mday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) buf[4] = bin2bcd(tm->tm_wday);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) buf[5] = bin2bcd(tm->tm_mon + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * While the HYM8563 has a century flag in the month register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * it does not seem to carry it over a subsequent write/read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * So we'll limit ourself to 100 years, starting at 2000 for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) buf[6] = bin2bcd(tm->tm_year - 100);
^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) * CTL1 only contains TEST-mode bits apart from stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * so no need to read the value first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) HYM8563_CTL1_STOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ret = i2c_smbus_write_i2c_block_data(client, HYM8563_SEC, 7, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int hym8563_rtc_alarm_irq_enable(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned int enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) data = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (data < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) data |= HYM8563_CTL2_AIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) data &= ~HYM8563_CTL2_AIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return i2c_smbus_write_byte_data(client, HYM8563_CTL2, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int hym8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct rtc_time *alm_tm = &alm->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u8 buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ret = i2c_smbus_read_i2c_block_data(client, HYM8563_ALM_MIN, 4, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* The alarm only has a minute accuracy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) alm_tm->tm_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) alm_tm->tm_min = (buf[0] & HYM8563_ALM_BIT_DISABLE) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) -1 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) bcd2bin(buf[0] & HYM8563_MIN_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) alm_tm->tm_hour = (buf[1] & HYM8563_ALM_BIT_DISABLE) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) -1 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) bcd2bin(buf[1] & HYM8563_HOUR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) alm_tm->tm_mday = (buf[2] & HYM8563_ALM_BIT_DISABLE) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) -1 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) bcd2bin(buf[2] & HYM8563_DAY_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) alm_tm->tm_wday = (buf[3] & HYM8563_ALM_BIT_DISABLE) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) -1 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) bcd2bin(buf[3] & HYM8563_WEEKDAY_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (ret & HYM8563_CTL2_AIE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) alm->enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int hym8563_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct rtc_time *alm_tm = &alm->time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u8 buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * The alarm has no seconds so deal with it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (alm_tm->tm_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) alm_tm->tm_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) alm_tm->tm_min++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (alm_tm->tm_min >= 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) alm_tm->tm_min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) alm_tm->tm_hour++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (alm_tm->tm_hour >= 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) alm_tm->tm_hour = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) alm_tm->tm_mday++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) alm_tm->tm_wday++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (alm_tm->tm_wday > 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) alm_tm->tm_wday = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) switch (alm_tm->tm_mon + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (alm_tm->tm_mday > 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) alm_tm->tm_mday = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) case 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (alm_tm->tm_mday > 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) alm_tm->tm_mday = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (alm_tm->tm_year / 4 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (alm_tm->tm_mday > 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) alm_tm->tm_mday = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) } else if (alm_tm->tm_mday > 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) alm_tm->tm_mday = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ret &= ~HYM8563_CTL2_AIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = i2c_smbus_write_byte_data(client, HYM8563_CTL2, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) buf[0] = (alm_tm->tm_min < 60 && alm_tm->tm_min >= 0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) bin2bcd(alm_tm->tm_min) : HYM8563_ALM_BIT_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) buf[1] = (alm_tm->tm_hour < 24 && alm_tm->tm_hour >= 0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) bin2bcd(alm_tm->tm_hour) : HYM8563_ALM_BIT_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) buf[2] = (alm_tm->tm_mday <= 31 && alm_tm->tm_mday >= 1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) bin2bcd(alm_tm->tm_mday) : HYM8563_ALM_BIT_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) buf[3] = (alm_tm->tm_wday < 7 && alm_tm->tm_wday >= 0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) bin2bcd(alm_tm->tm_wday) : HYM8563_ALM_BIT_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ret = i2c_smbus_write_i2c_block_data(client, HYM8563_ALM_MIN, 4, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return hym8563_rtc_alarm_irq_enable(dev, alm->enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static const struct rtc_class_ops hym8563_rtc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .read_time = hym8563_rtc_read_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .set_time = hym8563_rtc_set_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .alarm_irq_enable = hym8563_rtc_alarm_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .read_alarm = hym8563_rtc_read_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .set_alarm = hym8563_rtc_set_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * Handling of the clkout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #define clkout_hw_to_hym8563(_hw) container_of(_hw, struct hym8563, clkout_hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static int clkout_rates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 32768,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static unsigned long hym8563_clkout_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct i2c_client *client = hym8563->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ret &= HYM8563_CLKOUT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return clkout_rates[ret];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static long hym8563_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (clkout_rates[i] <= rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return clkout_rates[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int hym8563_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct i2c_client *client = hym8563->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) for (i = 0; i < ARRAY_SIZE(clkout_rates); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (clkout_rates[i] == rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ret &= ~HYM8563_CLKOUT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ret |= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) HYM8563_CLKOUT, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int hym8563_clkout_control(struct clk_hw *hw, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) struct i2c_client *client = hym8563->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ret |= HYM8563_CLKOUT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret &= ~HYM8563_CLKOUT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int hym8563_clkout_prepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return hym8563_clkout_control(hw, 1);
^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 void hym8563_clkout_unprepare(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) hym8563_clkout_control(hw, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static int hym8563_clkout_is_prepared(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct hym8563 *hym8563 = clkout_hw_to_hym8563(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct i2c_client *client = hym8563->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return !!(ret & HYM8563_CLKOUT_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static const struct clk_ops hym8563_clkout_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .prepare = hym8563_clkout_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .unprepare = hym8563_clkout_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .is_prepared = hym8563_clkout_is_prepared,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) .recalc_rate = hym8563_clkout_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) .round_rate = hym8563_clkout_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .set_rate = hym8563_clkout_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct i2c_client *client = hym8563->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct device_node *node = client->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct clk_init_data init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) init.name = "hym8563-clkout";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) init.ops = &hym8563_clkout_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) init.flags = CLK_IS_CRITICAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) init.parent_names = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) init.num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) hym8563->clkout_hw.init = &init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* optional override of the clockname */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) of_property_read_string(node, "clock-output-names", &init.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /* register the clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) clk = clk_register(&client->dev, &hym8563->clkout_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) of_clk_add_provider(node, of_clk_src_simple_get, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * The alarm interrupt is implemented as a level-low interrupt in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * hym8563, while the timer interrupt uses a falling edge.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * We don't use the timer at all, so the interrupt is requested to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * use the level-low trigger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static irqreturn_t hym8563_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct hym8563 *hym8563 = (struct hym8563 *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct i2c_client *client = hym8563->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct mutex *lock = &hym8563->rtc->ops_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int data, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) mutex_lock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* Clear the alarm flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) data = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (data < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dev_err(&client->dev, "%s: error reading i2c data %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) __func__, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) data &= ~HYM8563_CTL2_AF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ret = i2c_smbus_write_byte_data(client, HYM8563_CTL2, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dev_err(&client->dev, "%s: error writing i2c data %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) mutex_unlock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static int hym8563_init_device(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* Clear stop flag if present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ret = i2c_smbus_write_byte_data(client, HYM8563_CTL1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ret < 0)
^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) /* Disable alarm and timer interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ret &= ~HYM8563_CTL2_AIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret &= ~HYM8563_CTL2_TIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Clear any pending alarm and timer flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (ret & HYM8563_CTL2_AF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret &= ~HYM8563_CTL2_AF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (ret & HYM8563_CTL2_TF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ret &= ~HYM8563_CTL2_TF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ret &= ~HYM8563_CTL2_TI_TP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return i2c_smbus_write_byte_data(client, HYM8563_CTL2, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static int hym8563_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (device_may_wakeup(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ret = enable_irq_wake(client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) dev_err(dev, "enable_irq_wake failed, %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static int hym8563_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (device_may_wakeup(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) disable_irq_wake(client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static SIMPLE_DEV_PM_OPS(hym8563_pm_ops, hym8563_suspend, hym8563_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static int hym8563_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct hym8563 *hym8563;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * hym8563 initial time(2021_1_1_12:00:00),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * avoid hym8563 read time error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct rtc_time tm_read, tm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .tm_wday = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .tm_year = 121,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .tm_mon = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .tm_mday = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .tm_hour = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .tm_min = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .tm_sec = 0,
^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) hym8563 = devm_kzalloc(&client->dev, sizeof(*hym8563), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (!hym8563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) hym8563->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) i2c_set_clientdata(client, hym8563);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) ret = hym8563_init_device(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) dev_err(&client->dev, "could not init device, %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (client->irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ret = devm_request_threaded_irq(&client->dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) NULL, hym8563_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) IRQF_TRIGGER_LOW | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) client->name, hym8563);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) dev_err(&client->dev, "irq %d request failed, %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) client->irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (client->irq > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) device_property_read_bool(&client->dev, "wakeup-source")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) device_init_wakeup(&client->dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /* check state of calendar information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ret = i2c_smbus_read_byte_data(client, HYM8563_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) dev_info(&client->dev, "rtc information is %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) (ret & HYM8563_SEC_VL) ? "invalid" : "valid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) hym8563_rtc_read_time(&client->dev, &tm_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if ((ret & HYM8563_SEC_VL) || (tm_read.tm_year < 70) || (tm_read.tm_year > 200) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) (tm_read.tm_mon == -1) || (rtc_valid_tm(&tm_read) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) hym8563_rtc_set_time(&client->dev, &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) hym8563->rtc = devm_rtc_device_register(&client->dev, client->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) &hym8563_rtc_ops, THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (IS_ERR(hym8563->rtc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return PTR_ERR(hym8563->rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* the hym8563 alarm only supports a minute accuracy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) hym8563->rtc->uie_unsupported = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) hym8563_clkout_register_clk(hym8563);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static const struct i2c_device_id hym8563_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) { "hym8563", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) MODULE_DEVICE_TABLE(i2c, hym8563_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static const struct of_device_id hym8563_dt_idtable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) { .compatible = "haoyu,hym8563" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) MODULE_DEVICE_TABLE(of, hym8563_dt_idtable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static struct i2c_driver hym8563_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .name = "rtc-hym8563",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .pm = &hym8563_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) .of_match_table = hym8563_dt_idtable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .probe = hym8563_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .id_table = hym8563_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) module_i2c_driver(hym8563_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) MODULE_DESCRIPTION("HYM8563 RTC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) MODULE_LICENSE("GPL");