Skip to content

Commit 14688f1

Browse files
minying0829alexandrebelloni
authored andcommitted
rtc: nuvoton: Compatible with NCT3015Y-R and NCT3018Y-R
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> Link: https://lore.kernel.org/r/20231113103807.1036978-2-mimi05633@gmail.com Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
1 parent f5334aa commit 14688f1

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

drivers/rtc/rtc-nct3018y.c

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define NCT3018Y_REG_CTRL 0x0A /* timer control */
2424
#define NCT3018Y_REG_ST 0x0B /* status */
2525
#define NCT3018Y_REG_CLKO 0x0C /* clock out */
26+
#define NCT3018Y_REG_PART 0x21 /* part info */
2627

2728
#define NCT3018Y_BIT_AF BIT(7)
2829
#define NCT3018Y_BIT_ST BIT(7)
@@ -37,10 +38,12 @@
3738
#define NCT3018Y_REG_BAT_MASK 0x07
3839
#define NCT3018Y_REG_CLKO_F_MASK 0x03 /* frequenc mask */
3940
#define NCT3018Y_REG_CLKO_CKE 0x80 /* clock out enabled */
41+
#define NCT3018Y_REG_PART_NCT3018Y 0x02
4042

4143
struct nct3018y {
4244
struct rtc_device *rtc;
4345
struct i2c_client *client;
46+
int part_num;
4447
#ifdef CONFIG_COMMON_CLK
4548
struct clk_hw clkout_hw;
4649
#endif
@@ -177,8 +180,27 @@ static int nct3018y_rtc_read_time(struct device *dev, struct rtc_time *tm)
177180
static int nct3018y_rtc_set_time(struct device *dev, struct rtc_time *tm)
178181
{
179182
struct i2c_client *client = to_i2c_client(dev);
183+
struct nct3018y *nct3018y = dev_get_drvdata(dev);
180184
unsigned char buf[4] = {0};
181-
int err;
185+
int err, flags;
186+
int restore_flags = 0;
187+
188+
flags = i2c_smbus_read_byte_data(client, NCT3018Y_REG_CTRL);
189+
if (flags < 0) {
190+
dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_CTRL.\n");
191+
return flags;
192+
}
193+
194+
/* Check and set TWO bit */
195+
if (nct3018y->part_num == NCT3018Y_REG_PART_NCT3018Y && !(flags & NCT3018Y_BIT_TWO)) {
196+
restore_flags = 1;
197+
flags |= NCT3018Y_BIT_TWO;
198+
err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
199+
if (err < 0) {
200+
dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
201+
return err;
202+
}
203+
}
182204

183205
buf[0] = bin2bcd(tm->tm_sec);
184206
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)
212234
return -EIO;
213235
}
214236

237+
/* Restore TWO bit */
238+
if (restore_flags) {
239+
if (nct3018y->part_num == NCT3018Y_REG_PART_NCT3018Y)
240+
flags &= ~NCT3018Y_BIT_TWO;
241+
242+
err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
243+
if (err < 0) {
244+
dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
245+
return err;
246+
}
247+
}
248+
215249
return err;
216250
}
217251

@@ -479,11 +513,17 @@ static int nct3018y_probe(struct i2c_client *client)
479513
dev_dbg(&client->dev, "%s: NCT3018Y_BIT_TWO is set\n", __func__);
480514
}
481515

482-
flags = NCT3018Y_BIT_TWO;
483-
err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
484-
if (err < 0) {
485-
dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL\n");
486-
return err;
516+
nct3018y->part_num = i2c_smbus_read_byte_data(client, NCT3018Y_REG_PART);
517+
if (nct3018y->part_num < 0) {
518+
dev_dbg(&client->dev, "Failed to read NCT3018Y_REG_PART.\n");
519+
return nct3018y->part_num;
520+
} else if (nct3018y->part_num == NCT3018Y_REG_PART_NCT3018Y) {
521+
flags = NCT3018Y_BIT_HF;
522+
err = i2c_smbus_write_byte_data(client, NCT3018Y_REG_CTRL, flags);
523+
if (err < 0) {
524+
dev_dbg(&client->dev, "Unable to write NCT3018Y_REG_CTRL.\n");
525+
return err;
526+
}
487527
}
488528

489529
flags = 0;

0 commit comments

Comments
 (0)