From: Mia Lin <mimi05633@gmail.com>
To: avifishman70@gmail.com, tmaimon77@gmail.com,
tali.perry1@gmail.com, venture@google.com, yuenn@google.com,
benjaminfair@google.com, a.zummo@towertech.it,
alexandre.belloni@bootlin.com, KWLIU@nuvoton.com,
JJLIU0@nuvoton.com, KFLIN@nuvoton.com, mylin1@nuvoton.com
Cc: openbmc@lists.ozlabs.org, linux-rtc@vger.kernel.org,
linux-kernel@vger.kernel.org, Mia Lin <mimi05633@gmail.com>
Subject: [PATCH v6 1/1] rtc: nuvoton: Compatible with NCT3015Y-R and NCT3018Y-R
Date: Wed, 13 Sep 2023 09:37:19 +0800 [thread overview]
Message-ID: <20230913013719.8342-2-mimi05633@gmail.com> (raw)
In-Reply-To: <20230913013719.8342-1-mimi05633@gmail.com>
The NCT3015Y-R and NCT3018Y-R use the same datasheet
but have different topologies as follows.
- Topology (Only 1st i2c can set TWO bit and HF bit)
In NCT3015Y-R,
rtc 1st i2c is connected to a host CPU
rtc 2nd i2c is connected to a BMC
In NCT3018Y-R,
rtc 1st i2c is connected to a BMC
rtc 2nd i2c is connected to a host CPU
In order to be compatible with NCT3015Y-R and NCT3018Y-R,
- In probe,
If part number is NCT3018Y-R, only set HF bit to 24-Hour format.
Else, do nothing
- In set_time,
If part number is NCT3018Y-R && TWO bit is 0,
change TWO bit to 1, and restore TWO bit after updating time.
Signed-off-by: Mia Lin <mimi05633@gmail.com>
---
drivers/rtc/rtc-nct3018y.c | 52 +++++++++++++++++++++++++++++++++-----
1 file changed, 46 insertions(+), 6 deletions(-)
diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c
index ed4e606be8e5..b006b58e15e2 100644
--- a/drivers/rtc/rtc-nct3018y.c
+++ b/drivers/rtc/rtc-nct3018y.c
@@ -23,6 +23,7 @@
#define NCT3018Y_REG_CTRL 0x0A /* timer control */
#define NCT3018Y_REG_ST 0x0B /* status */
#define NCT3018Y_REG_CLKO 0x0C /* clock out */
+#define NCT3018Y_REG_PART 0x21 /* part info */
#define NCT3018Y_BIT_AF BIT(7)
#define NCT3018Y_BIT_ST BIT(7)
@@ -37,10 +38,12 @@
#define NCT3018Y_REG_BAT_MASK 0x07
#define NCT3018Y_REG_CLKO_F_MASK 0x03 /* frequenc mask */
#define NCT3018Y_REG_CLKO_CKE 0x80 /* clock out enabled */
+#define NCT3018Y_REG_PART_NCT3018Y 0x02
struct nct3018y {
struct rtc_device *rtc;
struct i2c_client *client;
+ int part_num;
#ifdef CONFIG_COMMON_CLK
struct clk_hw clkout_hw;
#endif
@@ -177,8 +180,27 @@ static int nct3018y_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int nct3018y_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
+ struct nct3018y *nct3018y = dev_get_drvdata(dev);
unsigned char buf[4] = {0};
- int err;
+ int err, flags;
+ int restore_flags = 0;
+
+ flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
+ if (flags < 0) {
+ dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_CTRL.\n");
+ return flags;
+ }
+
+ /* Check and set TWO bit */
+ if ((nct3018y->part_num & NCT3018Y_REG_PART_NCT3018Y) && !(flags & NCT3018Y_BIT_TWO)) {
+ restore_flags = 1;
+ flags |= NCT3018Y_BIT_TWO;
+ err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
+ if (err < 0) {
+ dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
+ return err;
+ }
+ }
buf[0] = bin2bcd(tm->tm_sec);
err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SC, buf[0]);
@@ -212,6 +234,18 @@ static int nct3018y_rtc_set_time(struct device *dev, struct rtc_time *tm)
return -EIO;
}
+ /* Restore TWO bit */
+ if (restore_flags) {
+ if (nct3018y->part_num & NCT3018Y_REG_PART_NCT3018Y)
+ flags &= ~NCT3018Y_BIT_TWO;
+
+ err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
+ if (err < 0) {
+ dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
+ return err;
+ }
+ }
+
return err;
}
@@ -479,11 +513,17 @@ static int nct3018y_probe(struct i2c_client *client)
dev_dbg(&client->dev, "%s: NCT3018Y_BIT_TWO is set\n", __func__);
}
- flags = NCT3018Y_BIT_TWO;
- err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
- if (err < 0) {
- dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL\n");
- return err;
+ nct3018y->part_num = i2c_smbus_read_byte_data(client, NCT3018Y_REG_PART);
+ if (nct3018y->part_num < 0) {
+ dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_PART.\n");
+ return nct3018y->part_num;
+ } else if (nct3018y->part_num & NCT3018Y_REG_PART_NCT3018Y) {
+ flags = NCT3018Y_BIT_HF;
+ err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
+ if (err < 0) {
+ dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
+ return err;
+ }
}
flags = 0;
--
2.17.1
WARNING: multiple messages have this Message-ID (diff)
From: Mia Lin <mimi05633@gmail.com>
To: avifishman70@gmail.com, tmaimon77@gmail.com,
tali.perry1@gmail.com, venture@google.com, yuenn@google.com,
benjaminfair@google.com, a.zummo@towertech.it,
alexandre.belloni@bootlin.com, KWLIU@nuvoton.com,
JJLIU0@nuvoton.com, KFLIN@nuvoton.com, mylin1@nuvoton.com
Cc: linux-rtc@vger.kernel.org, openbmc@lists.ozlabs.org,
Mia Lin <mimi05633@gmail.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH v6 1/1] rtc: nuvoton: Compatible with NCT3015Y-R and NCT3018Y-R
Date: Wed, 13 Sep 2023 09:37:19 +0800 [thread overview]
Message-ID: <20230913013719.8342-2-mimi05633@gmail.com> (raw)
In-Reply-To: <20230913013719.8342-1-mimi05633@gmail.com>
The NCT3015Y-R and NCT3018Y-R use the same datasheet
but have different topologies as follows.
- Topology (Only 1st i2c can set TWO bit and HF bit)
In NCT3015Y-R,
rtc 1st i2c is connected to a host CPU
rtc 2nd i2c is connected to a BMC
In NCT3018Y-R,
rtc 1st i2c is connected to a BMC
rtc 2nd i2c is connected to a host CPU
In order to be compatible with NCT3015Y-R and NCT3018Y-R,
- In probe,
If part number is NCT3018Y-R, only set HF bit to 24-Hour format.
Else, do nothing
- In set_time,
If part number is NCT3018Y-R && TWO bit is 0,
change TWO bit to 1, and restore TWO bit after updating time.
Signed-off-by: Mia Lin <mimi05633@gmail.com>
---
drivers/rtc/rtc-nct3018y.c | 52 +++++++++++++++++++++++++++++++++-----
1 file changed, 46 insertions(+), 6 deletions(-)
diff --git a/drivers/rtc/rtc-nct3018y.c b/drivers/rtc/rtc-nct3018y.c
index ed4e606be8e5..b006b58e15e2 100644
--- a/drivers/rtc/rtc-nct3018y.c
+++ b/drivers/rtc/rtc-nct3018y.c
@@ -23,6 +23,7 @@
#define NCT3018Y_REG_CTRL 0x0A /* timer control */
#define NCT3018Y_REG_ST 0x0B /* status */
#define NCT3018Y_REG_CLKO 0x0C /* clock out */
+#define NCT3018Y_REG_PART 0x21 /* part info */
#define NCT3018Y_BIT_AF BIT(7)
#define NCT3018Y_BIT_ST BIT(7)
@@ -37,10 +38,12 @@
#define NCT3018Y_REG_BAT_MASK 0x07
#define NCT3018Y_REG_CLKO_F_MASK 0x03 /* frequenc mask */
#define NCT3018Y_REG_CLKO_CKE 0x80 /* clock out enabled */
+#define NCT3018Y_REG_PART_NCT3018Y 0x02
struct nct3018y {
struct rtc_device *rtc;
struct i2c_client *client;
+ int part_num;
#ifdef CONFIG_COMMON_CLK
struct clk_hw clkout_hw;
#endif
@@ -177,8 +180,27 @@ static int nct3018y_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int nct3018y_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
+ struct nct3018y *nct3018y = dev_get_drvdata(dev);
unsigned char buf[4] = {0};
- int err;
+ int err, flags;
+ int restore_flags = 0;
+
+ flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
+ if (flags < 0) {
+ dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_CTRL.\n");
+ return flags;
+ }
+
+ /* Check and set TWO bit */
+ if ((nct3018y->part_num & NCT3018Y_REG_PART_NCT3018Y) && !(flags & NCT3018Y_BIT_TWO)) {
+ restore_flags = 1;
+ flags |= NCT3018Y_BIT_TWO;
+ err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
+ if (err < 0) {
+ dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
+ return err;
+ }
+ }
buf[0] = bin2bcd(tm->tm_sec);
err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_SC, buf[0]);
@@ -212,6 +234,18 @@ static int nct3018y_rtc_set_time(struct device *dev, struct rtc_time *tm)
return -EIO;
}
+ /* Restore TWO bit */
+ if (restore_flags) {
+ if (nct3018y->part_num & NCT3018Y_REG_PART_NCT3018Y)
+ flags &= ~NCT3018Y_BIT_TWO;
+
+ err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
+ if (err < 0) {
+ dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
+ return err;
+ }
+ }
+
return err;
}
@@ -479,11 +513,17 @@ static int nct3018y_probe(struct i2c_client *client)
dev_dbg(&client->dev, "%s: NCT3018Y_BIT_TWO is set\n", __func__);
}
- flags = NCT3018Y_BIT_TWO;
- err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
- if (err < 0) {
- dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL\n");
- return err;
+ nct3018y->part_num = i2c_smbus_read_byte_data(client, NCT3018Y_REG_PART);
+ if (nct3018y->part_num < 0) {
+ dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_PART.\n");
+ return nct3018y->part_num;
+ } else if (nct3018y->part_num & NCT3018Y_REG_PART_NCT3018Y) {
+ flags = NCT3018Y_BIT_HF;
+ err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
+ if (err < 0) {
+ dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
+ return err;
+ }
}
flags = 0;
--
2.17.1
next prev parent reply other threads:[~2023-09-13 1:37 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-13 1:37 [PATCH v6 0/1] Compatible with NCT3015Y-R and NCT3018Y-R Mia Lin
2023-09-13 1:37 ` Mia Lin
2023-09-13 1:37 ` Mia Lin [this message]
2023-09-13 1:37 ` [PATCH v6 1/1] rtc: nuvoton: " Mia Lin
2023-11-03 23:16 ` Alexandre Belloni
2023-11-03 23:16 ` Alexandre Belloni
2023-11-03 23:17 ` Alexandre Belloni
2023-11-03 23:17 ` Alexandre Belloni
2023-11-09 12:33 ` Mining Lin
2023-11-09 12:33 ` Mining Lin
2023-11-09 12:31 ` Mining Lin
2023-11-09 12:31 ` Mining Lin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230913013719.8342-2-mimi05633@gmail.com \
--to=mimi05633@gmail.com \
--cc=JJLIU0@nuvoton.com \
--cc=KFLIN@nuvoton.com \
--cc=KWLIU@nuvoton.com \
--cc=a.zummo@towertech.it \
--cc=alexandre.belloni@bootlin.com \
--cc=avifishman70@gmail.com \
--cc=benjaminfair@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rtc@vger.kernel.org \
--cc=mylin1@nuvoton.com \
--cc=openbmc@lists.ozlabs.org \
--cc=tali.perry1@gmail.com \
--cc=tmaimon77@gmail.com \
--cc=venture@google.com \
--cc=yuenn@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.