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 */ 265adbaed1SMia Lin 275adbaed1SMia Lin #define NCT3018Y_BIT_AF BIT(7) 285adbaed1SMia Lin #define NCT3018Y_BIT_ST BIT(7) 295adbaed1SMia Lin #define NCT3018Y_BIT_DM BIT(6) 305adbaed1SMia Lin #define NCT3018Y_BIT_HF BIT(5) 315adbaed1SMia Lin #define NCT3018Y_BIT_DSM BIT(4) 325adbaed1SMia Lin #define NCT3018Y_BIT_AIE BIT(3) 335adbaed1SMia Lin #define NCT3018Y_BIT_OFIE BIT(2) 345adbaed1SMia Lin #define NCT3018Y_BIT_CIE BIT(1) 355adbaed1SMia Lin #define NCT3018Y_BIT_TWO BIT(0) 365adbaed1SMia Lin 375adbaed1SMia Lin #define NCT3018Y_REG_BAT_MASK 0x07 385adbaed1SMia Lin #define NCT3018Y_REG_CLKO_F_MASK 0x03 /* frequenc mask */ 395adbaed1SMia Lin #define NCT3018Y_REG_CLKO_CKE 0x80 /* clock out enabled */ 405adbaed1SMia Lin 415adbaed1SMia Lin struct nct3018y { 425adbaed1SMia Lin struct rtc_device *rtc; 435adbaed1SMia Lin struct i2c_client *client; 445adbaed1SMia Lin #ifdef CONFIG_COMMON_CLK 455adbaed1SMia Lin struct clk_hw clkout_hw; 465adbaed1SMia Lin #endif 475adbaed1SMia Lin }; 485adbaed1SMia Lin 495adbaed1SMia Lin static int nct3018y_set_alarm_mode(struct i2c_client *client, bool on) 505adbaed1SMia Lin { 515adbaed1SMia Lin int err, flags; 525adbaed1SMia Lin 535adbaed1SMia Lin dev_dbg(&client->dev, "%s:on:%d\n", __func__, on); 545adbaed1SMia Lin 555adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL); 565adbaed1SMia Lin if (flags < 0) { 575adbaed1SMia Lin dev_dbg(&client->dev, 585adbaed1SMia Lin "Failed to read NCT3018Y_REG_CTRL\n"); 595adbaed1SMia Lin return flags; 605adbaed1SMia Lin } 615adbaed1SMia Lin 625adbaed1SMia Lin if (on) 635adbaed1SMia Lin flags |= NCT3018Y_BIT_AIE; 645adbaed1SMia Lin else 655adbaed1SMia Lin flags &= ~NCT3018Y_BIT_AIE; 665adbaed1SMia Lin 675adbaed1SMia Lin flags |= NCT3018Y_BIT_CIE; 685adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags); 695adbaed1SMia Lin if (err < 0) { 705adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL\n"); 715adbaed1SMia Lin return err; 725adbaed1SMia Lin } 735adbaed1SMia Lin 745adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_ST); 755adbaed1SMia Lin if (flags < 0) { 765adbaed1SMia Lin dev_dbg(&client->dev, 775adbaed1SMia Lin "Failed to read NCT3018Y_REG_ST\n"); 785adbaed1SMia Lin return flags; 795adbaed1SMia Lin } 805adbaed1SMia Lin 815adbaed1SMia Lin flags &= ~(NCT3018Y_BIT_AF); 825adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_ST, flags); 835adbaed1SMia Lin if (err < 0) { 845adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_ST\n"); 855adbaed1SMia Lin return err; 865adbaed1SMia Lin } 875adbaed1SMia Lin 885adbaed1SMia Lin return 0; 895adbaed1SMia Lin } 905adbaed1SMia Lin 915adbaed1SMia Lin static int nct3018y_get_alarm_mode(struct i2c_client *client, unsigned char *alarm_enable, 925adbaed1SMia Lin unsigned char *alarm_flag) 935adbaed1SMia Lin { 945adbaed1SMia Lin int flags; 955adbaed1SMia Lin 965adbaed1SMia Lin if (alarm_enable) { 975adbaed1SMia Lin dev_dbg(&client->dev, "%s:NCT3018Y_REG_CTRL\n", __func__); 985adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL); 995adbaed1SMia Lin if (flags < 0) 1005adbaed1SMia Lin return flags; 1015adbaed1SMia Lin *alarm_enable = flags & NCT3018Y_BIT_AIE; 1025adbaed1SMia Lin } 1035adbaed1SMia Lin 1045adbaed1SMia Lin if (alarm_flag) { 1055adbaed1SMia Lin dev_dbg(&client->dev, "%s:NCT3018Y_REG_ST\n", __func__); 1065adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_ST); 1075adbaed1SMia Lin if (flags < 0) 1085adbaed1SMia Lin return flags; 1095adbaed1SMia Lin *alarm_flag = flags & NCT3018Y_BIT_AF; 1105adbaed1SMia Lin } 1115adbaed1SMia Lin 1125adbaed1SMia Lin dev_dbg(&client->dev, "%s:alarm_enable:%x alarm_flag:%x\n", 1135adbaed1SMia Lin __func__, *alarm_enable, *alarm_flag); 1145adbaed1SMia Lin 1155adbaed1SMia Lin return 0; 1165adbaed1SMia Lin } 1175adbaed1SMia Lin 1185adbaed1SMia Lin static irqreturn_t nct3018y_irq(int irq, void *dev_id) 1195adbaed1SMia Lin { 1205adbaed1SMia Lin struct nct3018y *nct3018y = i2c_get_clientdata(dev_id); 1215adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 1225adbaed1SMia Lin int err; 1235adbaed1SMia Lin unsigned char alarm_flag; 1245adbaed1SMia Lin unsigned char alarm_enable; 1255adbaed1SMia Lin 1265adbaed1SMia Lin dev_dbg(&client->dev, "%s:irq:%d\n", __func__, irq); 1275adbaed1SMia Lin err = nct3018y_get_alarm_mode(nct3018y->client, &alarm_enable, &alarm_flag); 1285adbaed1SMia Lin if (err) 1295adbaed1SMia Lin return IRQ_NONE; 1305adbaed1SMia Lin 1315adbaed1SMia Lin if (alarm_flag) { 1325adbaed1SMia Lin dev_dbg(&client->dev, "%s:alarm flag:%x\n", 1335adbaed1SMia Lin __func__, alarm_flag); 1345adbaed1SMia Lin rtc_update_irq(nct3018y->rtc, 1, RTC_IRQF | RTC_AF); 1355adbaed1SMia Lin nct3018y_set_alarm_mode(nct3018y->client, 0); 1365adbaed1SMia Lin dev_dbg(&client->dev, "%s:IRQ_HANDLED\n", __func__); 1375adbaed1SMia Lin return IRQ_HANDLED; 1385adbaed1SMia Lin } 1395adbaed1SMia Lin 1405adbaed1SMia Lin return IRQ_NONE; 1415adbaed1SMia Lin } 1425adbaed1SMia Lin 1435adbaed1SMia Lin /* 1445adbaed1SMia Lin * In the routines that deal directly with the nct3018y hardware, we use 1455adbaed1SMia Lin * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. 1465adbaed1SMia Lin */ 1475adbaed1SMia Lin static int nct3018y_rtc_read_time(struct device *dev, struct rtc_time *tm) 1485adbaed1SMia Lin { 1495adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 1505adbaed1SMia Lin unsigned char buf[10]; 1515adbaed1SMia Lin int err; 1525adbaed1SMia Lin 1535adbaed1SMia Lin err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_ST, 1, buf); 1545adbaed1SMia Lin if (err < 0) 1555adbaed1SMia Lin return err; 1565adbaed1SMia Lin 1575adbaed1SMia Lin if (!buf[0]) { 1585adbaed1SMia Lin dev_dbg(&client->dev, " voltage <=1.7, date/time is not reliable.\n"); 1595adbaed1SMia Lin return -EINVAL; 1605adbaed1SMia Lin } 1615adbaed1SMia Lin 1625adbaed1SMia Lin err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SC, sizeof(buf), buf); 1635adbaed1SMia Lin if (err < 0) 1645adbaed1SMia Lin return err; 1655adbaed1SMia Lin 1665adbaed1SMia Lin tm->tm_sec = bcd2bin(buf[0] & 0x7F); 1675adbaed1SMia Lin tm->tm_min = bcd2bin(buf[2] & 0x7F); 1685adbaed1SMia Lin tm->tm_hour = bcd2bin(buf[4] & 0x3F); 1695adbaed1SMia Lin tm->tm_wday = buf[6] & 0x07; 1705adbaed1SMia Lin tm->tm_mday = bcd2bin(buf[7] & 0x3F); 1715adbaed1SMia Lin tm->tm_mon = bcd2bin(buf[8] & 0x1F) - 1; 1725adbaed1SMia Lin tm->tm_year = bcd2bin(buf[9]) + 100; 1735adbaed1SMia Lin 1745adbaed1SMia Lin return 0; 1755adbaed1SMia Lin } 1765adbaed1SMia Lin 1775adbaed1SMia Lin static int nct3018y_rtc_set_time(struct device *dev, struct rtc_time *tm) 1785adbaed1SMia Lin { 1795adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 1805adbaed1SMia Lin unsigned char buf[4] = {0}; 1815adbaed1SMia Lin int err; 1825adbaed1SMia Lin 1835adbaed1SMia Lin buf[0] = bin2bcd(tm->tm_sec); 1845adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SC, buf[0]); 1855adbaed1SMia Lin if (err < 0) { 1865adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_SC\n"); 1875adbaed1SMia Lin return err; 1885adbaed1SMia Lin } 1895adbaed1SMia Lin 1905adbaed1SMia Lin buf[0] = bin2bcd(tm->tm_min); 1915adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_MN, buf[0]); 1925adbaed1SMia Lin if (err < 0) { 1935adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_MN\n"); 1945adbaed1SMia Lin return err; 1955adbaed1SMia Lin } 1965adbaed1SMia Lin 1975adbaed1SMia Lin buf[0] = bin2bcd(tm->tm_hour); 1985adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_HR, buf[0]); 1995adbaed1SMia Lin if (err < 0) { 2005adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_HR\n"); 2015adbaed1SMia Lin return err; 2025adbaed1SMia Lin } 2035adbaed1SMia Lin 2045adbaed1SMia Lin buf[0] = tm->tm_wday & 0x07; 2055adbaed1SMia Lin buf[1] = bin2bcd(tm->tm_mday); 2065adbaed1SMia Lin buf[2] = bin2bcd(tm->tm_mon + 1); 2075adbaed1SMia Lin buf[3] = bin2bcd(tm->tm_year - 100); 2085adbaed1SMia Lin err = i2c_smbus_write_i2c_block_data(client, NCT3018Y_REG_DW, 2095adbaed1SMia Lin sizeof(buf), buf); 2105adbaed1SMia Lin if (err < 0) { 2115adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write for day and mon and year\n"); 2125adbaed1SMia Lin return -EIO; 2135adbaed1SMia Lin } 2145adbaed1SMia Lin 2155adbaed1SMia Lin return err; 2165adbaed1SMia Lin } 2175adbaed1SMia Lin 2185adbaed1SMia Lin static int nct3018y_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) 2195adbaed1SMia Lin { 2205adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 2215adbaed1SMia Lin unsigned char buf[5]; 2225adbaed1SMia Lin int err; 2235adbaed1SMia Lin 2245adbaed1SMia Lin err = i2c_smbus_read_i2c_block_data(client, NCT3018Y_REG_SCA, 2255adbaed1SMia Lin sizeof(buf), buf); 2265adbaed1SMia Lin if (err < 0) { 2275adbaed1SMia Lin dev_dbg(&client->dev, "Unable to read date\n"); 2285adbaed1SMia Lin return -EIO; 2295adbaed1SMia Lin } 2305adbaed1SMia Lin 2315adbaed1SMia Lin dev_dbg(&client->dev, "%s: raw data is sec=%02x, min=%02x hr=%02x\n", 2325adbaed1SMia Lin __func__, buf[0], buf[2], buf[4]); 2335adbaed1SMia Lin 2345adbaed1SMia Lin tm->time.tm_sec = bcd2bin(buf[0] & 0x7F); 2355adbaed1SMia Lin tm->time.tm_min = bcd2bin(buf[2] & 0x7F); 2365adbaed1SMia Lin tm->time.tm_hour = bcd2bin(buf[4] & 0x3F); 2375adbaed1SMia Lin 2385adbaed1SMia Lin err = nct3018y_get_alarm_mode(client, &tm->enabled, &tm->pending); 2395adbaed1SMia Lin if (err < 0) 2405adbaed1SMia Lin return err; 2415adbaed1SMia Lin 2425adbaed1SMia Lin dev_dbg(&client->dev, "%s:s=%d m=%d, hr=%d, enabled=%d, pending=%d\n", 2435adbaed1SMia Lin __func__, tm->time.tm_sec, tm->time.tm_min, 2445adbaed1SMia Lin tm->time.tm_hour, tm->enabled, tm->pending); 2455adbaed1SMia Lin 2465adbaed1SMia Lin return 0; 2475adbaed1SMia Lin } 2485adbaed1SMia Lin 2495adbaed1SMia Lin static int nct3018y_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm) 2505adbaed1SMia Lin { 2515adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 2525adbaed1SMia Lin int err; 2535adbaed1SMia Lin 2545adbaed1SMia Lin dev_dbg(dev, "%s, sec=%d, min=%d hour=%d tm->enabled:%d\n", 2555adbaed1SMia Lin __func__, tm->time.tm_sec, tm->time.tm_min, tm->time.tm_hour, 2565adbaed1SMia Lin tm->enabled); 2575adbaed1SMia Lin 2585adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SCA, bin2bcd(tm->time.tm_sec)); 2595adbaed1SMia Lin if (err < 0) { 2605adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_SCA\n"); 2615adbaed1SMia Lin return err; 2625adbaed1SMia Lin } 2635adbaed1SMia Lin 2645adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_MNA, bin2bcd(tm->time.tm_min)); 2655adbaed1SMia Lin if (err < 0) { 2665adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_MNA\n"); 2675adbaed1SMia Lin return err; 2685adbaed1SMia Lin } 2695adbaed1SMia Lin 2705adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_HRA, bin2bcd(tm->time.tm_hour)); 2715adbaed1SMia Lin if (err < 0) { 2725adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_HRA\n"); 2735adbaed1SMia Lin return err; 2745adbaed1SMia Lin } 2755adbaed1SMia Lin 2765adbaed1SMia Lin return nct3018y_set_alarm_mode(client, tm->enabled); 2775adbaed1SMia Lin } 2785adbaed1SMia Lin 2795adbaed1SMia Lin static int nct3018y_irq_enable(struct device *dev, unsigned int enabled) 2805adbaed1SMia Lin { 2815adbaed1SMia Lin dev_dbg(dev, "%s: alarm enable=%d\n", __func__, enabled); 2825adbaed1SMia Lin 2835adbaed1SMia Lin return nct3018y_set_alarm_mode(to_i2c_client(dev), enabled); 2845adbaed1SMia Lin } 2855adbaed1SMia Lin 2865adbaed1SMia Lin static int nct3018y_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 2875adbaed1SMia Lin { 2885adbaed1SMia Lin struct i2c_client *client = to_i2c_client(dev); 2895adbaed1SMia Lin int status, flags = 0; 2905adbaed1SMia Lin 2915adbaed1SMia Lin switch (cmd) { 2925adbaed1SMia Lin case RTC_VL_READ: 2935adbaed1SMia Lin status = i2c_smbus_read_byte_data(client, NCT3018Y_REG_ST); 2945adbaed1SMia Lin if (status < 0) 2955adbaed1SMia Lin return status; 2965adbaed1SMia Lin 2975adbaed1SMia Lin if (!(status & NCT3018Y_REG_BAT_MASK)) 2985adbaed1SMia Lin flags |= RTC_VL_DATA_INVALID; 2995adbaed1SMia Lin 3005adbaed1SMia Lin return put_user(flags, (unsigned int __user *)arg); 3015adbaed1SMia Lin 3025adbaed1SMia Lin default: 3035adbaed1SMia Lin return -ENOIOCTLCMD; 3045adbaed1SMia Lin } 3055adbaed1SMia Lin } 3065adbaed1SMia Lin 3075adbaed1SMia Lin #ifdef CONFIG_COMMON_CLK 3085adbaed1SMia Lin /* 3095adbaed1SMia Lin * Handling of the clkout 3105adbaed1SMia Lin */ 3115adbaed1SMia Lin 3125adbaed1SMia Lin #define clkout_hw_to_nct3018y(_hw) container_of(_hw, struct nct3018y, clkout_hw) 3135adbaed1SMia Lin 3145adbaed1SMia Lin static const int clkout_rates[] = { 3155adbaed1SMia Lin 32768, 3165adbaed1SMia Lin 1024, 3175adbaed1SMia Lin 32, 3185adbaed1SMia Lin 1, 3195adbaed1SMia Lin }; 3205adbaed1SMia Lin 3215adbaed1SMia Lin static unsigned long nct3018y_clkout_recalc_rate(struct clk_hw *hw, 3225adbaed1SMia Lin unsigned long parent_rate) 3235adbaed1SMia Lin { 3245adbaed1SMia Lin struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw); 3255adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 3265adbaed1SMia Lin int flags; 3275adbaed1SMia Lin 3285adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO); 3295adbaed1SMia Lin if (flags < 0) 3305adbaed1SMia Lin return 0; 3315adbaed1SMia Lin 3325adbaed1SMia Lin flags &= NCT3018Y_REG_CLKO_F_MASK; 3335adbaed1SMia Lin return clkout_rates[flags]; 3345adbaed1SMia Lin } 3355adbaed1SMia Lin 3365adbaed1SMia Lin static long nct3018y_clkout_round_rate(struct clk_hw *hw, unsigned long rate, 3375adbaed1SMia Lin unsigned long *prate) 3385adbaed1SMia Lin { 3395adbaed1SMia Lin int i; 3405adbaed1SMia Lin 3415adbaed1SMia Lin for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) 3425adbaed1SMia Lin if (clkout_rates[i] <= rate) 3435adbaed1SMia Lin return clkout_rates[i]; 3445adbaed1SMia Lin 3455adbaed1SMia Lin return 0; 3465adbaed1SMia Lin } 3475adbaed1SMia Lin 3485adbaed1SMia Lin static int nct3018y_clkout_set_rate(struct clk_hw *hw, unsigned long rate, 3495adbaed1SMia Lin unsigned long parent_rate) 3505adbaed1SMia Lin { 3515adbaed1SMia Lin struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw); 3525adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 3535adbaed1SMia Lin int i, flags; 3545adbaed1SMia Lin 3555adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO); 3565adbaed1SMia Lin if (flags < 0) 3575adbaed1SMia Lin return flags; 3585adbaed1SMia Lin 3595adbaed1SMia Lin for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) 3605adbaed1SMia Lin if (clkout_rates[i] == rate) { 3615adbaed1SMia Lin flags &= ~NCT3018Y_REG_CLKO_F_MASK; 3625adbaed1SMia Lin flags |= i; 3635adbaed1SMia Lin return i2c_smbus_write_byte_data(client, NCT3018Y_REG_CLKO, flags); 3645adbaed1SMia Lin } 3655adbaed1SMia Lin 3665adbaed1SMia Lin return -EINVAL; 3675adbaed1SMia Lin } 3685adbaed1SMia Lin 3695adbaed1SMia Lin static int nct3018y_clkout_control(struct clk_hw *hw, bool enable) 3705adbaed1SMia Lin { 3715adbaed1SMia Lin struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw); 3725adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 3735adbaed1SMia Lin int flags; 3745adbaed1SMia Lin 3755adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO); 3765adbaed1SMia Lin if (flags < 0) 3775adbaed1SMia Lin return flags; 3785adbaed1SMia Lin 3795adbaed1SMia Lin if (enable) 3805adbaed1SMia Lin flags |= NCT3018Y_REG_CLKO_CKE; 3815adbaed1SMia Lin else 3825adbaed1SMia Lin flags &= ~NCT3018Y_REG_CLKO_CKE; 3835adbaed1SMia Lin 3845adbaed1SMia Lin return i2c_smbus_write_byte_data(client, NCT3018Y_REG_CLKO, flags); 3855adbaed1SMia Lin } 3865adbaed1SMia Lin 3875adbaed1SMia Lin static int nct3018y_clkout_prepare(struct clk_hw *hw) 3885adbaed1SMia Lin { 3895adbaed1SMia Lin return nct3018y_clkout_control(hw, 1); 3905adbaed1SMia Lin } 3915adbaed1SMia Lin 3925adbaed1SMia Lin static void nct3018y_clkout_unprepare(struct clk_hw *hw) 3935adbaed1SMia Lin { 3945adbaed1SMia Lin nct3018y_clkout_control(hw, 0); 3955adbaed1SMia Lin } 3965adbaed1SMia Lin 3975adbaed1SMia Lin static int nct3018y_clkout_is_prepared(struct clk_hw *hw) 3985adbaed1SMia Lin { 3995adbaed1SMia Lin struct nct3018y *nct3018y = clkout_hw_to_nct3018y(hw); 4005adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 4015adbaed1SMia Lin int flags; 4025adbaed1SMia Lin 4035adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CLKO); 4045adbaed1SMia Lin if (flags < 0) 4055adbaed1SMia Lin return flags; 4065adbaed1SMia Lin 4075adbaed1SMia Lin return flags & NCT3018Y_REG_CLKO_CKE; 4085adbaed1SMia Lin } 4095adbaed1SMia Lin 4105adbaed1SMia Lin static const struct clk_ops nct3018y_clkout_ops = { 4115adbaed1SMia Lin .prepare = nct3018y_clkout_prepare, 4125adbaed1SMia Lin .unprepare = nct3018y_clkout_unprepare, 4135adbaed1SMia Lin .is_prepared = nct3018y_clkout_is_prepared, 4145adbaed1SMia Lin .recalc_rate = nct3018y_clkout_recalc_rate, 4155adbaed1SMia Lin .round_rate = nct3018y_clkout_round_rate, 4165adbaed1SMia Lin .set_rate = nct3018y_clkout_set_rate, 4175adbaed1SMia Lin }; 4185adbaed1SMia Lin 4195adbaed1SMia Lin static struct clk *nct3018y_clkout_register_clk(struct nct3018y *nct3018y) 4205adbaed1SMia Lin { 4215adbaed1SMia Lin struct i2c_client *client = nct3018y->client; 4225adbaed1SMia Lin struct device_node *node = client->dev.of_node; 4235adbaed1SMia Lin struct clk *clk; 4245adbaed1SMia Lin struct clk_init_data init; 4255adbaed1SMia Lin 4265adbaed1SMia Lin init.name = "nct3018y-clkout"; 4275adbaed1SMia Lin init.ops = &nct3018y_clkout_ops; 4285adbaed1SMia Lin init.flags = 0; 4295adbaed1SMia Lin init.parent_names = NULL; 4305adbaed1SMia Lin init.num_parents = 0; 4315adbaed1SMia Lin nct3018y->clkout_hw.init = &init; 4325adbaed1SMia Lin 4335adbaed1SMia Lin /* optional override of the clockname */ 4345adbaed1SMia Lin of_property_read_string(node, "clock-output-names", &init.name); 4355adbaed1SMia Lin 4365adbaed1SMia Lin /* register the clock */ 4375adbaed1SMia Lin clk = devm_clk_register(&client->dev, &nct3018y->clkout_hw); 4385adbaed1SMia Lin 4395adbaed1SMia Lin if (!IS_ERR(clk)) 4405adbaed1SMia Lin of_clk_add_provider(node, of_clk_src_simple_get, clk); 4415adbaed1SMia Lin 4425adbaed1SMia Lin return clk; 4435adbaed1SMia Lin } 4445adbaed1SMia Lin #endif 4455adbaed1SMia Lin 4465adbaed1SMia Lin static const struct rtc_class_ops nct3018y_rtc_ops = { 4475adbaed1SMia Lin .read_time = nct3018y_rtc_read_time, 4485adbaed1SMia Lin .set_time = nct3018y_rtc_set_time, 4495adbaed1SMia Lin .read_alarm = nct3018y_rtc_read_alarm, 4505adbaed1SMia Lin .set_alarm = nct3018y_rtc_set_alarm, 4515adbaed1SMia Lin .alarm_irq_enable = nct3018y_irq_enable, 4525adbaed1SMia Lin .ioctl = nct3018y_ioctl, 4535adbaed1SMia Lin }; 4545adbaed1SMia Lin 455c050dedbSUwe Kleine-König static int nct3018y_probe(struct i2c_client *client) 4565adbaed1SMia Lin { 4575adbaed1SMia Lin struct nct3018y *nct3018y; 4585adbaed1SMia Lin int err, flags; 4595adbaed1SMia Lin 4605adbaed1SMia Lin if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | 4615adbaed1SMia Lin I2C_FUNC_SMBUS_BYTE | 4625adbaed1SMia Lin I2C_FUNC_SMBUS_BLOCK_DATA)) 4635adbaed1SMia Lin return -ENODEV; 4645adbaed1SMia Lin 4655adbaed1SMia Lin nct3018y = devm_kzalloc(&client->dev, sizeof(struct nct3018y), 4665adbaed1SMia Lin GFP_KERNEL); 4675adbaed1SMia Lin if (!nct3018y) 4685adbaed1SMia Lin return -ENOMEM; 4695adbaed1SMia Lin 4705adbaed1SMia Lin i2c_set_clientdata(client, nct3018y); 4715adbaed1SMia Lin nct3018y->client = client; 4725adbaed1SMia Lin device_set_wakeup_capable(&client->dev, 1); 4735adbaed1SMia Lin 4745adbaed1SMia Lin flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL); 4755adbaed1SMia Lin if (flags < 0) { 4765adbaed1SMia Lin dev_dbg(&client->dev, "%s: read error\n", __func__); 4775adbaed1SMia Lin return flags; 4785adbaed1SMia Lin } else if (flags & NCT3018Y_BIT_TWO) { 4795adbaed1SMia Lin dev_dbg(&client->dev, "%s: NCT3018Y_BIT_TWO is set\n", __func__); 4805adbaed1SMia Lin } 4815adbaed1SMia Lin 4825adbaed1SMia Lin flags = NCT3018Y_BIT_TWO; 4835adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags); 4845adbaed1SMia Lin if (err < 0) { 4855adbaed1SMia Lin dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL\n"); 4865adbaed1SMia Lin return err; 4875adbaed1SMia Lin } 4885adbaed1SMia Lin 4895adbaed1SMia Lin flags = 0; 4905adbaed1SMia Lin err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_ST, flags); 4915adbaed1SMia Lin if (err < 0) { 4925adbaed1SMia Lin dev_dbg(&client->dev, "%s: write error\n", __func__); 4935adbaed1SMia Lin return err; 4945adbaed1SMia Lin } 4955adbaed1SMia Lin 4965adbaed1SMia Lin nct3018y->rtc = devm_rtc_allocate_device(&client->dev); 4975adbaed1SMia Lin if (IS_ERR(nct3018y->rtc)) 4985adbaed1SMia Lin return PTR_ERR(nct3018y->rtc); 4995adbaed1SMia Lin 5005adbaed1SMia Lin nct3018y->rtc->ops = &nct3018y_rtc_ops; 5015adbaed1SMia Lin nct3018y->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 5025adbaed1SMia Lin nct3018y->rtc->range_max = RTC_TIMESTAMP_END_2099; 5035adbaed1SMia Lin 5045adbaed1SMia Lin if (client->irq > 0) { 5055adbaed1SMia Lin err = devm_request_threaded_irq(&client->dev, client->irq, 5065adbaed1SMia Lin NULL, nct3018y_irq, 5075adbaed1SMia Lin IRQF_ONESHOT | IRQF_TRIGGER_FALLING, 5085adbaed1SMia Lin "nct3018y", client); 5095adbaed1SMia Lin if (err) { 5105adbaed1SMia Lin dev_dbg(&client->dev, "unable to request IRQ %d\n", client->irq); 5115adbaed1SMia Lin return err; 5125adbaed1SMia Lin } 5135adbaed1SMia Lin } else { 5145adbaed1SMia Lin clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, nct3018y->rtc->features); 5155adbaed1SMia Lin clear_bit(RTC_FEATURE_ALARM, nct3018y->rtc->features); 5165adbaed1SMia Lin } 5175adbaed1SMia Lin 5185adbaed1SMia Lin #ifdef CONFIG_COMMON_CLK 5195adbaed1SMia Lin /* register clk in common clk framework */ 5205adbaed1SMia Lin nct3018y_clkout_register_clk(nct3018y); 5215adbaed1SMia Lin #endif 5225adbaed1SMia Lin 5235adbaed1SMia Lin return devm_rtc_register_device(nct3018y->rtc); 5245adbaed1SMia Lin } 5255adbaed1SMia Lin 5265adbaed1SMia Lin static const struct i2c_device_id nct3018y_id[] = { 5275adbaed1SMia Lin { "nct3018y", 0 }, 5285adbaed1SMia Lin { } 5295adbaed1SMia Lin }; 5305adbaed1SMia Lin MODULE_DEVICE_TABLE(i2c, nct3018y_id); 5315adbaed1SMia Lin 5325adbaed1SMia Lin static const struct of_device_id nct3018y_of_match[] = { 5335adbaed1SMia Lin { .compatible = "nuvoton,nct3018y" }, 5345adbaed1SMia Lin {} 5355adbaed1SMia Lin }; 5365adbaed1SMia Lin MODULE_DEVICE_TABLE(of, nct3018y_of_match); 5375adbaed1SMia Lin 5385adbaed1SMia Lin static struct i2c_driver nct3018y_driver = { 5395adbaed1SMia Lin .driver = { 5405adbaed1SMia Lin .name = "rtc-nct3018y", 541*4f3688dcSZhu Wang .of_match_table = nct3018y_of_match, 5425adbaed1SMia Lin }, 54331b0cecbSUwe Kleine-König .probe = nct3018y_probe, 5445adbaed1SMia Lin .id_table = nct3018y_id, 5455adbaed1SMia Lin }; 5465adbaed1SMia Lin 5475adbaed1SMia Lin module_i2c_driver(nct3018y_driver); 5485adbaed1SMia Lin 5495adbaed1SMia Lin MODULE_AUTHOR("Medad CChien <ctcchien@nuvoton.com>"); 5505adbaed1SMia Lin MODULE_AUTHOR("Mia Lin <mimi05633@gmail.com>"); 5515adbaed1SMia Lin MODULE_DESCRIPTION("Nuvoton NCT3018Y RTC driver"); 5525adbaed1SMia Lin MODULE_LICENSE("GPL"); 553