15adbaed1SMia Lin // SPDX-License-Identifier: GPL-2.0 25adbaed1SMia Lin // Copyright (c) 2022 Nuvoton Technology Corporation 35adbaed1SMia Lin 45adbaed1SMia Lin #include <linux/bcd.h> 55adbaed1SMia Lin #include <linux/clk-provider.h> 65adbaed1SMia Lin #include <linux/err.h> 75adbaed1SMia Lin #include <linux/i2c.h> 85adbaed1SMia Lin #include <linux/module.h> 95adbaed1SMia Lin #include <linux/of.h> 105adbaed1SMia Lin #include <linux/rtc.h> 115adbaed1SMia Lin #include <linux/slab.h> 125adbaed1SMia Lin 135adbaed1SMia Lin #define NCT3018Y_REG_SC 0x00 /* seconds */ 145adbaed1SMia Lin #define NCT3018Y_REG_SCA 0x01 /* alarm */ 155adbaed1SMia Lin #define NCT3018Y_REG_MN 0x02 165adbaed1SMia Lin #define NCT3018Y_REG_MNA 0x03 /* alarm */ 175adbaed1SMia Lin #define NCT3018Y_REG_HR 0x04 185adbaed1SMia Lin #define NCT3018Y_REG_HRA 0x05 /* alarm */ 195adbaed1SMia Lin #define NCT3018Y_REG_DW 0x06 205adbaed1SMia Lin #define NCT3018Y_REG_DM 0x07 215adbaed1SMia Lin #define NCT3018Y_REG_MO 0x08 225adbaed1SMia Lin #define NCT3018Y_REG_YR 0x09 235adbaed1SMia Lin #define NCT3018Y_REG_CTRL 0x0A /* timer control */ 245adbaed1SMia Lin #define NCT3018Y_REG_ST 0x0B /* status */ 255adbaed1SMia Lin #define NCT3018Y_REG_CLKO 0x0C /* clock out */ 2614688f1aSMia Lin #define NCT3018Y_REG_PART 0x21 /* part info */ 275adbaed1SMia Lin 285adbaed1SMia Lin #define NCT3018Y_BIT_AF BIT(7) 295adbaed1SMia Lin #define NCT3018Y_BIT_ST BIT(7) 305adbaed1SMia Lin #define NCT3018Y_BIT_DM BIT(6) 315adbaed1SMia Lin #define NCT3018Y_BIT_HF BIT(5) 325adbaed1SMia Lin #define NCT3018Y_BIT_DSM BIT(4) 335adbaed1SMia Lin #define NCT3018Y_BIT_AIE BIT(3) 345adbaed1SMia Lin #define NCT3018Y_BIT_OFIE BIT(2) 355adbaed1SMia Lin #define NCT3018Y_BIT_CIE BIT(1) 365adbaed1SMia Lin #define NCT3018Y_BIT_TWO BIT(0) 375adbaed1SMia Lin 385adbaed1SMia Lin #define NCT3018Y_REG_BAT_MASK 0x07 395adbaed1SMia Lin #define NCT3018Y_REG_CLKO_F_MASK 0x03 /* frequenc mask */ 405adbaed1SMia Lin #define NCT3018Y_REG_CLKO_CKE 0x80 /* clock out enabled */ 4114688f1aSMia Lin #define NCT3018Y_REG_PART_NCT3018Y 0x02 425adbaed1SMia Lin 435adbaed1SMia Lin struct nct3018y { 445adbaed1SMia Lin struct rtc_device *rtc; 455adbaed1SMia Lin struct i2c_client *client; 4614688f1aSMia Lin int part_num; 475adbaed1SMia Lin #ifdef CONFIG_COMMON_CLK 485adbaed1SMia Lin struct clk_hw clkout_hw; 495adbaed1SMia Lin #endif 505adbaed1SMia Lin }; 515adbaed1SMia Lin 525adbaed1SMia Lin static int nct3018y_set_alarm_mode(struct i2c_client *client, bool on) 535adbaed1SMia Lin { 545adbaed1SMia Lin int err, flags; 555adbaed1SMia Lin 565adbaed1SMia Lin dev_dbg(&client->dev, "%s:on:%d\n", __func__, on); 575adbaed1SMia Lin 585adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL); 595adbaed1SMia Lin if (flags < 0) { 605adbaed1SMia Lin dev_dbg(&client->dev, 615adbaed1SMia Lin "Failed to read NCT3018Y_REG_CTRL\n"); 625adbaed1SMia Lin return flags; 635adbaed1SMia Lin } 645adbaed1SMia Lin 655adbaed1SMia Lin if (on) 665adbaed1SMia Lin flags |= NCT3018Y_BIT_AIE; 675adbaed1SMia Lin else 685adbaed1SMia Lin flags &= ~NCT3018Y_BIT_AIE; 695adbaed1SMia Lin 705adbaed1SMia Lin flags |= NCT3018Y_BIT_CIE; 715adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags); 725adbaed1SMia Lin if (err < 0) { 735adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL\n"); 745adbaed1SMia Lin return err; 755adbaed1SMia Lin } 765adbaed1SMia Lin 775adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_ST); 785adbaed1SMia Lin if (flags < 0) { 795adbaed1SMia Lin dev_dbg(&client->dev, 805adbaed1SMia Lin "Failed to read NCT3018Y_REG_ST\n"); 815adbaed1SMia Lin return flags; 825adbaed1SMia Lin } 835adbaed1SMia Lin 845adbaed1SMia Lin flags &= ~(NCT3018Y_BIT_AF); 855adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_ST, flags); 865adbaed1SMia Lin if (err < 0) { 875adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_ST\n"); 885adbaed1SMia Lin return err; 895adbaed1SMia Lin } 905adbaed1SMia Lin 915adbaed1SMia Lin return 0; 925adbaed1SMia Lin } 935adbaed1SMia Lin 945adbaed1SMia Lin static int nct3018y_get_alarm_mode(struct i2c_client *client, unsigned char *alarm_enable, 955adbaed1SMia Lin unsigned char *alarm_flag) 965adbaed1SMia Lin { 975adbaed1SMia Lin int flags; 985adbaed1SMia Lin 995adbaed1SMia Lin if (alarm_enable) { 1005adbaed1SMia Lin dev_dbg(&client->dev, "%s:NCT3018Y_REG_CTRL\n", __func__); 1015adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL); 1025adbaed1SMia Lin if (flags < 0) 1035adbaed1SMia Lin return flags; 1045adbaed1SMia Lin *alarm_enable = flags & NCT3018Y_BIT_AIE; 105babfeb9cSAlexandre Belloni dev_dbg(&client->dev, "%s:alarm_enable:%x\n", __func__, *alarm_enable); 106babfeb9cSAlexandre Belloni 1075adbaed1SMia Lin } 1085adbaed1SMia Lin 1095adbaed1SMia Lin if (alarm_flag) { 1105adbaed1SMia Lin dev_dbg(&client->dev, "%s:NCT3018Y_REG_ST\n", __func__); 1115adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_ST); 1125adbaed1SMia Lin if (flags < 0) 1135adbaed1SMia Lin return flags; 1145adbaed1SMia Lin *alarm_flag = flags & NCT3018Y_BIT_AF; 115babfeb9cSAlexandre Belloni dev_dbg(&client->dev, "%s:alarm_flag:%x\n", __func__, *alarm_flag); 1165adbaed1SMia Lin } 1175adbaed1SMia Lin 1185adbaed1SMia Lin return 0; 1195adbaed1SMia Lin } 1205adbaed1SMia Lin 1215adbaed1SMia Lin static irqreturn_t nct3018y_irq(int irq, void *dev_id) 1225adbaed1SMia Lin { 1235adbaed1SMia Lin struct nct3018y *nct3018y = i2c_get_clientdata(dev_id); 1245adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 1255adbaed1SMia Lin int err; 1265adbaed1SMia Lin unsigned char alarm_flag; 1275adbaed1SMia Lin unsigned char alarm_enable; 1285adbaed1SMia Lin 1295adbaed1SMia Lin dev_dbg(&client->dev, "%s:irq:%d\n", __func__, irq); 1305adbaed1SMia Lin err = nct3018y_get_alarm_mode(nct3018y->client, &alarm_enable, &alarm_flag); 1315adbaed1SMia Lin if (err) 1325adbaed1SMia Lin return IRQ_NONE; 1335adbaed1SMia Lin 1345adbaed1SMia Lin if (alarm_flag) { 1355adbaed1SMia Lin dev_dbg(&client->dev, "%s:alarm flag:%x\n", 1365adbaed1SMia Lin __func__, alarm_flag); 1375adbaed1SMia Lin rtc_update_irq(nct3018y->rtc, 1, RTC_IRQF | RTC_AF); 1385adbaed1SMia Lin nct3018y_set_alarm_mode(nct3018y->client, 0); 1395adbaed1SMia Lin dev_dbg(&client->dev, "%s:IRQ_HANDLED\n", __func__); 1405adbaed1SMia Lin return IRQ_HANDLED; 1415adbaed1SMia Lin } 1425adbaed1SMia Lin 1435adbaed1SMia Lin return IRQ_NONE; 1445adbaed1SMia Lin } 1455adbaed1SMia Lin 1465adbaed1SMia Lin /* 1475adbaed1SMia Lin * In the routines that deal directly with the nct3018y hardware, we use 1485adbaed1SMia Lin * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. 1495adbaed1SMia Lin */ 1505adbaed1SMia Lin static int nct3018y_rtc_read_time(struct device *dev, struct rtc_time *tm) 1515adbaed1SMia Lin { 1525adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 1535adbaed1SMia Lin unsigned char buf[10]; 1545adbaed1SMia Lin int err; 1555adbaed1SMia Lin 1565adbaed1SMia Lin err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_ST, 1, buf); 1575adbaed1SMia Lin if (err < 0) 1585adbaed1SMia Lin return err; 1595adbaed1SMia Lin 1605adbaed1SMia Lin if (!buf[0]) { 1615adbaed1SMia Lin dev_dbg(&client->dev, " voltage <=1.7, date/time is not reliable.\n"); 1625adbaed1SMia Lin return -EINVAL; 1635adbaed1SMia Lin } 1645adbaed1SMia Lin 1655adbaed1SMia Lin err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SC, sizeof(buf), buf); 1665adbaed1SMia Lin if (err < 0) 1675adbaed1SMia Lin return err; 1685adbaed1SMia Lin 1695adbaed1SMia Lin tm->tm_sec = bcd2bin(buf[0] & 0x7F); 1705adbaed1SMia Lin tm->tm_min = bcd2bin(buf[2] & 0x7F); 1715adbaed1SMia Lin tm->tm_hour = bcd2bin(buf[4] & 0x3F); 1725adbaed1SMia Lin tm->tm_wday = buf[6] & 0x07; 1735adbaed1SMia Lin tm->tm_mday = bcd2bin(buf[7] & 0x3F); 1745adbaed1SMia Lin tm->tm_mon = bcd2bin(buf[8] & 0x1F) - 1; 1755adbaed1SMia Lin tm->tm_year = bcd2bin(buf[9]) + 100; 1765adbaed1SMia Lin 1775adbaed1SMia Lin return 0; 1785adbaed1SMia Lin } 1795adbaed1SMia Lin 1805adbaed1SMia Lin static int nct3018y_rtc_set_time(struct device *dev, struct rtc_time *tm) 1815adbaed1SMia Lin { 1825adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 18314688f1aSMia Lin struct nct3018y *nct3018y = dev_get_drvdata(dev); 1845adbaed1SMia Lin unsigned char buf[4] = {0}; 18514688f1aSMia Lin int err, flags; 18614688f1aSMia Lin int restore_flags = 0; 18714688f1aSMia Lin 18814688f1aSMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL); 18914688f1aSMia Lin if (flags < 0) { 19014688f1aSMia Lin dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_CTRL.\n"); 19114688f1aSMia Lin return flags; 19214688f1aSMia Lin } 19314688f1aSMia Lin 19414688f1aSMia Lin /* Check and set TWO bit */ 19514688f1aSMia Lin if (nct3018y->part_num == NCT3018Y_REG_PART_NCT3018Y && !(flags & NCT3018Y_BIT_TWO)) { 19614688f1aSMia Lin restore_flags = 1; 19714688f1aSMia Lin flags |= NCT3018Y_BIT_TWO; 19814688f1aSMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags); 19914688f1aSMia Lin if (err < 0) { 20014688f1aSMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n"); 20114688f1aSMia Lin return err; 20214688f1aSMia Lin } 20314688f1aSMia Lin } 2045adbaed1SMia Lin 2055adbaed1SMia Lin buf[0] = bin2bcd(tm->tm_sec); 2065adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SC, buf[0]); 2075adbaed1SMia Lin if (err < 0) { 2085adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_SC\n"); 2095adbaed1SMia Lin return err; 2105adbaed1SMia Lin } 2115adbaed1SMia Lin 2125adbaed1SMia Lin buf[0] = bin2bcd(tm->tm_min); 2135adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_MN, buf[0]); 2145adbaed1SMia Lin if (err < 0) { 2155adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_MN\n"); 2165adbaed1SMia Lin return err; 2175adbaed1SMia Lin } 2185adbaed1SMia Lin 2195adbaed1SMia Lin buf[0] = bin2bcd(tm->tm_hour); 2205adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_HR, buf[0]); 2215adbaed1SMia Lin if (err < 0) { 2225adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_HR\n"); 2235adbaed1SMia Lin return err; 2245adbaed1SMia Lin } 2255adbaed1SMia Lin 2265adbaed1SMia Lin buf[0] = tm->tm_wday & 0x07; 2275adbaed1SMia Lin buf[1] = bin2bcd(tm->tm_mday); 2285adbaed1SMia Lin buf[2] = bin2bcd(tm->tm_mon + 1); 2295adbaed1SMia Lin buf[3] = bin2bcd(tm->tm_year - 100); 2305adbaed1SMia Lin err = i2c_smbus_write_i2c_block_data(client, NCT3018Y_REG_DW, 2315adbaed1SMia Lin sizeof(buf), buf); 2325adbaed1SMia Lin if (err < 0) { 2335adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write for day and mon and year\n"); 2345adbaed1SMia Lin return -EIO; 2355adbaed1SMia Lin } 2365adbaed1SMia Lin 23714688f1aSMia Lin /* Restore TWO bit */ 23814688f1aSMia Lin if (restore_flags) { 23914688f1aSMia Lin if (nct3018y->part_num == NCT3018Y_REG_PART_NCT3018Y) 24014688f1aSMia Lin flags &= ~NCT3018Y_BIT_TWO; 24114688f1aSMia Lin 24214688f1aSMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags); 24314688f1aSMia Lin if (err < 0) { 24414688f1aSMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n"); 24514688f1aSMia Lin return err; 24614688f1aSMia Lin } 24714688f1aSMia Lin } 24814688f1aSMia Lin 2495adbaed1SMia Lin return err; 2505adbaed1SMia Lin } 2515adbaed1SMia Lin 2525adbaed1SMia Lin static int nct3018y_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) 2535adbaed1SMia Lin { 2545adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 2555adbaed1SMia Lin unsigned char buf[5]; 2565adbaed1SMia Lin int err; 2575adbaed1SMia Lin 2585adbaed1SMia Lin err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SCA, 2595adbaed1SMia Lin sizeof(buf), buf); 2605adbaed1SMia Lin if (err < 0) { 2615adbaed1SMia Lin dev_dbg(&client->dev, "Unable to read date\n"); 2625adbaed1SMia Lin return -EIO; 2635adbaed1SMia Lin } 2645adbaed1SMia Lin 2655adbaed1SMia Lin dev_dbg(&client->dev, "%s: raw data is sec=%02x, min=%02x hr=%02x\n", 2665adbaed1SMia Lin __func__, buf[0], buf[2], buf[4]); 2675adbaed1SMia Lin 2685adbaed1SMia Lin tm->time.tm_sec = bcd2bin(buf[0] & 0x7F); 2695adbaed1SMia Lin tm->time.tm_min = bcd2bin(buf[2] & 0x7F); 2705adbaed1SMia Lin tm->time.tm_hour = bcd2bin(buf[4] & 0x3F); 2715adbaed1SMia Lin 2725adbaed1SMia Lin err = nct3018y_get_alarm_mode(client, &tm->enabled, &tm->pending); 2735adbaed1SMia Lin if (err < 0) 2745adbaed1SMia Lin return err; 2755adbaed1SMia Lin 2765adbaed1SMia Lin dev_dbg(&client->dev, "%s:s=%d m=%d, hr=%d, enabled=%d, pending=%d\n", 2775adbaed1SMia Lin __func__, tm->time.tm_sec, tm->time.tm_min, 2785adbaed1SMia Lin tm->time.tm_hour, tm->enabled, tm->pending); 2795adbaed1SMia Lin 2805adbaed1SMia Lin return 0; 2815adbaed1SMia Lin } 2825adbaed1SMia Lin 2835adbaed1SMia Lin static int nct3018y_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm) 2845adbaed1SMia Lin { 2855adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 2865adbaed1SMia Lin int err; 2875adbaed1SMia Lin 2885adbaed1SMia Lin dev_dbg(dev, "%s, sec=%d, min=%d hour=%d tm->enabled:%d\n", 2895adbaed1SMia Lin __func__, tm->time.tm_sec, tm->time.tm_min, tm->time.tm_hour, 2905adbaed1SMia Lin tm->enabled); 2915adbaed1SMia Lin 2925adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SCA, bin2bcd(tm->time.tm_sec)); 2935adbaed1SMia Lin if (err < 0) { 2945adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_SCA\n"); 2955adbaed1SMia Lin return err; 2965adbaed1SMia Lin } 2975adbaed1SMia Lin 2985adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_MNA, bin2bcd(tm->time.tm_min)); 2995adbaed1SMia Lin if (err < 0) { 3005adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_MNA\n"); 3015adbaed1SMia Lin return err; 3025adbaed1SMia Lin } 3035adbaed1SMia Lin 3045adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_HRA, bin2bcd(tm->time.tm_hour)); 3055adbaed1SMia Lin if (err < 0) { 3065adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_HRA\n"); 3075adbaed1SMia Lin return err; 3085adbaed1SMia Lin } 3095adbaed1SMia Lin 3105adbaed1SMia Lin return nct3018y_set_alarm_mode(client, tm->enabled); 3115adbaed1SMia Lin } 3125adbaed1SMia Lin 3135adbaed1SMia Lin static int nct3018y_irq_enable(struct device *dev, unsigned int enabled) 3145adbaed1SMia Lin { 3155adbaed1SMia Lin dev_dbg(dev, "%s: alarm enable=%d\n", __func__, enabled); 3165adbaed1SMia Lin 3175adbaed1SMia Lin return nct3018y_set_alarm_mode(to_i2c_client(dev), enabled); 3185adbaed1SMia Lin } 3195adbaed1SMia Lin 3205adbaed1SMia Lin static int nct3018y_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 3215adbaed1SMia Lin { 3225adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 3235adbaed1SMia Lin int status, flags = 0; 3245adbaed1SMia Lin 3255adbaed1SMia Lin switch (cmd) { 3265adbaed1SMia Lin case RTC_VL_READ: 3275adbaed1SMia Lin status = i2c_smbus_read_byte_data(client, NCT3018Y_REG_ST); 3285adbaed1SMia Lin if (status < 0) 3295adbaed1SMia Lin return status; 3305adbaed1SMia Lin 3315adbaed1SMia Lin if (!(status & NCT3018Y_REG_BAT_MASK)) 3325adbaed1SMia Lin flags |= RTC_VL_DATA_INVALID; 3335adbaed1SMia Lin 3345adbaed1SMia Lin return put_user(flags, (unsigned int __user *)arg); 3355adbaed1SMia Lin 3365adbaed1SMia Lin default: 3375adbaed1SMia Lin return -ENOIOCTLCMD; 3385adbaed1SMia Lin } 3395adbaed1SMia Lin } 3405adbaed1SMia Lin 3415adbaed1SMia Lin #ifdef CONFIG_COMMON_CLK 3425adbaed1SMia Lin /* 3435adbaed1SMia Lin * Handling of the clkout 3445adbaed1SMia Lin */ 3455adbaed1SMia Lin 3465adbaed1SMia Lin #define clkout_hw_to_nct3018y(_hw) container_of(_hw, struct nct3018y, clkout_hw) 3475adbaed1SMia Lin 3485adbaed1SMia Lin static const int clkout_rates[] = { 3495adbaed1SMia Lin 32768, 3505adbaed1SMia Lin 1024, 3515adbaed1SMia Lin 32, 3525adbaed1SMia Lin 1, 3535adbaed1SMia Lin }; 3545adbaed1SMia Lin 3555adbaed1SMia Lin static unsigned long nct3018y_clkout_recalc_rate(struct clk_hw *hw, 3565adbaed1SMia Lin unsigned long parent_rate) 3575adbaed1SMia Lin { 3585adbaed1SMia Lin struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw); 3595adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 3605adbaed1SMia Lin int flags; 3615adbaed1SMia Lin 3625adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO); 3635adbaed1SMia Lin if (flags < 0) 3645adbaed1SMia Lin return 0; 3655adbaed1SMia Lin 3665adbaed1SMia Lin flags &= NCT3018Y_REG_CLKO_F_MASK; 3675adbaed1SMia Lin return clkout_rates[flags]; 3685adbaed1SMia Lin } 3695adbaed1SMia Lin 3705adbaed1SMia Lin static long nct3018y_clkout_round_rate(struct clk_hw *hw, unsigned long rate, 3715adbaed1SMia Lin unsigned long *prate) 3725adbaed1SMia Lin { 3735adbaed1SMia Lin int i; 3745adbaed1SMia Lin 3755adbaed1SMia Lin for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) 3765adbaed1SMia Lin if (clkout_rates[i] <= rate) 3775adbaed1SMia Lin return clkout_rates[i]; 3785adbaed1SMia Lin 3795adbaed1SMia Lin return 0; 3805adbaed1SMia Lin } 3815adbaed1SMia Lin 3825adbaed1SMia Lin static int nct3018y_clkout_set_rate(struct clk_hw *hw, unsigned long rate, 3835adbaed1SMia Lin unsigned long parent_rate) 3845adbaed1SMia Lin { 3855adbaed1SMia Lin struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw); 3865adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 3875adbaed1SMia Lin int i, flags; 3885adbaed1SMia Lin 3895adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO); 3905adbaed1SMia Lin if (flags < 0) 3915adbaed1SMia Lin return flags; 3925adbaed1SMia Lin 3935adbaed1SMia Lin for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) 3945adbaed1SMia Lin if (clkout_rates[i] == rate) { 3955adbaed1SMia Lin flags &= ~NCT3018Y_REG_CLKO_F_MASK; 3965adbaed1SMia Lin flags |= i; 3975adbaed1SMia Lin return i2c_smbus_write_byte_data(client, NCT3018Y_REG_CLKO, flags); 3985adbaed1SMia Lin } 3995adbaed1SMia Lin 4005adbaed1SMia Lin return -EINVAL; 4015adbaed1SMia Lin } 4025adbaed1SMia Lin 4035adbaed1SMia Lin static int nct3018y_clkout_control(struct clk_hw *hw, bool enable) 4045adbaed1SMia Lin { 4055adbaed1SMia Lin struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw); 4065adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 4075adbaed1SMia Lin int flags; 4085adbaed1SMia Lin 4095adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO); 4105adbaed1SMia Lin if (flags < 0) 4115adbaed1SMia Lin return flags; 4125adbaed1SMia Lin 4135adbaed1SMia Lin if (enable) 4145adbaed1SMia Lin flags |= NCT3018Y_REG_CLKO_CKE; 4155adbaed1SMia Lin else 4165adbaed1SMia Lin flags &= ~NCT3018Y_REG_CLKO_CKE; 4175adbaed1SMia Lin 4185adbaed1SMia Lin return i2c_smbus_write_byte_data(client, NCT3018Y_REG_CLKO, flags); 4195adbaed1SMia Lin } 4205adbaed1SMia Lin 4215adbaed1SMia Lin static int nct3018y_clkout_prepare(struct clk_hw *hw) 4225adbaed1SMia Lin { 4235adbaed1SMia Lin return nct3018y_clkout_control(hw, 1); 4245adbaed1SMia Lin } 4255adbaed1SMia Lin 4265adbaed1SMia Lin static void nct3018y_clkout_unprepare(struct clk_hw *hw) 4275adbaed1SMia Lin { 4285adbaed1SMia Lin nct3018y_clkout_control(hw, 0); 4295adbaed1SMia Lin } 4305adbaed1SMia Lin 4315adbaed1SMia Lin static int nct3018y_clkout_is_prepared(struct clk_hw *hw) 4325adbaed1SMia Lin { 4335adbaed1SMia Lin struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw); 4345adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 4355adbaed1SMia Lin int flags; 4365adbaed1SMia Lin 4375adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO); 4385adbaed1SMia Lin if (flags < 0) 4395adbaed1SMia Lin return flags; 4405adbaed1SMia Lin 4415adbaed1SMia Lin return flags & NCT3018Y_REG_CLKO_CKE; 4425adbaed1SMia Lin } 4435adbaed1SMia Lin 4445adbaed1SMia Lin static const struct clk_ops nct3018y_clkout_ops = { 4455adbaed1SMia Lin .prepare = nct3018y_clkout_prepare, 4465adbaed1SMia Lin .unprepare = nct3018y_clkout_unprepare, 4475adbaed1SMia Lin .is_prepared = nct3018y_clkout_is_prepared, 4485adbaed1SMia Lin .recalc_rate = nct3018y_clkout_recalc_rate, 4495adbaed1SMia Lin .round_rate = nct3018y_clkout_round_rate, 4505adbaed1SMia Lin .set_rate = nct3018y_clkout_set_rate, 4515adbaed1SMia Lin }; 4525adbaed1SMia Lin 4535adbaed1SMia Lin static struct clk *nct3018y_clkout_register_clk(struct nct3018y *nct3018y) 4545adbaed1SMia Lin { 4555adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 4565adbaed1SMia Lin struct device_node *node = client->dev.of_node; 4575adbaed1SMia Lin struct clk *clk; 4585adbaed1SMia Lin struct clk_init_data init; 4595adbaed1SMia Lin 4605adbaed1SMia Lin init.name = "nct3018y-clkout"; 4615adbaed1SMia Lin init.ops = &nct3018y_clkout_ops; 4625adbaed1SMia Lin init.flags = 0; 4635adbaed1SMia Lin init.parent_names = NULL; 4645adbaed1SMia Lin init.num_parents = 0; 4655adbaed1SMia Lin nct3018y->clkout_hw.init = &init; 4665adbaed1SMia Lin 4675adbaed1SMia Lin /* optional override of the clockname */ 4685adbaed1SMia Lin of_property_read_string(node, "clock-output-names", &init.name); 4695adbaed1SMia Lin 4705adbaed1SMia Lin /* register the clock */ 4715adbaed1SMia Lin clk = devm_clk_register(&client->dev, &nct3018y->clkout_hw); 4725adbaed1SMia Lin 4735adbaed1SMia Lin if (!IS_ERR(clk)) 4745adbaed1SMia Lin of_clk_add_provider(node, of_clk_src_simple_get, clk); 4755adbaed1SMia Lin 4765adbaed1SMia Lin return clk; 4775adbaed1SMia Lin } 4785adbaed1SMia Lin #endif 4795adbaed1SMia Lin 4805adbaed1SMia Lin static const struct rtc_class_ops nct3018y_rtc_ops = { 4815adbaed1SMia Lin .read_time = nct3018y_rtc_read_time, 4825adbaed1SMia Lin .set_time = nct3018y_rtc_set_time, 4835adbaed1SMia Lin .read_alarm = nct3018y_rtc_read_alarm, 4845adbaed1SMia Lin .set_alarm = nct3018y_rtc_set_alarm, 4855adbaed1SMia Lin .alarm_irq_enable = nct3018y_irq_enable, 4865adbaed1SMia Lin .ioctl = nct3018y_ioctl, 4875adbaed1SMia Lin }; 4885adbaed1SMia Lin 489c050dedbSUwe Kleine-König static int nct3018y_probe(struct i2c_client *client) 4905adbaed1SMia Lin { 4915adbaed1SMia Lin struct nct3018y *nct3018y; 4925adbaed1SMia Lin int err, flags; 4935adbaed1SMia Lin 4945adbaed1SMia Lin if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | 4955adbaed1SMia Lin I2C_FUNC_SMBUS_BYTE | 4965adbaed1SMia Lin I2C_FUNC_SMBUS_BLOCK_DATA)) 4975adbaed1SMia Lin return -ENODEV; 4985adbaed1SMia Lin 4995adbaed1SMia Lin nct3018y = devm_kzalloc(&client->dev, sizeof(struct nct3018y), 5005adbaed1SMia Lin GFP_KERNEL); 5015adbaed1SMia Lin if (!nct3018y) 5025adbaed1SMia Lin return -ENOMEM; 5035adbaed1SMia Lin 5045adbaed1SMia Lin i2c_set_clientdata(client, nct3018y); 5055adbaed1SMia Lin nct3018y->client = client; 5065adbaed1SMia Lin device_set_wakeup_capable(&client->dev, 1); 5075adbaed1SMia Lin 5085adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL); 5095adbaed1SMia Lin if (flags < 0) { 5105adbaed1SMia Lin dev_dbg(&client->dev, "%s: read error\n", __func__); 5115adbaed1SMia Lin return flags; 5125adbaed1SMia Lin } else if (flags & NCT3018Y_BIT_TWO) { 5135adbaed1SMia Lin dev_dbg(&client->dev, "%s: NCT3018Y_BIT_TWO is set\n", __func__); 5145adbaed1SMia Lin } 5155adbaed1SMia Lin 51614688f1aSMia Lin nct3018y->part_num = i2c_smbus_read_byte_data(client, NCT3018Y_REG_PART); 51714688f1aSMia Lin if (nct3018y->part_num < 0) { 51814688f1aSMia Lin dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_PART.\n"); 51914688f1aSMia Lin return nct3018y->part_num; 5208b59a11fSMia Lin } else { 5218b59a11fSMia Lin nct3018y->part_num &= 0x03; /* Part number is corresponding to bit 0 and 1 */ 5228b59a11fSMia Lin if (nct3018y->part_num == NCT3018Y_REG_PART_NCT3018Y) { 52314688f1aSMia Lin flags = NCT3018Y_BIT_HF; 5245adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags); 5255adbaed1SMia Lin if (err < 0) { 52614688f1aSMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n"); 5275adbaed1SMia Lin return err; 5285adbaed1SMia Lin } 52914688f1aSMia Lin } 5308b59a11fSMia Lin } 5315adbaed1SMia Lin 5325adbaed1SMia Lin flags = 0; 5335adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_ST, flags); 5345adbaed1SMia Lin if (err < 0) { 5355adbaed1SMia Lin dev_dbg(&client->dev, "%s: write error\n", __func__); 5365adbaed1SMia Lin return err; 5375adbaed1SMia Lin } 5385adbaed1SMia Lin 5395adbaed1SMia Lin nct3018y->rtc = devm_rtc_allocate_device(&client->dev); 5405adbaed1SMia Lin if (IS_ERR(nct3018y->rtc)) 5415adbaed1SMia Lin return PTR_ERR(nct3018y->rtc); 5425adbaed1SMia Lin 5435adbaed1SMia Lin nct3018y->rtc->ops = &nct3018y_rtc_ops; 5445adbaed1SMia Lin nct3018y->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 5455adbaed1SMia Lin nct3018y->rtc->range_max = RTC_TIMESTAMP_END_2099; 5465adbaed1SMia Lin 5475adbaed1SMia Lin if (client->irq > 0) { 5485adbaed1SMia Lin err = devm_request_threaded_irq(&client->dev, client->irq, 5495adbaed1SMia Lin NULL, nct3018y_irq, 5505adbaed1SMia Lin IRQF_ONESHOT | IRQF_TRIGGER_FALLING, 5515adbaed1SMia Lin "nct3018y", client); 5525adbaed1SMia Lin if (err) { 5535adbaed1SMia Lin dev_dbg(&client->dev, "unable to request IRQ %d\n", client->irq); 5545adbaed1SMia Lin return err; 5555adbaed1SMia Lin } 5565adbaed1SMia Lin } else { 5575adbaed1SMia Lin clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, nct3018y->rtc->features); 5585adbaed1SMia Lin clear_bit(RTC_FEATURE_ALARM, nct3018y->rtc->features); 5595adbaed1SMia Lin } 5605adbaed1SMia Lin 5615adbaed1SMia Lin #ifdef CONFIG_COMMON_CLK 5625adbaed1SMia Lin /* register clk in common clk framework */ 5635adbaed1SMia Lin nct3018y_clkout_register_clk(nct3018y); 5645adbaed1SMia Lin #endif 5655adbaed1SMia Lin 5665adbaed1SMia Lin return devm_rtc_register_device(nct3018y->rtc); 5675adbaed1SMia Lin } 5685adbaed1SMia Lin 5695adbaed1SMia Lin static const struct i2c_device_id nct3018y_id[] = { 570*a47d377eSUwe Kleine-König { "nct3018y" }, 5715adbaed1SMia Lin { } 5725adbaed1SMia Lin }; 5735adbaed1SMia Lin MODULE_DEVICE_TABLE(i2c, nct3018y_id); 5745adbaed1SMia Lin 5755adbaed1SMia Lin static const struct of_device_id nct3018y_of_match[] = { 5765adbaed1SMia Lin { .compatible = "nuvoton,nct3018y" }, 5775adbaed1SMia Lin {} 5785adbaed1SMia Lin }; 5795adbaed1SMia Lin MODULE_DEVICE_TABLE(of, nct3018y_of_match); 5805adbaed1SMia Lin 5815adbaed1SMia Lin static struct i2c_driver nct3018y_driver = { 5825adbaed1SMia Lin .driver = { 5835adbaed1SMia Lin .name = "rtc-nct3018y", 5844f3688dcSZhu Wang .of_match_table = nct3018y_of_match, 5855adbaed1SMia Lin }, 58631b0cecbSUwe Kleine-König .probe = nct3018y_probe, 5875adbaed1SMia Lin .id_table = nct3018y_id, 5885adbaed1SMia Lin }; 5895adbaed1SMia Lin 5905adbaed1SMia Lin module_i2c_driver(nct3018y_driver); 5915adbaed1SMia Lin 5925adbaed1SMia Lin MODULE_AUTHOR("Medad CChien <ctcchien@nuvoton.com>"); 5935adbaed1SMia Lin MODULE_AUTHOR("Mia Lin <mimi05633@gmail.com>"); 5945adbaed1SMia Lin MODULE_DESCRIPTION("Nuvoton NCT3018Y RTC driver"); 5955adbaed1SMia Lin MODULE_LICENSE("GPL"); 596