Skip to contentSkip to conversation

rtc-rv3029c2: Add trickle charger

PATCH In review Michael Büsch 2 participants 27 messages Mar 1, 2016 – Mar 5, 2016 1 message not in the archive Real time clock (RTC)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 rtc-rv3029c2: Add trickle charger

This adds a device tree property to enable the tricke charger at some to be configured resistance.
If the property is left out, the trickle charger is disabled.

The kconfig name is also changed to include the chip number as there are other MicroCrystal RTCs.

Also a "rv3029" device ID was added, because the C2 suffix does not appear in latest chip versions and datasheet versions.

---
 drivers/rtc/Kconfig        |   2 +-
 drivers/rtc/rtc-rv3029c2.c | 335 ++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 299 insertions(+), 38 deletions(-)
drivers/rtc/Kconfig +1 -1
index 376322f..c37f535 100644
@@ -595,7 +595,7 @@ config RTC_DRV_EM3027
 	  will be called rtc-em3027.
 
 config RTC_DRV_RV3029C2
-	tristate "Micro Crystal RTC"
+	tristate "Micro Crystal RV3029(C2)"
 	help
 	  If you say yes here you get support for the Micro Crystal
 	  RV3029-C2 RTC chips.
drivers/rtc/rtc-rv3029c2.c +298 -37

433 lines not on this page · raw message

Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#1 lore raw

Hi,

Quoted 7 lines · On 01/03/2016 at 21:33:22 +0100, Michael B=C3=BCsch wrote :

This adds a device tree property to enable the tricke charger at some to be configured resistance.
If the property is left out, the trickle charger is disabled. =20
The kconfig name is also changed to include the chip number as there are other MicroCrystal RTCs.
=20

This should have been another patch and will conflict with my patch doing exactly that, see rtc-next.

Quoted 3 lines

Also a "rv3029" device ID was added, because the C2 suffix does not appear in latest chip versions and datasheet versions. =20

This change should also be part of another patch.

You may as well stop adding that suffix to newly added functions and macros.
I'd also take a preliminary patch removing the c2 prefix from current functions and macros.

Unfortunately, we can't rename the file because this will break scripts loading modules.

drivers/rtc/rtc-rv3029c2.c line 32

Quoted 11 lines

/* Register map */
/* control section */
#define RV3029C2_ONOFF_CTRL 0x00

drivers/rtc/rtc-rv3029c2.c +8 -0
+#define RV3029C2_ONOFF_CTRL_WE		(1 << 0)
+#define RV3029C2_ONOFF_CTRL_TE		(1 << 1)
+#define RV3029C2_ONOFF_CTRL_TAR		(1 << 2)
+#define RV3029C2_ONOFF_CTRL_EERE	(1 << 3)
+#define RV3029C2_ONOFF_CTRL_SRON	(1 << 4)
+#define RV3029C2_ONOFF_CTRL_TD0		(1 << 5)
+#define RV3029C2_ONOFF_CTRL_TD1		(1 << 6)
+#define RV3029C2_ONOFF_CTRL_CLKINT	(1 << 7)

You didn't use --strict for checkpatch, please use BIT() and also correct the alignments issues.

drivers/rtc/rtc-rv3029c2.c line 38

Quoted 6 lines

#define RV3029C2_IRQ_CTRL 0x01
#define RV3029C2_IRQ_CTRL_AIE (1 << 0)

drivers/rtc/rtc-rv3029c2.c +4 -0
+#define RV3029C2_IRQ_CTRL_TIE		(1 << 1)
+#define RV3029C2_IRQ_CTRL_V1IE		(1 << 2)
+#define RV3029C2_IRQ_CTRL_V2IE		(1 << 3)
+#define RV3029C2_IRQ_CTRL_SRIE		(1 << 4)

I'm pretty sure many you are adding many of those but not using them yet.

Quoted 7 lines

/* user ram section */
#define RV3029C2_USR1_RAM_PAGE 0x38

drivers/rtc/rtc-rv3029c2.c +0 -0
@@ -84,6 +111,7 @@
 #define RV3029C2_USR2_RAM_PAGE		0x3C
 #define RV3029C2_USR2_SECTION_LEN	0x04

=20
+

spurious blank line

drivers/rtc/rtc-rv3029c2.c rv3029c2_i2c_write_regs(struct i2c_client *client, u=

Quoted 4 lines

static int
rv3029c2_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,

drivers/rtc/rtc-rv3029c2.c +0 -0
 	unsigned len)
@@ -114,6 +142,24 @@ rv3029c2_i2c_write_regs(struct i2c_client *client, u=

8 reg, u8 const buf[],

Quoted 4 lines
(quoted diff) +0 -0
 }

=20
static int
+rv3029c2_i2c_maskset_reg(struct i2c_client *client, u8 reg, u8 mask, u8 =

set)

I'd prefer that function named _update_bits

drivers/rtc/rtc-rv3029c2.c rv3029c2_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], · line 147

Quoted 2 lines
drivers/rtc/rtc-rv3029c2.c +2 -0
+{
+	u8 buf[1];

couldn't that be u8 buf?

drivers/rtc/rtc-rv3029c2.c rv3029c2_i2c_set_sr(struct i2c_client *client, u8 v=

Quoted 19 lines
drivers/rtc/rtc-rv3029c2.c +15 -0
+	int ret;
+
+	ret =3D rv3029c2_i2c_read_regs(client, reg, buf, 1);
+	if (ret < 0)
+		return ret;
+	buf[0] &=3D mask;
+	buf[0] |=3D set;
+	ret =3D rv3029c2_i2c_write_regs(client, reg, buf, 1);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int
 rv3029c2_i2c_get_sr(struct i2c_client *client, u8 *buf)
 {
 	int ret =3D rv3029c2_i2c_read_regs(client, RV3029C2_STATUS, buf, 1);
@@ -138,6 +184,128 @@ rv3029c2_i2c_set_sr(struct i2c_client *client, u8 v=

al)

Quoted 39 lines
drivers/rtc/rtc-rv3029c2.c +0 -0
 	return 0;
 }

=20

drivers/rtc/rtc-rv3029c2.c +36 -0
+static int rv3029c2_eeprom_busywait(struct i2c_client *client)
+{
+	int i, ret;
+	u8 sr;
+
+	for (i =3D 100; i > 0; i--) {
+		ret =3D rv3029c2_i2c_get_sr(client, &sr);
+		if (ret < 0)
+			break;
+		if (!(sr & RV3029C2_STATUS_EEBUSY))
+			break;
+		usleep_range(1000, 10000);
+	}
+	if (i <=3D 0) {
+		dev_err(&client->dev, "EEPROM busy wait timeout.\n");
+		return -ETIMEDOUT;
+	}
+
+	return ret;
+}
+
+static int rv3029c2_eeprom_exit(struct i2c_client *client)
+{
+	/* Re-enable eeprom refresh */
+	return rv3029c2_i2c_maskset_reg(client, RV3029C2_ONOFF_CTRL,
+					0xFF, RV3029C2_ONOFF_CTRL_EERE);
+}
+
+static int rv3029c2_eeprom_enter(struct i2c_client *client)
+{
+	int i, ret;
+	u8 sr;
+
+	/* Check whether we are in the allowed voltage range. */
+	for (i =3D 100; i > 0; i--) {
+		ret =3D rv3029c2_i2c_get_sr(client, &sr);

drivers/rtc/rtc-rv3029c2.c rv3029c2_i2c_set_sr(struct i2c_client *client, u8 val) · line 232

Quoted 10 lines
drivers/rtc/rtc-rv3029c2.c +10 -0
+		if (ret < 0)
+			return ret;
+		if (!(sr & (RV3029C2_STATUS_VLOW1 | RV3029C2_STATUS_VLOW2)))
+			break;
+
+		sr &=3D ~RV3029C2_STATUS_VLOW1;
+		sr &=3D ~RV3029C2_STATUS_VLOW2;
+		ret =3D rv3029c2_i2c_set_sr(client, sr);
+		if (ret < 0)
+			return ret;

I wouldn't reset the VLOW1 and VLOW2 flags here. Just bail out if the voltage is not sufficient. I don't think that condition will actually get better simply by waiting.

Proper VLOW1 and VLOW2 handling for that RTC is something I have in the pipe.

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2=

Quoted 80 lines
drivers/rtc/rtc-rv3029c2.c +76 -0
+		usleep_range(1000, 10000);
+	}
+	if (i <=3D 0) {
+		dev_err(&client->dev, "EEPROM voltage wait timeout.\n");
+		return -ETIMEDOUT;
+	}
+
+	/* Disable eeprom refresh. */
+	ret =3D rv3029c2_i2c_maskset_reg(client, RV3029C2_ONOFF_CTRL,
+				       (u8)~RV3029C2_ONOFF_CTRL_EERE, 0);
+	if (ret < 0)
+		return ret;
+
+	/* Wait for previous eeprom accesses to finish. */
+	ret =3D rv3029c2_eeprom_busywait(client);
+	if (ret < 0)
+		rv3029c2_eeprom_exit(client);
+
+	return ret;
+}
+
+static int rv3029c2_eeprom_read(struct i2c_client *client, u8 reg,
+				u8 buf[], size_t len)
+{
+	int ret, err;
+	size_t i;
+
+	ret =3D rv3029c2_eeprom_enter(client);
+	if (ret < 0)
+		return ret;
+
+	for (i =3D 0; i < len; i++) {
+		ret =3D rv3029c2_i2c_read_regs(client, reg, &buf[i], 1);
+		if (ret < 0)
+			break;
+	}
+
+	err =3D rv3029c2_eeprom_exit(client);
+	if (err < 0)
+		return err;
+
+	return ret;
+}
+
+static int rv3029c2_eeprom_write(struct i2c_client *client, u8 reg,
+				 u8 const buf[], size_t len)
+{
+	int ret, err;
+	size_t i;
+	u8 tmp;
+
+	ret =3D rv3029c2_eeprom_enter(client);
+	if (ret < 0)
+		return ret;
+
+	for (i =3D 0; i < len; i++) {
+		ret =3D rv3029c2_i2c_read_regs(client, reg, &tmp, 1);
+		if (ret < 0)
+			break;
+		if (tmp !=3D buf[i]) {
+			ret =3D rv3029c2_i2c_write_regs(client, reg, &buf[i], 1);
+			if (ret < 0)
+				break;
+		}
+		ret =3D rv3029c2_eeprom_busywait(client);
+		if (ret < 0)
+			break;
+	}
+
+	err =3D rv3029c2_eeprom_exit(client);
+	if (err < 0)
+		return err;
+
+	return ret;
+}
+
 static int
 rv3029c2_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 {
@@ -230,22 +398,13 @@ static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2=

c_client *client,

Quoted 16 lines
drivers/rtc/rtc-rv3029c2.c +0 -12
 					int enable)
 {
 	int ret;
-	u8 buf[1];
-
-	/* enable AIE irq */
-	ret =3D rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_CTRL,	buf, 1);
-	if (ret < 0) {
-		dev_err(&client->dev, "can't read INT reg\n");
-		return ret;
-	}
-	if (enable)
-		buf[0] |=3D RV3029C2_IRQ_CTRL_AIE;
-	else
-		buf[0] &=3D ~RV3029C2_IRQ_CTRL_AIE;

=20

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client, · line 407

Quoted 8 lines
drivers/rtc/rtc-rv3029c2.c +5 -2
-	ret =3D rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_CTRL, buf, 1);
+	/* enable/disable AIE irq */
+	ret =3D rv3029c2_i2c_maskset_reg(client, RV3029C2_IRQ_CTRL,
+				       (u8)~RV3029C2_IRQ_CTRL_AIE,
+				       (enable ? RV3029C2_IRQ_CTRL_AIE : 0));
 	if (ret < 0) {
-		dev_err(&client->dev, "can't set INT reg\n");
+		dev_err(&client->dev, "can't update INT reg\n");

I would also put that particular change in a separate patch, with the _update_bits addition.

Review static int rv3029c2_rtc_i2c_set_alarm(struct i2c_cl=

Quoted 4 lines
(quoted diff) +0 -0
 		return ret;
 	}

=20

(quoted diff) +0 -0
@@ -286,20 +445,11 @@ static int rv3029c2_rtc_i2c_set_alarm(struct i2c_cl=

ient *client,

Quoted 10 lines
(quoted diff) +0 -0
 		return ret;

=20

drivers/rtc/rtc-rv3029c2.c +0 -6
 	if (alarm->enabled) {
-		u8 buf[1];
-
 		/* clear AF flag */
-		ret =3D rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_FLAGS,
-						buf, 1);
-		if (ret < 0) {
-			dev_err(&client->dev, "can't read alarm flag\n");

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client, · line 452

Quoted 10 lines
drivers/rtc/rtc-rv3029c2.c +3 -6
-			return ret;
-		}
-		buf[0] &=3D ~RV3029C2_IRQ_FLAGS_AF;
-		ret =3D rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_FLAGS,
-						buf, 1);
+		ret =3D rv3029c2_i2c_maskset_reg(client, RV3029C2_IRQ_FLAGS,
+					       (u8)~RV3029C2_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
-			dev_err(&client->dev, "can't set alarm flag\n");
+			dev_err(&client->dev, "can't clear alarm flag\n");

Ditto.

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_set_time(struct device *dev=

Quoted 4 lines
drivers/rtc/rtc-rv3029c2.c +0 -0
 			return ret;
 		}
 		/* enable AIE irq */
@@ -372,6 +522,109 @@ static int rv3029c2_rtc_set_time(struct device *dev=

, struct rtc_time *tm)

Quoted 51 lines
drivers/rtc/rtc-rv3029c2.c +0 -0
 	return rv3029c2_i2c_set_time(to_i2c_client(dev), tm);
 }

=20

(quoted diff) +48 -0
+static const struct rv3029c2_trickle_tab_elem {
+	u32 r;		/* resistance in ohms */
+	u8 conf;	/* trickle config bits */
+} rv3029c2_trickle_tab[] =3D {
+	{
+		.r	=3D 1076,
+		.conf	=3D RV3029C2_TRICKLE_1K | RV3029C2_TRICKLE_5K |
+			  RV3029C2_TRICKLE_20K | RV3029C2_TRICKLE_80K,
+	}, {
+		.r	=3D 1091,
+		.conf	=3D RV3029C2_TRICKLE_1K | RV3029C2_TRICKLE_5K |
+			  RV3029C2_TRICKLE_20K,
+	}, {
+		.r	=3D 1137,
+		.conf	=3D RV3029C2_TRICKLE_1K | RV3029C2_TRICKLE_5K |
+			  RV3029C2_TRICKLE_80K,
+	}, {
+		.r	=3D 1154,
+		.conf	=3D RV3029C2_TRICKLE_1K | RV3029C2_TRICKLE_5K,
+	}, {
+		.r	=3D 1371,
+		.conf	=3D RV3029C2_TRICKLE_1K | RV3029C2_TRICKLE_20K |
+			  RV3029C2_TRICKLE_80K,
+	}, {
+		.r	=3D 1395,
+		.conf	=3D RV3029C2_TRICKLE_1K | RV3029C2_TRICKLE_20K,
+	}, {
+		.r	=3D 1472,
+		.conf	=3D RV3029C2_TRICKLE_1K | RV3029C2_TRICKLE_80K,
+	}, {
+		.r	=3D 1500,
+		.conf	=3D RV3029C2_TRICKLE_1K,
+	}, {
+		.r	=3D 3810,
+		.conf	=3D RV3029C2_TRICKLE_5K | RV3029C2_TRICKLE_20K |
+			  RV3029C2_TRICKLE_80K,
+	}, {
+		.r	=3D 4000,
+		.conf	=3D RV3029C2_TRICKLE_5K | RV3029C2_TRICKLE_20K,
+	}, {
+		.r	=3D 4706,
+		.conf	=3D RV3029C2_TRICKLE_5K | RV3029C2_TRICKLE_80K,
+	}, {
+		.r	=3D 5000,
+		.conf	=3D RV3029C2_TRICKLE_5K,
+	}, {
+		.r	=3D 16000,
+		.conf	=3D RV3029C2_TRICKLE_20K | RV3029C2_TRICKLE_80K,

Review

Quoted 10 lines
(quoted diff) +10 -0
+	}, {
+		.r	=3D 20000,
+		.conf	=3D RV3029C2_TRICKLE_20K,
+	}, {
+		.r	=3D 80000,
+		.conf	=3D RV3029C2_TRICKLE_80K,
+	},
+};
+
+static int rv3029c2_of_init(struct i2c_client *client)

I'd name that function rv3029_trickle_config or so. Other features parsed from DT can be implemented using other functions.

Quoted 12 lines
drivers/rtc/rtc-rv3029c2.c +12 -0
+{
+	struct device_node *of_node =3D client->dev.of_node;
+	const struct rv3029c2_trickle_tab_elem *elem;
+	int i, err;
+	u32 ohms;
+	u8 eectrl;
+
+	if (!of_node)
+		return 0;
+
+	/* Configure the trickle charger. */
+	err =3D rv3029c2_eeprom_read(client, RV3029C2_CONTROL_E2P_EECTRL,

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm)

Quoted 10 lines
drivers/rtc/rtc-rv3029c2.c +10 -0
+				   &eectrl, 1);
+	if (err < 0) {
+		dev_err(&client->dev, "Failed to read trickle "
+			"charger config\n");
+		return err;
+	}
+	err =3D of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms);
+	if (err) {
+		/* Disable trickle charger. */
+		eectrl &=3D ~RV3029C2_TRICKLE_MASK;

I wouldn't touch it at all, some people may set it in the bootloader and don't expect linux to change the value.

Quoted 7 lines
drivers/rtc/rtc-rv3029c2.c +7 -0
+	} else {
+		/* Enable trickle charger. */
+		for (i =3D 0; i < ARRAY_SIZE(rv3029c2_trickle_tab); i++) {
+			elem =3D &rv3029c2_trickle_tab[i];
+			if (elem->r >=3D ohms)
+				break;
+		}

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm) · line 621

Quoted 10 lines
drivers/rtc/rtc-rv3029c2.c +10 -0
+		eectrl &=3D ~RV3029C2_TRICKLE_MASK;
+		eectrl |=3D elem->conf;
+		dev_info(&client->dev, "Trickle charger enabled at %d ohms "
+			 "resistance.\n", elem->r);
+	}
+	err =3D rv3029c2_eeprom_write(client, RV3029C2_CONTROL_E2P_EECTRL,
+				    &eectrl, 1);
+	if (err < 0) {
+		dev_err(&client->dev, "Failed to write trickle "
+			"charger config\n");

Those strings should be only on one line to stay greppable.

drivers/rtc/rtc-rv3029c2.c static const struct rtc_class_ops rv3029c2_rtc_ops =

Quoted 10 lines
drivers/rtc/rtc-rv3029c2.c +6 -0
+		return err;
+	}
+
+	return 0;
+}
+
 static const struct rtc_class_ops rv3029c2_rtc_ops =3D {
 	.read_time	=3D rv3029c2_rtc_read_time,
 	.set_time	=3D rv3029c2_rtc_set_time,
@@ -381,6 +634,7 @@ static const struct rtc_class_ops rv3029c2_rtc_ops =

=3D {

Quoted 11 lines

=20
static struct i2c_device_id rv3029c2_id[] =3D {

drivers/rtc/rtc-rv3029c2.c +1 -0
 	{ "rv3029c2", 0 },
+	{ "rv3029", 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, rv3029c2_id);
@@ -401,6 +655,12 @@ static int rv3029c2_probe(struct i2c_client *client,
 		return rc;
 	}

=20

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_probe(struct i2c_client *client, · line 661

Quoted 4 lines
drivers/rtc/rtc-rv3029c2.c +4 -0
+	rc =3D rv3029c2_of_init(client);
+	if (rc < 0) {
+		dev_err(&client->dev, "OF init failed.\n");
+		return rc;

I don't think this should be a hard failure, the RTC can function without that particular configuration, the previous error message is enough (no need for two messages).

--=20
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

--=20
--=20
You received this message because you are subscribed to "rtc-linux". Membership options at http://groups.google.com/group/rtc-linux . Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---=20
You received this message because you are subscribed to the Google Groups "= rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to [email protected].
For more options, visit https://groups.google.com/d/optout.

#2 lore raw
Quoted 6 lines · On Tue, 1 Mar 2016 22:36:55 +0100 Alexandre Belloni…
Quoted 3 lines

The kconfig name is also changed to include the chip number as there are other MicroCrystal RTCs.

This should have been another patch and will conflict with my patch doing exactly that, see rtc-next.

Ok, will remove that.

Quoted 5 lines
Quoted 3 lines

Also a "rv3029" device ID was added, because the C2 suffix does not appear in latest chip versions and datasheet versions.

This change should also be part of another patch.

Well, ok.

Quoted 8 lines

You may as well stop adding that suffix to newly added functions and macros.
I'd also take a preliminary patch removing the c2 prefix from current functions and macros.

Unfortunately, we can't rename the file because this will break scripts loading modules.

Quoted 14 lines

drivers/rtc/rtc-rv3029c2.c line 32

Quoted 11 lines

/* Register map */
/* control section */
#define RV3029C2_ONOFF_CTRL 0x00

drivers/rtc/rtc-rv3029c2.c +8 -0
+#define RV3029C2_ONOFF_CTRL_WE		(1 << 0)
+#define RV3029C2_ONOFF_CTRL_TE		(1 << 1)
+#define RV3029C2_ONOFF_CTRL_TAR		(1 << 2)
+#define RV3029C2_ONOFF_CTRL_EERE	(1 << 3)
+#define RV3029C2_ONOFF_CTRL_SRON	(1 << 4)
+#define RV3029C2_ONOFF_CTRL_TD0		(1 << 5)
+#define RV3029C2_ONOFF_CTRL_TD1		(1 << 6)
+#define RV3029C2_ONOFF_CTRL_CLKINT	(1 << 7)  

You didn't use --strict for checkpatch, please use BIT() and also correct the alignments issues.

It's what the current code already does. But I can change it all to BIT.

Quoted 9 lines

drivers/rtc/rtc-rv3029c2.c line 38

Quoted 6 lines

#define RV3029C2_IRQ_CTRL 0x01
#define RV3029C2_IRQ_CTRL_AIE (1 << 0)

drivers/rtc/rtc-rv3029c2.c +4 -0
+#define RV3029C2_IRQ_CTRL_TIE		(1 << 1)
+#define RV3029C2_IRQ_CTRL_V1IE		(1 << 2)
+#define RV3029C2_IRQ_CTRL_V2IE		(1 << 3)
+#define RV3029C2_IRQ_CTRL_SRIE		(1 << 4)  

I'm pretty sure many you are adding many of those but not using them yet.

Yes. I'm adding all missing register definitions. I didn't really see the need for splitting this further.

Quoted 9 lines

drivers/rtc/rtc-rv3029c2.c line 114

Quoted 7 lines

/* user ram section */
#define RV3029C2_USR1_RAM_PAGE 0x38

drivers/rtc/rtc-rv3029c2.c +1 -0
@@ -84,6 +111,7 @@
 #define RV3029C2_USR2_RAM_PAGE		0x3C
 #define RV3029C2_USR2_SECTION_LEN	0x04
 
+  

spurious blank line

Hm yes. Just adds some space to separate the reg definitions.

Quoted 4 lines

drivers/rtc/rtc-rv3029c2.c rv3029c2_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], · line 145

Quoted 2 lines
drivers/rtc/rtc-rv3029c2.c +1 -0
 static int
+rv3029c2_i2c_maskset_reg(struct i2c_client *client, u8 reg, u8 mask, u8 set)  

I'd prefer that function named _update_bits

I prefer maskset, because that's just what it does. Mask and set. But well, I'll just change it because it doesn't matter much.

Quoted 4 lines

drivers/rtc/rtc-rv3029c2.c rv3029c2_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], · line 147

Quoted 2 lines
drivers/rtc/rtc-rv3029c2.c +2 -0
+{
+	u8 buf[1];  

couldn't that be u8 buf?

Well, yes. Some other functions do it like this, too. But I'll change it, because I already did it in a sane way for sr and such, too.

Quoted 9 lines
Quoted 9 lines
drivers/rtc/rtc-rv3029c2.c +9 -0
+	/* Check whether we are in the allowed voltage range. */
+	for (i = 100; i > 0; i--) {
+		ret = rv3029c2_i2c_get_sr(client, &sr);
+		if (ret < 0)
+			return ret;
+		if (!(sr & (RV3029C2_STATUS_VLOW1 | RV3029C2_STATUS_VLOW2)))
+			break;
+
+		sr &= ~RV3029C2_STATUS_VLOW1;
Quoted 8 lines

drivers/rtc/rtc-rv3029c2.c rv3029c2_i2c_set_sr(struct i2c_client *client, u8 val) · line 232

Quoted 4 lines
drivers/rtc/rtc-rv3029c2.c +4 -0
+		sr &= ~RV3029C2_STATUS_VLOW2;
+		ret = rv3029c2_i2c_set_sr(client, sr);
+		if (ret < 0)
+			return ret;  

I wouldn't reset the VLOW1 and VLOW2 flags here. Just bail out if the voltage is not sufficient. I don't think that condition will actually get better simply by waiting.

I do actually think so that we should clear them at least once (that is retry once). According to the data sheet these bits will not reset automatically and might be left over from machine start (brown out).

Quoted 32 lines
Quoted 18 lines

static int
rv3029c2_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) {

drivers/rtc/rtc-rv3029c2.c +0 -11
@@ -230,22 +398,13 @@ static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client,
 					int enable)
 {
 	int ret;
-	u8 buf[1];
-
-	/* enable AIE irq */
-	ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_CTRL,	buf, 1);
-	if (ret < 0) {
-		dev_err(&client->dev, "can't read INT reg\n");
-		return ret;
-	}
-	if (enable)
-		buf[0] |= RV3029C2_IRQ_CTRL_AIE;
-	else

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client, · line 407

Quoted 10 lines
drivers/rtc/rtc-rv3029c2.c +5 -3
-		buf[0] &= ~RV3029C2_IRQ_CTRL_AIE;
 
-	ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_CTRL, buf, 1);
+	/* enable/disable AIE irq */
+	ret = rv3029c2_i2c_maskset_reg(client, RV3029C2_IRQ_CTRL,
+				       (u8)~RV3029C2_IRQ_CTRL_AIE,
+				       (enable ? RV3029C2_IRQ_CTRL_AIE : 0));
 	if (ret < 0) {
-		dev_err(&client->dev, "can't set INT reg\n");
+		dev_err(&client->dev, "can't update INT reg\n");  

I would also put that particular change in a separate patch, with the _update_bits addition.

Quoted 1 line

Ditto.

Ok. This will require a separate patch that just adds the update_bits function which the tricke change depends on then.

Quoted 4 lines

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm) · line 582

Quoted 1 line
drivers/rtc/rtc-rv3029c2.c +1 -0
+static int rv3029c2_of_init(struct i2c_client *client)  

I'd name that function rv3029_trickle_config or so. Other features parsed from DT can be implemented using other functions.

Ok.

Quoted 7 lines

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm) · line 604

Quoted 4 lines
drivers/rtc/rtc-rv3029c2.c +4 -0
+	err = of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms);
+	if (err) {
+		/* Disable trickle charger. */
+		eectrl &= ~RV3029C2_TRICKLE_MASK;  

I wouldn't touch it at all, some people may set it in the bootloader and don't expect linux to change the value.

But that would mean there is no way to disable it once it got enabled. So I'd rather keep it like this or use special values (like a huge value) like we already discussed.

Quoted 11 lines
Quoted 11 lines
drivers/rtc/rtc-rv3029c2.c +11 -0
+	} else {
+		/* Enable trickle charger. */
+		for (i = 0; i < ARRAY_SIZE(rv3029c2_trickle_tab); i++) {
+			elem = &rv3029c2_trickle_tab[i];
+			if (elem->r >= ohms)
+				break;
+		}
+		eectrl &= ~RV3029C2_TRICKLE_MASK;
+		eectrl |= elem->conf;
+		dev_info(&client->dev, "Trickle charger enabled at %d ohms "
+			 "resistance.\n", elem->r);
Quoted 8 lines

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm) · line 621

Quoted 6 lines
drivers/rtc/rtc-rv3029c2.c +6 -0
+	}
+	err = rv3029c2_eeprom_write(client, RV3029C2_CONTROL_E2P_EECTRL,
+				    &eectrl, 1);
+	if (err < 0) {
+		dev_err(&client->dev, "Failed to write trickle "
+			"charger config\n");  

Those strings should be only on one line to stay greppable.

Ok. The line break is a left over from a code reformat.

Quoted 8 lines

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_probe(struct i2c_client *client, · line 661

Quoted 4 lines
drivers/rtc/rtc-rv3029c2.c +4 -0
+	rc = rv3029c2_of_init(client);
+	if (rc < 0) {
+		dev_err(&client->dev, "OF init failed.\n");
+		return rc;  

I don't think this should be a hard failure, the RTC can function without that particular configuration, the previous error message is enough (no need for two messages).

Only 50% agree here. :)
And RTC without a working backup battery is not really that useful. But I can remove the error checking of course.

Thanks for the comments.

Signature · 12 lines
Michael

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#3 lore raw
Quoted 18 lines · On 01/03/2016 at 22:54:01 +0100, Michael B=C3=BCsch wrote :

=20

Quoted 9 lines
Quoted 9 lines
drivers/rtc/rtc-rv3029c2.c +9 -0
+	/* Check whether we are in the allowed voltage range. */
+	for (i =3D 100; i > 0; i--) {
+		ret =3D rv3029c2_i2c_get_sr(client, &sr);
+		if (ret < 0)
+			return ret;
+		if (!(sr & (RV3029C2_STATUS_VLOW1 | RV3029C2_STATUS_VLOW2)))
+			break;
+
+		sr &=3D ~RV3029C2_STATUS_VLOW1;
Quoted 8 lines

Review

Quoted 4 lines
(quoted diff) +4 -0
+		sr &=3D ~RV3029C2_STATUS_VLOW2;
+		ret =3D rv3029c2_i2c_set_sr(client, sr);
+		if (ret < 0)
+			return ret; =20

=20
I wouldn't reset the VLOW1 and VLOW2 flags here. Just bail out if the voltage is not sufficient. I don't think that condition will actually get better simply by waiting.

Quoted 6 lines

=20
=20
I do actually think so that we should clear them at least once (that is retry once). According to the data sheet these bits will not reset automatically and might be left over from machine start (brown out). =20

No, this should be handled differently. I have some pending patches to handle those bits. The main issue is that if you reset those bits there, there is now way to know whether the date has been set or is invalid.

I think the best way to handle this case is to call the function again when the date/time are set and we have to reset VLOW1/2.

Quoted 1 line
Quoted 1 line

Review

Quoted 1 line
(quoted diff) +1 -0
+	err =3D of_property_read_u32(of_node, "trickle-resistor-ohms", &ohm=

s);

Quoted 5 lines
Quoted 5 lines

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm)

Quoted 3 lines
drivers/rtc/rtc-rv3029c2.c +3 -0
+	if (err) {
+		/* Disable trickle charger. */
+		eectrl &=3D ~RV3029C2_TRICKLE_MASK; =20

=20
I wouldn't touch it at all, some people may set it in the bootloader an=

d

Quoted 6 lines
Quoted 1 line

don't expect linux to change the value.

=20
But that would mean there is no way to disable it once it got enabled. So I'd rather keep it like this or use special values (like a huge value) like we already discussed.
=20

Agreed, keep it that way.

Quoted 8 lines
Quoted 8 lines

drivers/rtc/rtc-rv3029c2.c static int rv3029c2_probe(struct i2c_client *client,

Quoted 4 lines
drivers/rtc/rtc-rv3029c2.c +4 -0
+	rc =3D rv3029c2_of_init(client);
+	if (rc < 0) {
+		dev_err(&client->dev, "OF init failed.\n");
+		return rc; =20

=20
I don't think this should be a hard failure, the RTC can function without that particular configuration, the previous error message is enough (no need for two messages).

Quoted 5 lines

=20
Only 50% agree here. :)
And RTC without a working backup battery is not really that useful. But I can remove the error checking of course.
=20

As proposed, I think we can retry to set trickle charging when necessary, when setting the date.

--=20
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

--=20
--=20
You received this message because you are subscribed to "rtc-linux". Membership options at http://groups.google.com/group/rtc-linux . Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---=20
You received this message because you are subscribed to the Google Groups "= rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to [email protected].
For more options, visit https://groups.google.com/d/optout.

#4 lore raw
Quoted 10 lines · On Wed, 2 Mar 2016 00:07:45 +0100 Alexandre Belloni…
Quoted 9 lines
Quoted 3 lines

I wouldn't reset the VLOW1 and VLOW2 flags here. Just bail out if the voltage is not sufficient. I don't think that condition will actually get better simply by waiting.

I do actually think so that we should clear them at least once (that is retry once). According to the data sheet these bits will not reset automatically and might be left over from machine start (brown out).

Quoted 6 lines

No, this should be handled differently. I have some pending patches to handle those bits. The main issue is that if you reset those bits there, there is now way to know whether the date has been set or is invalid.

I think the best way to handle this case is to call the function again when the date/time are set and we have to reset VLOW1/2.

Yes, right. But as of now we do not have VLOW handling. So I don't see an issue with clearing the bits here.
The clearing can be removed, if VLOW handling is added eventually.

The issue currently is: We need to check VLOW before accessing the eeprom, because otherwise it would mean data corruption. This is especially true for writing. And if we read VLOW, we need a way to reset the bits from the probable initial brown out. Otherwise we can never access the eeprom as this check would hit often.

So when are your VLOW patches going to be available?

Signature · 12 lines
Michael

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#5 lore raw
Quoted 4 lines · On 02/03/2016 at 07:26:27 +0100, Michael B=C3=BCsch wrote :

On Wed, 2 Mar 2016 00:07:45 +0100
Alexandre Belloni <[email protected]> wrote:
=20

Quoted 1 line
Quoted 1 line
Quoted 1 line

I wouldn't reset the VLOW1 and VLOW2 flags here. Just bail out if t=

he

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

voltage is not sufficient. I don't think that condition will actual=

ly

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 1 line

get better simply by waiting. =20

=20
=20
I do actually think so that we should clear them at least once (that =

is

Quoted 6 lines
Quoted 6 lines
Quoted 3 lines

retry once). According to the data sheet these bits will not reset automatically and might be left over from machine start (brown out).
=20

=20
No, this should be handled differently. I have some pending patches to handle those bits. The main issue is that if you reset those bits there=

,

Quoted 4 lines
Quoted 4 lines

there is now way to know whether the date has been set or is invalid. =20
I think the best way to handle this case is to call the function again when the date/time are set and we have to reset VLOW1/2.

Quoted 11 lines

=20
Yes, right. But as of now we do not have VLOW handling. So I don't see an issue with clearing the bits here.
The clearing can be removed, if VLOW handling is added eventually. =20
The issue currently is: We need to check VLOW before accessing the eeprom, because otherwise it would mean data corruption. This is especially true for writing. And if we read VLOW, we need a way to reset the bits from the probable initial brown out. Otherwise we can never access the eeprom as this check would hit often.
=20

Ok, that is fine.

Quoted 2 lines

So when are your VLOW patches going to be available? =20

I'll probably rebase on top of your changes.

--=20
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

--=20
--=20
You received this message because you are subscribed to "rtc-linux". Membership options at http://groups.google.com/group/rtc-linux . Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---=20
You received this message because you are subscribed to the Google Groups "= rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to [email protected].
For more options, visit https://groups.google.com/d/optout.

A message that is not in the archive (sent off-list or not yet received): 20160304195337.51439645@wiggum

#7 lore raw

PATCH 1/6 rtc-rv3029: Remove all 'C2' suffixes from identifiers

The C2 suffix does not appear anymore in the latest device and data sheet versions.

---
 drivers/rtc/rtc-rv3029c2.c | 295 +++++++++++++++++++++++----------------------
 1 file changed, 148 insertions(+), 147 deletions(-)
drivers/rtc/rtc-rv3029c2.c +148 -147
index e9ac5a4..3083ace 100644
@@ -1,5 +1,5 @@
 /*
- * Micro Crystal RV-3029C2 rtc class driver
+ * Micro Crystal RV-3029 rtc class driver
  *
  * Author: Gregory Hermant <[email protected]>
  *
@@ -21,77 +21,77 @@
 
 /* Register map */
 /* control section */
-#define RV3029C2_ONOFF_CTRL		0x00
-#define RV3029C2_IRQ_CTRL		0x01
-#define RV3029C2_IRQ_CTRL_AIE		(1 << 0)
-#define RV3029C2_IRQ_FLAGS		0x02
-#define RV3029C2_IRQ_FLAGS_AF		(1 << 0)
-#define RV3029C2_STATUS			0x03
-#define RV3029C2_STATUS_VLOW1		(1 << 2)
-#define RV3029C2_STATUS_VLOW2		(1 << 3)
-#define RV3029C2_STATUS_SR		(1 << 4)
-#define RV3029C2_STATUS_PON		(1 << 5)
-#define RV3029C2_STATUS_EEBUSY		(1 << 7)
-#define RV3029C2_RST_CTRL		0x04
-#define RV3029C2_CONTROL_SECTION_LEN	0x05
+#define RV3029_ONOFF_CTRL		0x00
+#define RV3029_IRQ_CTRL			0x01
+#define RV3029_IRQ_CTRL_AIE		(1 << 0)
+#define RV3029_IRQ_FLAGS		0x02
+#define RV3029_IRQ_FLAGS_AF		(1 << 0)
+#define RV3029_STATUS			0x03
+#define RV3029_STATUS_VLOW1		(1 << 2)
+#define RV3029_STATUS_VLOW2		(1 << 3)
+#define RV3029_STATUS_SR		(1 << 4)
+#define RV3029_STATUS_PON		(1 << 5)
+#define RV3029_STATUS_EEBUSY		(1 << 7)
+#define RV3029_RST_CTRL			0x04
+#define RV3029_CONTROL_SECTION_LEN	0x05
 
 /* watch section */
-#define RV3029C2_W_SEC			0x08
-#define RV3029C2_W_MINUTES		0x09
-#define RV3029C2_W_HOURS		0x0A
-#define RV3029C2_REG_HR_12_24		(1<<6)  /* 24h/12h mode */
-#define RV3029C2_REG_HR_PM		(1<<5)  /* PM/AM bit in 12h mode */
-#define RV3029C2_W_DATE			0x0B
-#define RV3029C2_W_DAYS			0x0C
-#define RV3029C2_W_MONTHS		0x0D
-#define RV3029C2_W_YEARS		0x0E
-#define RV3029C2_WATCH_SECTION_LEN	0x07
+#define RV3029_W_SEC			0x08
+#define RV3029_W_MINUTES		0x09
+#define RV3029_W_HOURS			0x0A
+#define RV3029_REG_HR_12_24		(1<<6)  /* 24h/12h mode */
+#define RV3029_REG_HR_PM		(1<<5)  /* PM/AM bit in 12h mode */
+#define RV3029_W_DATE			0x0B
+#define RV3029_W_DAYS			0x0C
+#define RV3029_W_MONTHS			0x0D
+#define RV3029_W_YEARS			0x0E
+#define RV3029_WATCH_SECTION_LEN	0x07
 
 /* alarm section */
-#define RV3029C2_A_SC			0x10
-#define RV3029C2_A_MN			0x11
-#define RV3029C2_A_HR			0x12
-#define RV3029C2_A_DT			0x13
-#define RV3029C2_A_DW			0x14
-#define RV3029C2_A_MO			0x15
-#define RV3029C2_A_YR			0x16
-#define RV3029C2_ALARM_SECTION_LEN	0x07
+#define RV3029_A_SC			0x10
+#define RV3029_A_MN			0x11
+#define RV3029_A_HR			0x12
+#define RV3029_A_DT			0x13
+#define RV3029_A_DW			0x14
+#define RV3029_A_MO			0x15
+#define RV3029_A_YR			0x16
+#define RV3029_ALARM_SECTION_LEN	0x07
 
 /* timer section */
-#define RV3029C2_TIMER_LOW		0x18
-#define RV3029C2_TIMER_HIGH		0x19
+#define RV3029_TIMER_LOW		0x18
+#define RV3029_TIMER_HIGH		0x19
 
 /* temperature section */
-#define RV3029C2_TEMP_PAGE		0x20
+#define RV3029_TEMP_PAGE		0x20
 
 /* eeprom data section */
-#define RV3029C2_E2P_EEDATA1		0x28
-#define RV3029C2_E2P_EEDATA2		0x29
+#define RV3029_E2P_EEDATA1		0x28
+#define RV3029_E2P_EEDATA2		0x29
 
 /* eeprom control section */
-#define RV3029C2_CONTROL_E2P_EECTRL	0x30
-#define RV3029C2_TRICKLE_1K		(1<<0)  /*  1K resistance */
-#define RV3029C2_TRICKLE_5K		(1<<1)  /*  5K resistance */
-#define RV3029C2_TRICKLE_20K		(1<<2)  /* 20K resistance */
-#define RV3029C2_TRICKLE_80K		(1<<3)  /* 80K resistance */
-#define RV3029C2_CONTROL_E2P_XTALOFFSET	0x31
-#define RV3029C2_CONTROL_E2P_QCOEF	0x32
-#define RV3029C2_CONTROL_E2P_TURNOVER	0x33
+#define RV3029_CONTROL_E2P_EECTRL	0x30
+#define RV3029_TRICKLE_1K		(1<<0)  /*  1K resistance */
+#define RV3029_TRICKLE_5K		(1<<1)  /*  5K resistance */
+#define RV3029_TRICKLE_20K		(1<<2)  /* 20K resistance */
+#define RV3029_TRICKLE_80K		(1<<3)  /* 80K resistance */
+#define RV3029_CONTROL_E2P_XTALOFFSET	0x31
+#define RV3029_CONTROL_E2P_QCOEF	0x32
+#define RV3029_CONTROL_E2P_TURNOVER	0x33
 
 /* user ram section */
-#define RV3029C2_USR1_RAM_PAGE		0x38
-#define RV3029C2_USR1_SECTION_LEN	0x04
-#define RV3029C2_USR2_RAM_PAGE		0x3C
-#define RV3029C2_USR2_SECTION_LEN	0x04
+#define RV3029_USR1_RAM_PAGE		0x38
+#define RV3029_USR1_SECTION_LEN		0x04
+#define RV3029_USR2_RAM_PAGE		0x3C
+#define RV3029_USR2_SECTION_LEN		0x04
 
 static int
-rv3029c2_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
-	unsigned len)
+rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+		     unsigned len)
 {
 	int ret;
 
-	if ((reg > RV3029C2_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029C2_USR1_RAM_PAGE + 8))
+	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
+		(reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 
 	ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf);
@@ -103,20 +103,20 @@ rv3029c2_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
 }
 
 static int
-rv3029c2_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
-			unsigned len)
+rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
+		      unsigned len)
 {
-	if ((reg > RV3029C2_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029C2_USR1_RAM_PAGE + 8))
+	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
+		(reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 
 	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
 }
 
 static int
-rv3029c2_i2c_get_sr(struct i2c_client *client, u8 *buf)
+rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
 {
-	int ret = rv3029c2_i2c_read_regs(client, RV3029C2_STATUS, buf, 1);
+	int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
 
 	if (ret < 0)
 		return -EIO;
@@ -125,13 +125,13 @@ rv3029c2_i2c_get_sr(struct i2c_client *client, u8 *buf)
 }
 
 static int
-rv3029c2_i2c_set_sr(struct i2c_client *client, u8 val)
+rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
 {
 	u8 buf[1];
 	int sr;
 
 	buf[0] = val;
-	sr = rv3029c2_i2c_write_regs(client, RV3029C2_STATUS, buf, 1);
+	sr = rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1);
 	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
 	if (sr < 0)
 		return -EIO;
@@ -139,69 +139,70 @@ rv3029c2_i2c_set_sr(struct i2c_client *client, u8 val)
 }
 
 static int
-rv3029c2_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 {
 	u8 buf[1];
 	int ret;
-	u8 regs[RV3029C2_WATCH_SECTION_LEN] = { 0, };
+	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
-	ret = rv3029c2_i2c_get_sr(client, buf);
+	ret = rv3029_i2c_get_sr(client, buf);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029c2_i2c_read_regs(client, RV3029C2_W_SEC , regs,
-					RV3029C2_WATCH_SECTION_LEN);
+	ret = rv3029_i2c_read_regs(client, RV3029_W_SEC, regs,
+				   RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading RTC section failed\n",
 			__func__);
 		return ret;
 	}
 
-	tm->tm_sec = bcd2bin(regs[RV3029C2_W_SEC-RV3029C2_W_SEC]);
-	tm->tm_min = bcd2bin(regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC]);
+	tm->tm_sec = bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
+	tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES-RV3029_W_SEC]);
 
 	/* HR field has a more complex interpretation */
 	{
-		const u8 _hr = regs[RV3029C2_W_HOURS-RV3029C2_W_SEC];
-		if (_hr & RV3029C2_REG_HR_12_24) {
+		const u8 _hr = regs[RV3029_W_HOURS-RV3029_W_SEC];
+
+		if (_hr & RV3029_REG_HR_12_24) {
 			/* 12h format */
 			tm->tm_hour = bcd2bin(_hr & 0x1f);
-			if (_hr & RV3029C2_REG_HR_PM)	/* PM flag set */
+			if (_hr & RV3029_REG_HR_PM)	/* PM flag set */
 				tm->tm_hour += 12;
 		} else /* 24h format */
 			tm->tm_hour = bcd2bin(_hr & 0x3f);
 	}
 
-	tm->tm_mday = bcd2bin(regs[RV3029C2_W_DATE-RV3029C2_W_SEC]);
-	tm->tm_mon = bcd2bin(regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC]) - 1;
-	tm->tm_year = bcd2bin(regs[RV3029C2_W_YEARS-RV3029C2_W_SEC]) + 100;
-	tm->tm_wday = bcd2bin(regs[RV3029C2_W_DAYS-RV3029C2_W_SEC]) - 1;
+	tm->tm_mday = bcd2bin(regs[RV3029_W_DATE-RV3029_W_SEC]);
+	tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS-RV3029_W_SEC]) - 1;
+	tm->tm_year = bcd2bin(regs[RV3029_W_YEARS-RV3029_W_SEC]) + 100;
+	tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS-RV3029_W_SEC]) - 1;
 
 	return 0;
 }
 
-static int rv3029c2_rtc_read_time(struct device *dev, struct rtc_time *tm)
+static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029c2_i2c_read_time(to_i2c_client(dev), tm);
+	return rv3029_i2c_read_time(to_i2c_client(dev), tm);
 }
 
 static int
-rv3029c2_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
+rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
 {
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
 
-	ret = rv3029c2_i2c_get_sr(client, regs);
+	ret = rv3029_i2c_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029c2_i2c_read_regs(client, RV3029C2_A_SC, regs,
-					RV3029C2_ALARM_SECTION_LEN);
+	ret = rv3029_i2c_read_regs(client, RV3029_A_SC, regs,
+				   RV3029_ALARM_SECTION_LEN);
 
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading alarm section failed\n",
@@ -209,41 +210,41 @@ rv3029c2_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
 		return ret;
 	}
 
-	tm->tm_sec = bcd2bin(regs[RV3029C2_A_SC-RV3029C2_A_SC] & 0x7f);
-	tm->tm_min = bcd2bin(regs[RV3029C2_A_MN-RV3029C2_A_SC] & 0x7f);
-	tm->tm_hour = bcd2bin(regs[RV3029C2_A_HR-RV3029C2_A_SC] & 0x3f);
-	tm->tm_mday = bcd2bin(regs[RV3029C2_A_DT-RV3029C2_A_SC] & 0x3f);
-	tm->tm_mon = bcd2bin(regs[RV3029C2_A_MO-RV3029C2_A_SC] & 0x1f) - 1;
-	tm->tm_year = bcd2bin(regs[RV3029C2_A_YR-RV3029C2_A_SC] & 0x7f) + 100;
-	tm->tm_wday = bcd2bin(regs[RV3029C2_A_DW-RV3029C2_A_SC] & 0x07) - 1;
+	tm->tm_sec = bcd2bin(regs[RV3029_A_SC-RV3029_A_SC] & 0x7f);
+	tm->tm_min = bcd2bin(regs[RV3029_A_MN-RV3029_A_SC] & 0x7f);
+	tm->tm_hour = bcd2bin(regs[RV3029_A_HR-RV3029_A_SC] & 0x3f);
+	tm->tm_mday = bcd2bin(regs[RV3029_A_DT-RV3029_A_SC] & 0x3f);
+	tm->tm_mon = bcd2bin(regs[RV3029_A_MO-RV3029_A_SC] & 0x1f) - 1;
+	tm->tm_year = bcd2bin(regs[RV3029_A_YR-RV3029_A_SC] & 0x7f) + 100;
+	tm->tm_wday = bcd2bin(regs[RV3029_A_DW-RV3029_A_SC] & 0x07) - 1;
 
 	return 0;
 }
 
 static int
-rv3029c2_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	return rv3029c2_i2c_read_alarm(to_i2c_client(dev), alarm);
+	return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm);
 }
 
-static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client,
+static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
 					int enable)
 {
 	int ret;
 	u8 buf[1];
 
 	/* enable AIE irq */
-	ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_CTRL,	buf, 1);
+	ret = rv3029_i2c_read_regs(client, RV3029_IRQ_CTRL, buf, 1);
 	if (ret < 0) {
 		dev_err(&client->dev, "can't read INT reg\n");
 		return ret;
 	}
 	if (enable)
-		buf[0] |= RV3029C2_IRQ_CTRL_AIE;
+		buf[0] |= RV3029_IRQ_CTRL_AIE;
 	else
-		buf[0] &= ~RV3029C2_IRQ_CTRL_AIE;
+		buf[0] &= ~RV3029_IRQ_CTRL_AIE;
 
-	ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_CTRL, buf, 1);
+	ret = rv3029_i2c_write_regs(client, RV3029_IRQ_CTRL, buf, 1);
 	if (ret < 0) {
 		dev_err(&client->dev, "can't set INT reg\n");
 		return ret;
@@ -252,8 +253,8 @@ static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client,
 	return 0;
 }
 
-static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client,
-					struct rtc_wkalrm *alarm)
+static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
+				    struct rtc_wkalrm *alarm)
 {
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
@@ -267,21 +268,21 @@ static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client,
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	ret = rv3029c2_i2c_get_sr(client, regs);
+	ret = rv3029_i2c_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	regs[RV3029C2_A_SC-RV3029C2_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
-	regs[RV3029C2_A_MN-RV3029C2_A_SC] = bin2bcd(tm->tm_min & 0x7f);
-	regs[RV3029C2_A_HR-RV3029C2_A_SC] = bin2bcd(tm->tm_hour & 0x3f);
-	regs[RV3029C2_A_DT-RV3029C2_A_SC] = bin2bcd(tm->tm_mday & 0x3f);
-	regs[RV3029C2_A_MO-RV3029C2_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1);
-	regs[RV3029C2_A_DW-RV3029C2_A_SC] = bin2bcd((tm->tm_wday & 7) - 1);
-	regs[RV3029C2_A_YR-RV3029C2_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100);
-
-	ret = rv3029c2_i2c_write_regs(client, RV3029C2_A_SC, regs,
-					RV3029C2_ALARM_SECTION_LEN);
+	regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
+	regs[RV3029_A_MN-RV3029_A_SC] = bin2bcd(tm->tm_min & 0x7f);
+	regs[RV3029_A_HR-RV3029_A_SC] = bin2bcd(tm->tm_hour & 0x3f);
+	regs[RV3029_A_DT-RV3029_A_SC] = bin2bcd(tm->tm_mday & 0x3f);
+	regs[RV3029_A_MO-RV3029_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1);
+	regs[RV3029_A_DW-RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1);
+	regs[RV3029_A_YR-RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100);
+
+	ret = rv3029_i2c_write_regs(client, RV3029_A_SC, regs,
+				    RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
@@ -289,28 +290,28 @@ static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client,
 		u8 buf[1];
 
 		/* clear AF flag */
-		ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_FLAGS,
-						buf, 1);
+		ret = rv3029_i2c_read_regs(client, RV3029_IRQ_FLAGS,
+					   buf, 1);
 		if (ret < 0) {
 			dev_err(&client->dev, "can't read alarm flag\n");
 			return ret;
 		}
-		buf[0] &= ~RV3029C2_IRQ_FLAGS_AF;
-		ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_FLAGS,
-						buf, 1);
+		buf[0] &= ~RV3029_IRQ_FLAGS_AF;
+		ret = rv3029_i2c_write_regs(client, RV3029_IRQ_FLAGS,
+					    buf, 1);
 		if (ret < 0) {
 			dev_err(&client->dev, "can't set alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1);
+		ret = rv3029_rtc_i2c_alarm_set_irq(client, 1);
 		if (ret)
 			return ret;
 
 		dev_dbg(&client->dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 0);
+		ret = rv3029_rtc_i2c_alarm_set_irq(client, 0);
 		if (ret)
 			return ret;
 
@@ -320,13 +321,13 @@ static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client,
 	return 0;
 }
 
-static int rv3029c2_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	return rv3029c2_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
+	return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
 }
 
 static int
-rv3029c2_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
+rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -339,26 +340,26 @@ rv3029c2_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	regs[RV3029C2_W_SEC-RV3029C2_W_SEC] = bin2bcd(tm->tm_sec);
-	regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC] = bin2bcd(tm->tm_min);
-	regs[RV3029C2_W_HOURS-RV3029C2_W_SEC] = bin2bcd(tm->tm_hour);
-	regs[RV3029C2_W_DATE-RV3029C2_W_SEC] = bin2bcd(tm->tm_mday);
-	regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC] = bin2bcd(tm->tm_mon+1);
-	regs[RV3029C2_W_DAYS-RV3029C2_W_SEC] = bin2bcd((tm->tm_wday & 7)+1);
-	regs[RV3029C2_W_YEARS-RV3029C2_W_SEC] = bin2bcd(tm->tm_year - 100);
+	regs[RV3029_W_SEC-RV3029_W_SEC] = bin2bcd(tm->tm_sec);
+	regs[RV3029_W_MINUTES-RV3029_W_SEC] = bin2bcd(tm->tm_min);
+	regs[RV3029_W_HOURS-RV3029_W_SEC] = bin2bcd(tm->tm_hour);
+	regs[RV3029_W_DATE-RV3029_W_SEC] = bin2bcd(tm->tm_mday);
+	regs[RV3029_W_MONTHS-RV3029_W_SEC] = bin2bcd(tm->tm_mon+1);
+	regs[RV3029_W_DAYS-RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7)+1);
+	regs[RV3029_W_YEARS-RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
 
-	ret = rv3029c2_i2c_write_regs(client, RV3029C2_W_SEC, regs,
-					RV3029C2_WATCH_SECTION_LEN);
+	ret = rv3029_i2c_write_regs(client, RV3029_W_SEC, regs,
+				    RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
-	ret = rv3029c2_i2c_get_sr(client, regs);
+	ret = rv3029_i2c_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret = rv3029c2_i2c_set_sr(client, (regs[0] & ~RV3029C2_STATUS_PON));
+	ret = rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
@@ -367,26 +368,26 @@ rv3029c2_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 	return 0;
 }
 
-static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm)
+static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029c2_i2c_set_time(to_i2c_client(dev), tm);
+	return rv3029_i2c_set_time(to_i2c_client(dev), tm);
 }
 
-static const struct rtc_class_ops rv3029c2_rtc_ops = {
-	.read_time	= rv3029c2_rtc_read_time,
-	.set_time	= rv3029c2_rtc_set_time,
-	.read_alarm	= rv3029c2_rtc_read_alarm,
-	.set_alarm	= rv3029c2_rtc_set_alarm,
+static const struct rtc_class_ops rv3029_rtc_ops = {
+	.read_time	= rv3029_rtc_read_time,
+	.set_time	= rv3029_rtc_set_time,
+	.read_alarm	= rv3029_rtc_read_alarm,
+	.set_alarm	= rv3029_rtc_set_alarm,
 };
 
-static struct i2c_device_id rv3029c2_id[] = {
+static struct i2c_device_id rv3029_id[] = {
 	{ "rv3029c2", 0 },
 	{ }
 };
-MODULE_DEVICE_TABLE(i2c, rv3029c2_id);
+MODULE_DEVICE_TABLE(i2c, rv3029_id);
 
-static int rv3029c2_probe(struct i2c_client *client,
-			  const struct i2c_device_id *id)
+static int rv3029_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	struct rtc_device *rtc;
 	int rc = 0;
@@ -395,14 +396,14 @@ static int rv3029c2_probe(struct i2c_client *client,
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
 		return -ENODEV;
 
-	rc = rv3029c2_i2c_get_sr(client, buf);
+	rc = rv3029_i2c_get_sr(client, buf);
 	if (rc < 0) {
 		dev_err(&client->dev, "reading status failed\n");
 		return rc;
 	}
 
 	rtc = devm_rtc_device_register(&client->dev, client->name,
-					&rv3029c2_rtc_ops, THIS_MODULE);
+				       &rv3029_rtc_ops, THIS_MODULE);
 
 	if (IS_ERR(rtc))
 		return PTR_ERR(rtc);
@@ -412,16 +413,16 @@ static int rv3029c2_probe(struct i2c_client *client,
 	return 0;
 }
 
-static struct i2c_driver rv3029c2_driver = {
+static struct i2c_driver rv3029_driver = {
 	.driver = {
 		.name = "rtc-rv3029c2",
 	},
-	.probe = rv3029c2_probe,
-	.id_table = rv3029c2_id,
+	.probe		= rv3029_probe,
+	.id_table	= rv3029_id,
 };
 
-module_i2c_driver(rv3029c2_driver);
+module_i2c_driver(rv3029_driver);
 
 MODULE_AUTHOR("Gregory Hermant <[email protected]>");
-MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver");
+MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
 MODULE_LICENSE("GPL");
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#8 lore raw

PATCH v3 1/6 rtc-rv3029: Remove all 'C2' suffixes from identifiers

The C2 suffix does not appear anymore in the latest device and data sheet versions.

---
 drivers/rtc/rtc-rv3029c2.c | 295 +++++++++++++++++++++++----------------------
 1 file changed, 148 insertions(+), 147 deletions(-)
drivers/rtc/rtc-rv3029c2.c +148 -147
index e9ac5a4..3083ace 100644
@@ -1,5 +1,5 @@
 /*
- * Micro Crystal RV-3029C2 rtc class driver
+ * Micro Crystal RV-3029 rtc class driver
  *
  * Author: Gregory Hermant <[email protected]>
  *
@@ -21,77 +21,77 @@
 
 /* Register map */
 /* control section */
-#define RV3029C2_ONOFF_CTRL		0x00
-#define RV3029C2_IRQ_CTRL		0x01
-#define RV3029C2_IRQ_CTRL_AIE		(1 << 0)
-#define RV3029C2_IRQ_FLAGS		0x02
-#define RV3029C2_IRQ_FLAGS_AF		(1 << 0)
-#define RV3029C2_STATUS			0x03
-#define RV3029C2_STATUS_VLOW1		(1 << 2)
-#define RV3029C2_STATUS_VLOW2		(1 << 3)
-#define RV3029C2_STATUS_SR		(1 << 4)
-#define RV3029C2_STATUS_PON		(1 << 5)
-#define RV3029C2_STATUS_EEBUSY		(1 << 7)
-#define RV3029C2_RST_CTRL		0x04
-#define RV3029C2_CONTROL_SECTION_LEN	0x05
+#define RV3029_ONOFF_CTRL		0x00
+#define RV3029_IRQ_CTRL			0x01
+#define RV3029_IRQ_CTRL_AIE		(1 << 0)
+#define RV3029_IRQ_FLAGS		0x02
+#define RV3029_IRQ_FLAGS_AF		(1 << 0)
+#define RV3029_STATUS			0x03
+#define RV3029_STATUS_VLOW1		(1 << 2)
+#define RV3029_STATUS_VLOW2		(1 << 3)
+#define RV3029_STATUS_SR		(1 << 4)
+#define RV3029_STATUS_PON		(1 << 5)
+#define RV3029_STATUS_EEBUSY		(1 << 7)
+#define RV3029_RST_CTRL			0x04
+#define RV3029_CONTROL_SECTION_LEN	0x05
 
 /* watch section */
-#define RV3029C2_W_SEC			0x08
-#define RV3029C2_W_MINUTES		0x09
-#define RV3029C2_W_HOURS		0x0A
-#define RV3029C2_REG_HR_12_24		(1<<6)  /* 24h/12h mode */
-#define RV3029C2_REG_HR_PM		(1<<5)  /* PM/AM bit in 12h mode */
-#define RV3029C2_W_DATE			0x0B
-#define RV3029C2_W_DAYS			0x0C
-#define RV3029C2_W_MONTHS		0x0D
-#define RV3029C2_W_YEARS		0x0E
-#define RV3029C2_WATCH_SECTION_LEN	0x07
+#define RV3029_W_SEC			0x08
+#define RV3029_W_MINUTES		0x09
+#define RV3029_W_HOURS			0x0A
+#define RV3029_REG_HR_12_24		(1<<6)  /* 24h/12h mode */
+#define RV3029_REG_HR_PM		(1<<5)  /* PM/AM bit in 12h mode */
+#define RV3029_W_DATE			0x0B
+#define RV3029_W_DAYS			0x0C
+#define RV3029_W_MONTHS			0x0D
+#define RV3029_W_YEARS			0x0E
+#define RV3029_WATCH_SECTION_LEN	0x07
 
 /* alarm section */
-#define RV3029C2_A_SC			0x10
-#define RV3029C2_A_MN			0x11
-#define RV3029C2_A_HR			0x12
-#define RV3029C2_A_DT			0x13
-#define RV3029C2_A_DW			0x14
-#define RV3029C2_A_MO			0x15
-#define RV3029C2_A_YR			0x16
-#define RV3029C2_ALARM_SECTION_LEN	0x07
+#define RV3029_A_SC			0x10
+#define RV3029_A_MN			0x11
+#define RV3029_A_HR			0x12
+#define RV3029_A_DT			0x13
+#define RV3029_A_DW			0x14
+#define RV3029_A_MO			0x15
+#define RV3029_A_YR			0x16
+#define RV3029_ALARM_SECTION_LEN	0x07
 
 /* timer section */
-#define RV3029C2_TIMER_LOW		0x18
-#define RV3029C2_TIMER_HIGH		0x19
+#define RV3029_TIMER_LOW		0x18
+#define RV3029_TIMER_HIGH		0x19
 
 /* temperature section */
-#define RV3029C2_TEMP_PAGE		0x20
+#define RV3029_TEMP_PAGE		0x20
 
 /* eeprom data section */
-#define RV3029C2_E2P_EEDATA1		0x28
-#define RV3029C2_E2P_EEDATA2		0x29
+#define RV3029_E2P_EEDATA1		0x28
+#define RV3029_E2P_EEDATA2		0x29
 
 /* eeprom control section */
-#define RV3029C2_CONTROL_E2P_EECTRL	0x30
-#define RV3029C2_TRICKLE_1K		(1<<0)  /*  1K resistance */
-#define RV3029C2_TRICKLE_5K		(1<<1)  /*  5K resistance */
-#define RV3029C2_TRICKLE_20K		(1<<2)  /* 20K resistance */
-#define RV3029C2_TRICKLE_80K		(1<<3)  /* 80K resistance */
-#define RV3029C2_CONTROL_E2P_XTALOFFSET	0x31
-#define RV3029C2_CONTROL_E2P_QCOEF	0x32
-#define RV3029C2_CONTROL_E2P_TURNOVER	0x33
+#define RV3029_CONTROL_E2P_EECTRL	0x30
+#define RV3029_TRICKLE_1K		(1<<0)  /*  1K resistance */
+#define RV3029_TRICKLE_5K		(1<<1)  /*  5K resistance */
+#define RV3029_TRICKLE_20K		(1<<2)  /* 20K resistance */
+#define RV3029_TRICKLE_80K		(1<<3)  /* 80K resistance */
+#define RV3029_CONTROL_E2P_XTALOFFSET	0x31
+#define RV3029_CONTROL_E2P_QCOEF	0x32
+#define RV3029_CONTROL_E2P_TURNOVER	0x33
 
 /* user ram section */
-#define RV3029C2_USR1_RAM_PAGE		0x38
-#define RV3029C2_USR1_SECTION_LEN	0x04
-#define RV3029C2_USR2_RAM_PAGE		0x3C
-#define RV3029C2_USR2_SECTION_LEN	0x04
+#define RV3029_USR1_RAM_PAGE		0x38
+#define RV3029_USR1_SECTION_LEN		0x04
+#define RV3029_USR2_RAM_PAGE		0x3C
+#define RV3029_USR2_SECTION_LEN		0x04
 
 static int
-rv3029c2_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
-	unsigned len)
+rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+		     unsigned len)
 {
 	int ret;
 
-	if ((reg > RV3029C2_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029C2_USR1_RAM_PAGE + 8))
+	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
+		(reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 
 	ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf);
@@ -103,20 +103,20 @@ rv3029c2_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
 }
 
 static int
-rv3029c2_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
-			unsigned len)
+rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
+		      unsigned len)
 {
-	if ((reg > RV3029C2_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029C2_USR1_RAM_PAGE + 8))
+	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
+		(reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 
 	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
 }
 
 static int
-rv3029c2_i2c_get_sr(struct i2c_client *client, u8 *buf)
+rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
 {
-	int ret = rv3029c2_i2c_read_regs(client, RV3029C2_STATUS, buf, 1);
+	int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
 
 	if (ret < 0)
 		return -EIO;
@@ -125,13 +125,13 @@ rv3029c2_i2c_get_sr(struct i2c_client *client, u8 *buf)
 }
 
 static int
-rv3029c2_i2c_set_sr(struct i2c_client *client, u8 val)
+rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
 {
 	u8 buf[1];
 	int sr;
 
 	buf[0] = val;
-	sr = rv3029c2_i2c_write_regs(client, RV3029C2_STATUS, buf, 1);
+	sr = rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1);
 	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
 	if (sr < 0)
 		return -EIO;
@@ -139,69 +139,70 @@ rv3029c2_i2c_set_sr(struct i2c_client *client, u8 val)
 }
 
 static int
-rv3029c2_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 {
 	u8 buf[1];
 	int ret;
-	u8 regs[RV3029C2_WATCH_SECTION_LEN] = { 0, };
+	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
-	ret = rv3029c2_i2c_get_sr(client, buf);
+	ret = rv3029_i2c_get_sr(client, buf);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029c2_i2c_read_regs(client, RV3029C2_W_SEC , regs,
-					RV3029C2_WATCH_SECTION_LEN);
+	ret = rv3029_i2c_read_regs(client, RV3029_W_SEC, regs,
+				   RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading RTC section failed\n",
 			__func__);
 		return ret;
 	}
 
-	tm->tm_sec = bcd2bin(regs[RV3029C2_W_SEC-RV3029C2_W_SEC]);
-	tm->tm_min = bcd2bin(regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC]);
+	tm->tm_sec = bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
+	tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES-RV3029_W_SEC]);
 
 	/* HR field has a more complex interpretation */
 	{
-		const u8 _hr = regs[RV3029C2_W_HOURS-RV3029C2_W_SEC];
-		if (_hr & RV3029C2_REG_HR_12_24) {
+		const u8 _hr = regs[RV3029_W_HOURS-RV3029_W_SEC];
+
+		if (_hr & RV3029_REG_HR_12_24) {
 			/* 12h format */
 			tm->tm_hour = bcd2bin(_hr & 0x1f);
-			if (_hr & RV3029C2_REG_HR_PM)	/* PM flag set */
+			if (_hr & RV3029_REG_HR_PM)	/* PM flag set */
 				tm->tm_hour += 12;
 		} else /* 24h format */
 			tm->tm_hour = bcd2bin(_hr & 0x3f);
 	}
 
-	tm->tm_mday = bcd2bin(regs[RV3029C2_W_DATE-RV3029C2_W_SEC]);
-	tm->tm_mon = bcd2bin(regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC]) - 1;
-	tm->tm_year = bcd2bin(regs[RV3029C2_W_YEARS-RV3029C2_W_SEC]) + 100;
-	tm->tm_wday = bcd2bin(regs[RV3029C2_W_DAYS-RV3029C2_W_SEC]) - 1;
+	tm->tm_mday = bcd2bin(regs[RV3029_W_DATE-RV3029_W_SEC]);
+	tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS-RV3029_W_SEC]) - 1;
+	tm->tm_year = bcd2bin(regs[RV3029_W_YEARS-RV3029_W_SEC]) + 100;
+	tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS-RV3029_W_SEC]) - 1;
 
 	return 0;
 }
 
-static int rv3029c2_rtc_read_time(struct device *dev, struct rtc_time *tm)
+static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029c2_i2c_read_time(to_i2c_client(dev), tm);
+	return rv3029_i2c_read_time(to_i2c_client(dev), tm);
 }
 
 static int
-rv3029c2_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
+rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
 {
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
 
-	ret = rv3029c2_i2c_get_sr(client, regs);
+	ret = rv3029_i2c_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029c2_i2c_read_regs(client, RV3029C2_A_SC, regs,
-					RV3029C2_ALARM_SECTION_LEN);
+	ret = rv3029_i2c_read_regs(client, RV3029_A_SC, regs,
+				   RV3029_ALARM_SECTION_LEN);
 
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading alarm section failed\n",
@@ -209,41 +210,41 @@ rv3029c2_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
 		return ret;
 	}
 
-	tm->tm_sec = bcd2bin(regs[RV3029C2_A_SC-RV3029C2_A_SC] & 0x7f);
-	tm->tm_min = bcd2bin(regs[RV3029C2_A_MN-RV3029C2_A_SC] & 0x7f);
-	tm->tm_hour = bcd2bin(regs[RV3029C2_A_HR-RV3029C2_A_SC] & 0x3f);
-	tm->tm_mday = bcd2bin(regs[RV3029C2_A_DT-RV3029C2_A_SC] & 0x3f);
-	tm->tm_mon = bcd2bin(regs[RV3029C2_A_MO-RV3029C2_A_SC] & 0x1f) - 1;
-	tm->tm_year = bcd2bin(regs[RV3029C2_A_YR-RV3029C2_A_SC] & 0x7f) + 100;
-	tm->tm_wday = bcd2bin(regs[RV3029C2_A_DW-RV3029C2_A_SC] & 0x07) - 1;
+	tm->tm_sec = bcd2bin(regs[RV3029_A_SC-RV3029_A_SC] & 0x7f);
+	tm->tm_min = bcd2bin(regs[RV3029_A_MN-RV3029_A_SC] & 0x7f);
+	tm->tm_hour = bcd2bin(regs[RV3029_A_HR-RV3029_A_SC] & 0x3f);
+	tm->tm_mday = bcd2bin(regs[RV3029_A_DT-RV3029_A_SC] & 0x3f);
+	tm->tm_mon = bcd2bin(regs[RV3029_A_MO-RV3029_A_SC] & 0x1f) - 1;
+	tm->tm_year = bcd2bin(regs[RV3029_A_YR-RV3029_A_SC] & 0x7f) + 100;
+	tm->tm_wday = bcd2bin(regs[RV3029_A_DW-RV3029_A_SC] & 0x07) - 1;
 
 	return 0;
 }
 
 static int
-rv3029c2_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	return rv3029c2_i2c_read_alarm(to_i2c_client(dev), alarm);
+	return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm);
 }
 
-static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client,
+static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
 					int enable)
 {
 	int ret;
 	u8 buf[1];
 
 	/* enable AIE irq */
-	ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_CTRL,	buf, 1);
+	ret = rv3029_i2c_read_regs(client, RV3029_IRQ_CTRL, buf, 1);
 	if (ret < 0) {
 		dev_err(&client->dev, "can't read INT reg\n");
 		return ret;
 	}
 	if (enable)
-		buf[0] |= RV3029C2_IRQ_CTRL_AIE;
+		buf[0] |= RV3029_IRQ_CTRL_AIE;
 	else
-		buf[0] &= ~RV3029C2_IRQ_CTRL_AIE;
+		buf[0] &= ~RV3029_IRQ_CTRL_AIE;
 
-	ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_CTRL, buf, 1);
+	ret = rv3029_i2c_write_regs(client, RV3029_IRQ_CTRL, buf, 1);
 	if (ret < 0) {
 		dev_err(&client->dev, "can't set INT reg\n");
 		return ret;
@@ -252,8 +253,8 @@ static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client,
 	return 0;
 }
 
-static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client,
-					struct rtc_wkalrm *alarm)
+static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
+				    struct rtc_wkalrm *alarm)
 {
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
@@ -267,21 +268,21 @@ static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client,
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	ret = rv3029c2_i2c_get_sr(client, regs);
+	ret = rv3029_i2c_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	regs[RV3029C2_A_SC-RV3029C2_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
-	regs[RV3029C2_A_MN-RV3029C2_A_SC] = bin2bcd(tm->tm_min & 0x7f);
-	regs[RV3029C2_A_HR-RV3029C2_A_SC] = bin2bcd(tm->tm_hour & 0x3f);
-	regs[RV3029C2_A_DT-RV3029C2_A_SC] = bin2bcd(tm->tm_mday & 0x3f);
-	regs[RV3029C2_A_MO-RV3029C2_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1);
-	regs[RV3029C2_A_DW-RV3029C2_A_SC] = bin2bcd((tm->tm_wday & 7) - 1);
-	regs[RV3029C2_A_YR-RV3029C2_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100);
-
-	ret = rv3029c2_i2c_write_regs(client, RV3029C2_A_SC, regs,
-					RV3029C2_ALARM_SECTION_LEN);
+	regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
+	regs[RV3029_A_MN-RV3029_A_SC] = bin2bcd(tm->tm_min & 0x7f);
+	regs[RV3029_A_HR-RV3029_A_SC] = bin2bcd(tm->tm_hour & 0x3f);
+	regs[RV3029_A_DT-RV3029_A_SC] = bin2bcd(tm->tm_mday & 0x3f);
+	regs[RV3029_A_MO-RV3029_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1);
+	regs[RV3029_A_DW-RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1);
+	regs[RV3029_A_YR-RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100);
+
+	ret = rv3029_i2c_write_regs(client, RV3029_A_SC, regs,
+				    RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
@@ -289,28 +290,28 @@ static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client,
 		u8 buf[1];
 
 		/* clear AF flag */
-		ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_FLAGS,
-						buf, 1);
+		ret = rv3029_i2c_read_regs(client, RV3029_IRQ_FLAGS,
+					   buf, 1);
 		if (ret < 0) {
 			dev_err(&client->dev, "can't read alarm flag\n");
 			return ret;
 		}
-		buf[0] &= ~RV3029C2_IRQ_FLAGS_AF;
-		ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_FLAGS,
-						buf, 1);
+		buf[0] &= ~RV3029_IRQ_FLAGS_AF;
+		ret = rv3029_i2c_write_regs(client, RV3029_IRQ_FLAGS,
+					    buf, 1);
 		if (ret < 0) {
 			dev_err(&client->dev, "can't set alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1);
+		ret = rv3029_rtc_i2c_alarm_set_irq(client, 1);
 		if (ret)
 			return ret;
 
 		dev_dbg(&client->dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 0);
+		ret = rv3029_rtc_i2c_alarm_set_irq(client, 0);
 		if (ret)
 			return ret;
 
@@ -320,13 +321,13 @@ static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client,
 	return 0;
 }
 
-static int rv3029c2_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	return rv3029c2_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
+	return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
 }
 
 static int
-rv3029c2_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
+rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -339,26 +340,26 @@ rv3029c2_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	regs[RV3029C2_W_SEC-RV3029C2_W_SEC] = bin2bcd(tm->tm_sec);
-	regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC] = bin2bcd(tm->tm_min);
-	regs[RV3029C2_W_HOURS-RV3029C2_W_SEC] = bin2bcd(tm->tm_hour);
-	regs[RV3029C2_W_DATE-RV3029C2_W_SEC] = bin2bcd(tm->tm_mday);
-	regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC] = bin2bcd(tm->tm_mon+1);
-	regs[RV3029C2_W_DAYS-RV3029C2_W_SEC] = bin2bcd((tm->tm_wday & 7)+1);
-	regs[RV3029C2_W_YEARS-RV3029C2_W_SEC] = bin2bcd(tm->tm_year - 100);
+	regs[RV3029_W_SEC-RV3029_W_SEC] = bin2bcd(tm->tm_sec);
+	regs[RV3029_W_MINUTES-RV3029_W_SEC] = bin2bcd(tm->tm_min);
+	regs[RV3029_W_HOURS-RV3029_W_SEC] = bin2bcd(tm->tm_hour);
+	regs[RV3029_W_DATE-RV3029_W_SEC] = bin2bcd(tm->tm_mday);
+	regs[RV3029_W_MONTHS-RV3029_W_SEC] = bin2bcd(tm->tm_mon+1);
+	regs[RV3029_W_DAYS-RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7)+1);
+	regs[RV3029_W_YEARS-RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
 
-	ret = rv3029c2_i2c_write_regs(client, RV3029C2_W_SEC, regs,
-					RV3029C2_WATCH_SECTION_LEN);
+	ret = rv3029_i2c_write_regs(client, RV3029_W_SEC, regs,
+				    RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
-	ret = rv3029c2_i2c_get_sr(client, regs);
+	ret = rv3029_i2c_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret = rv3029c2_i2c_set_sr(client, (regs[0] & ~RV3029C2_STATUS_PON));
+	ret = rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
@@ -367,26 +368,26 @@ rv3029c2_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 	return 0;
 }
 
-static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm)
+static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029c2_i2c_set_time(to_i2c_client(dev), tm);
+	return rv3029_i2c_set_time(to_i2c_client(dev), tm);
 }
 
-static const struct rtc_class_ops rv3029c2_rtc_ops = {
-	.read_time	= rv3029c2_rtc_read_time,
-	.set_time	= rv3029c2_rtc_set_time,
-	.read_alarm	= rv3029c2_rtc_read_alarm,
-	.set_alarm	= rv3029c2_rtc_set_alarm,
+static const struct rtc_class_ops rv3029_rtc_ops = {
+	.read_time	= rv3029_rtc_read_time,
+	.set_time	= rv3029_rtc_set_time,
+	.read_alarm	= rv3029_rtc_read_alarm,
+	.set_alarm	= rv3029_rtc_set_alarm,
 };
 
-static struct i2c_device_id rv3029c2_id[] = {
+static struct i2c_device_id rv3029_id[] = {
 	{ "rv3029c2", 0 },
 	{ }
 };
-MODULE_DEVICE_TABLE(i2c, rv3029c2_id);
+MODULE_DEVICE_TABLE(i2c, rv3029_id);
 
-static int rv3029c2_probe(struct i2c_client *client,
-			  const struct i2c_device_id *id)
+static int rv3029_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 	struct rtc_device *rtc;
 	int rc = 0;
@@ -395,14 +396,14 @@ static int rv3029c2_probe(struct i2c_client *client,
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
 		return -ENODEV;
 
-	rc = rv3029c2_i2c_get_sr(client, buf);
+	rc = rv3029_i2c_get_sr(client, buf);
 	if (rc < 0) {
 		dev_err(&client->dev, "reading status failed\n");
 		return rc;
 	}
 
 	rtc = devm_rtc_device_register(&client->dev, client->name,
-					&rv3029c2_rtc_ops, THIS_MODULE);
+				       &rv3029_rtc_ops, THIS_MODULE);
 
 	if (IS_ERR(rtc))
 		return PTR_ERR(rtc);
@@ -412,16 +413,16 @@ static int rv3029c2_probe(struct i2c_client *client,
 	return 0;
 }
 
-static struct i2c_driver rv3029c2_driver = {
+static struct i2c_driver rv3029_driver = {
 	.driver = {
 		.name = "rtc-rv3029c2",
 	},
-	.probe = rv3029c2_probe,
-	.id_table = rv3029c2_id,
+	.probe		= rv3029_probe,
+	.id_table	= rv3029_id,
 };
 
-module_i2c_driver(rv3029c2_driver);
+module_i2c_driver(rv3029_driver);
 
 MODULE_AUTHOR("Gregory Hermant <[email protected]>");
-MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver");
+MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
 MODULE_LICENSE("GPL");
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#9 lore raw

PATCH 2/6 rtc-rv3029: Add "rv3029" I2C device id

In reply to a message not in the archive

The C2 suffix does not appear in the latest datasheet, so add a device ID without it.

---
 drivers/rtc/rtc-rv3029c2.c | 1 +
 1 file changed, 1 insertion(+)
drivers/rtc/rtc-rv3029c2.c +1 -0
index 3083ace..fc0dbc4 100644
@@ -381,6 +381,7 @@ static const struct rtc_class_ops rv3029_rtc_ops = {
 };
 
 static struct i2c_device_id rv3029_id[] = {
+	{ "rv3029", 0 },
 	{ "rv3029c2", 0 },
 	{ }
 };
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#10 lore raw

PATCH v3 2/6 rtc-rv3029: Add "rv3029" I2C device id

The C2 suffix does not appear in the latest datasheet, so add a device ID without it.

---
 drivers/rtc/rtc-rv3029c2.c | 1 +
 1 file changed, 1 insertion(+)
drivers/rtc/rtc-rv3029c2.c +1 -0
index 3083ace..fc0dbc4 100644
@@ -381,6 +381,7 @@ static const struct rtc_class_ops rv3029_rtc_ops = {
 };
 
 static struct i2c_device_id rv3029_id[] = {
+	{ "rv3029", 0 },
 	{ "rv3029c2", 0 },
 	{ }
 };
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#11 lore raw

PATCH 3/6 rtc-rv3029: Add missing register definitions

In reply to a message not in the archive

This adds all (according to the data sheet) missing register and bit definitions.
It also fixes the definition of the trickle charger bit masks.

---
 drivers/rtc/rtc-rv3029c2.c | 61 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 45 insertions(+), 16 deletions(-)
drivers/rtc/rtc-rv3029c2.c +45 -16
index fc0dbc4..29cc871 100644
@@ -22,25 +22,42 @@
 /* Register map */
 /* control section */
 #define RV3029_ONOFF_CTRL		0x00
+#define RV3029_ONOFF_CTRL_WE		BIT(0)
+#define RV3029_ONOFF_CTRL_TE		BIT(1)
+#define RV3029_ONOFF_CTRL_TAR		BIT(2)
+#define RV3029_ONOFF_CTRL_EERE		BIT(3)
+#define RV3029_ONOFF_CTRL_SRON		BIT(4)
+#define RV3029_ONOFF_CTRL_TD0		BIT(5)
+#define RV3029_ONOFF_CTRL_TD1		BIT(6)
+#define RV3029_ONOFF_CTRL_CLKINT	BIT(7)
 #define RV3029_IRQ_CTRL			0x01
-#define RV3029_IRQ_CTRL_AIE		(1 << 0)
+#define RV3029_IRQ_CTRL_AIE		BIT(0)
+#define RV3029_IRQ_CTRL_TIE		BIT(1)
+#define RV3029_IRQ_CTRL_V1IE		BIT(2)
+#define RV3029_IRQ_CTRL_V2IE		BIT(3)
+#define RV3029_IRQ_CTRL_SRIE		BIT(4)
 #define RV3029_IRQ_FLAGS		0x02
-#define RV3029_IRQ_FLAGS_AF		(1 << 0)
+#define RV3029_IRQ_FLAGS_AF		BIT(0)
+#define RV3029_IRQ_FLAGS_TF		BIT(1)
+#define RV3029_IRQ_FLAGS_V1IF		BIT(2)
+#define RV3029_IRQ_FLAGS_V2IF		BIT(3)
+#define RV3029_IRQ_FLAGS_SRF		BIT(4)
 #define RV3029_STATUS			0x03
-#define RV3029_STATUS_VLOW1		(1 << 2)
-#define RV3029_STATUS_VLOW2		(1 << 3)
-#define RV3029_STATUS_SR		(1 << 4)
-#define RV3029_STATUS_PON		(1 << 5)
-#define RV3029_STATUS_EEBUSY		(1 << 7)
+#define RV3029_STATUS_VLOW1		BIT(2)
+#define RV3029_STATUS_VLOW2		BIT(3)
+#define RV3029_STATUS_SR		BIT(4)
+#define RV3029_STATUS_PON		BIT(5)
+#define RV3029_STATUS_EEBUSY		BIT(7)
 #define RV3029_RST_CTRL			0x04
+#define RV3029_RST_CTRL_SYSR		BIT(4)
 #define RV3029_CONTROL_SECTION_LEN	0x05
 
 /* watch section */
 #define RV3029_W_SEC			0x08
 #define RV3029_W_MINUTES		0x09
 #define RV3029_W_HOURS			0x0A
-#define RV3029_REG_HR_12_24		(1<<6)  /* 24h/12h mode */
-#define RV3029_REG_HR_PM		(1<<5)  /* PM/AM bit in 12h mode */
+#define RV3029_REG_HR_12_24		BIT(6) /* 24h/12h mode */
+#define RV3029_REG_HR_PM		BIT(5) /* PM/AM bit in 12h mode */
 #define RV3029_W_DATE			0x0B
 #define RV3029_W_DAYS			0x0C
 #define RV3029_W_MONTHS			0x0D
@@ -67,16 +84,28 @@
 /* eeprom data section */
 #define RV3029_E2P_EEDATA1		0x28
 #define RV3029_E2P_EEDATA2		0x29
+#define RV3029_E2PDATA_SECTION_LEN	0x02
 
 /* eeprom control section */
 #define RV3029_CONTROL_E2P_EECTRL	0x30
-#define RV3029_TRICKLE_1K		(1<<0)  /*  1K resistance */
-#define RV3029_TRICKLE_5K		(1<<1)  /*  5K resistance */
-#define RV3029_TRICKLE_20K		(1<<2)  /* 20K resistance */
-#define RV3029_TRICKLE_80K		(1<<3)  /* 80K resistance */
-#define RV3029_CONTROL_E2P_XTALOFFSET	0x31
-#define RV3029_CONTROL_E2P_QCOEF	0x32
-#define RV3029_CONTROL_E2P_TURNOVER	0x33
+#define RV3029_EECTRL_THP		BIT(0) /* temp scan interval */
+#define RV3029_EECTRL_THE		BIT(1) /* thermometer enable */
+#define RV3029_EECTRL_FD0		BIT(2) /* CLKOUT */
+#define RV3029_EECTRL_FD1		BIT(3) /* CLKOUT */
+#define RV3029_TRICKLE_1K		BIT(4) /* 1.5K resistance */
+#define RV3029_TRICKLE_5K		BIT(5) /* 5K   resistance */
+#define RV3029_TRICKLE_20K		BIT(6) /* 20K  resistance */
+#define RV3029_TRICKLE_80K		BIT(7) /* 80K  resistance */
+#define RV3029_TRICKLE_MASK		(RV3029_TRICKLE_1K |\
+					 RV3029_TRICKLE_5K |\
+					 RV3029_TRICKLE_20K |\
+					 RV3029_TRICKLE_80K)
+#define RV3029_TRICKLE_SHIFT		4
+#define RV3029_CONTROL_E2P_XOFFS	0x31 /* XTAL offset */
+#define RV3029_CONTROL_E2P_XOFFS_SIGN	BIT(7) /* Sign: 1->pos, 0->neg */
+#define RV3029_CONTROL_E2P_QCOEF	0x32 /* XTAL temp drift coef */
+#define RV3029_CONTROL_E2P_TURNOVER	0x33 /* XTAL turnover temp (in *C) */
+#define RV3029_CONTROL_E2P_TOV_MASK	0x3F /* XTAL turnover temp mask */
 
 /* user ram section */
 #define RV3029_USR1_RAM_PAGE		0x38
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#12 lore raw

PATCH v3 3/6 rtc-rv3029: Add missing register definitions

This adds all (according to the data sheet) missing register and bit definitions.
It also fixes the definition of the trickle charger bit masks.

---
 drivers/rtc/rtc-rv3029c2.c | 61 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 45 insertions(+), 16 deletions(-)
drivers/rtc/rtc-rv3029c2.c +45 -16
index fc0dbc4..29cc871 100644
@@ -22,25 +22,42 @@
 /* Register map */
 /* control section */
 #define RV3029_ONOFF_CTRL		0x00
+#define RV3029_ONOFF_CTRL_WE		BIT(0)
+#define RV3029_ONOFF_CTRL_TE		BIT(1)
+#define RV3029_ONOFF_CTRL_TAR		BIT(2)
+#define RV3029_ONOFF_CTRL_EERE		BIT(3)
+#define RV3029_ONOFF_CTRL_SRON		BIT(4)
+#define RV3029_ONOFF_CTRL_TD0		BIT(5)
+#define RV3029_ONOFF_CTRL_TD1		BIT(6)
+#define RV3029_ONOFF_CTRL_CLKINT	BIT(7)
 #define RV3029_IRQ_CTRL			0x01
-#define RV3029_IRQ_CTRL_AIE		(1 << 0)
+#define RV3029_IRQ_CTRL_AIE		BIT(0)
+#define RV3029_IRQ_CTRL_TIE		BIT(1)
+#define RV3029_IRQ_CTRL_V1IE		BIT(2)
+#define RV3029_IRQ_CTRL_V2IE		BIT(3)
+#define RV3029_IRQ_CTRL_SRIE		BIT(4)
 #define RV3029_IRQ_FLAGS		0x02
-#define RV3029_IRQ_FLAGS_AF		(1 << 0)
+#define RV3029_IRQ_FLAGS_AF		BIT(0)
+#define RV3029_IRQ_FLAGS_TF		BIT(1)
+#define RV3029_IRQ_FLAGS_V1IF		BIT(2)
+#define RV3029_IRQ_FLAGS_V2IF		BIT(3)
+#define RV3029_IRQ_FLAGS_SRF		BIT(4)
 #define RV3029_STATUS			0x03
-#define RV3029_STATUS_VLOW1		(1 << 2)
-#define RV3029_STATUS_VLOW2		(1 << 3)
-#define RV3029_STATUS_SR		(1 << 4)
-#define RV3029_STATUS_PON		(1 << 5)
-#define RV3029_STATUS_EEBUSY		(1 << 7)
+#define RV3029_STATUS_VLOW1		BIT(2)
+#define RV3029_STATUS_VLOW2		BIT(3)
+#define RV3029_STATUS_SR		BIT(4)
+#define RV3029_STATUS_PON		BIT(5)
+#define RV3029_STATUS_EEBUSY		BIT(7)
 #define RV3029_RST_CTRL			0x04
+#define RV3029_RST_CTRL_SYSR		BIT(4)
 #define RV3029_CONTROL_SECTION_LEN	0x05
 
 /* watch section */
 #define RV3029_W_SEC			0x08
 #define RV3029_W_MINUTES		0x09
 #define RV3029_W_HOURS			0x0A
-#define RV3029_REG_HR_12_24		(1<<6)  /* 24h/12h mode */
-#define RV3029_REG_HR_PM		(1<<5)  /* PM/AM bit in 12h mode */
+#define RV3029_REG_HR_12_24		BIT(6) /* 24h/12h mode */
+#define RV3029_REG_HR_PM		BIT(5) /* PM/AM bit in 12h mode */
 #define RV3029_W_DATE			0x0B
 #define RV3029_W_DAYS			0x0C
 #define RV3029_W_MONTHS			0x0D
@@ -67,16 +84,28 @@
 /* eeprom data section */
 #define RV3029_E2P_EEDATA1		0x28
 #define RV3029_E2P_EEDATA2		0x29
+#define RV3029_E2PDATA_SECTION_LEN	0x02
 
 /* eeprom control section */
 #define RV3029_CONTROL_E2P_EECTRL	0x30
-#define RV3029_TRICKLE_1K		(1<<0)  /*  1K resistance */
-#define RV3029_TRICKLE_5K		(1<<1)  /*  5K resistance */
-#define RV3029_TRICKLE_20K		(1<<2)  /* 20K resistance */
-#define RV3029_TRICKLE_80K		(1<<3)  /* 80K resistance */
-#define RV3029_CONTROL_E2P_XTALOFFSET	0x31
-#define RV3029_CONTROL_E2P_QCOEF	0x32
-#define RV3029_CONTROL_E2P_TURNOVER	0x33
+#define RV3029_EECTRL_THP		BIT(0) /* temp scan interval */
+#define RV3029_EECTRL_THE		BIT(1) /* thermometer enable */
+#define RV3029_EECTRL_FD0		BIT(2) /* CLKOUT */
+#define RV3029_EECTRL_FD1		BIT(3) /* CLKOUT */
+#define RV3029_TRICKLE_1K		BIT(4) /* 1.5K resistance */
+#define RV3029_TRICKLE_5K		BIT(5) /* 5K   resistance */
+#define RV3029_TRICKLE_20K		BIT(6) /* 20K  resistance */
+#define RV3029_TRICKLE_80K		BIT(7) /* 80K  resistance */
+#define RV3029_TRICKLE_MASK		(RV3029_TRICKLE_1K |\
+					 RV3029_TRICKLE_5K |\
+					 RV3029_TRICKLE_20K |\
+					 RV3029_TRICKLE_80K)
+#define RV3029_TRICKLE_SHIFT		4
+#define RV3029_CONTROL_E2P_XOFFS	0x31 /* XTAL offset */
+#define RV3029_CONTROL_E2P_XOFFS_SIGN	BIT(7) /* Sign: 1->pos, 0->neg */
+#define RV3029_CONTROL_E2P_QCOEF	0x32 /* XTAL temp drift coef */
+#define RV3029_CONTROL_E2P_TURNOVER	0x33 /* XTAL turnover temp (in *C) */
+#define RV3029_CONTROL_E2P_TOV_MASK	0x3F /* XTAL turnover temp mask */
 
 /* user ram section */
 #define RV3029_USR1_RAM_PAGE		0x38
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#13 lore raw

PATCH 4/6 rtc-rv3029: Add i2c register update-bits helper

In reply to a message not in the archive

This simplifies mask/set operations on device I2C registers.

---
 drivers/rtc/rtc-rv3029c2.c | 54 ++++++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 26 deletions(-)
drivers/rtc/rtc-rv3029c2.c +28 -26
index 29cc871..769f73a 100644
@@ -2,6 +2,7 @@
  * Micro Crystal RV-3029 rtc class driver
  *
  * Author: Gregory Hermant <[email protected]>
+ *         Michael Buesch <[email protected]>
  *
  * based on previously existing rtc class drivers
  *
@@ -143,6 +144,24 @@ rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
 }
 
 static int
+rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set)
+{
+	u8 buf;
+	int ret;
+
+	ret = rv3029_i2c_read_regs(client, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
+	buf &= mask;
+	buf |= set;
+	ret = rv3029_i2c_write_regs(client, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int
 rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
 {
 	int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
@@ -260,22 +279,13 @@ static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
 					int enable)
 {
 	int ret;
-	u8 buf[1];
-
-	/* enable AIE irq */
-	ret = rv3029_i2c_read_regs(client, RV3029_IRQ_CTRL, buf, 1);
-	if (ret < 0) {
-		dev_err(&client->dev, "can't read INT reg\n");
-		return ret;
-	}
-	if (enable)
-		buf[0] |= RV3029_IRQ_CTRL_AIE;
-	else
-		buf[0] &= ~RV3029_IRQ_CTRL_AIE;
 
-	ret = rv3029_i2c_write_regs(client, RV3029_IRQ_CTRL, buf, 1);
+	/* enable/disable AIE irq */
+	ret = rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
+				     (u8)~RV3029_IRQ_CTRL_AIE,
+				     (enable ? RV3029_IRQ_CTRL_AIE : 0));
 	if (ret < 0) {
-		dev_err(&client->dev, "can't set INT reg\n");
+		dev_err(&client->dev, "can't update INT reg\n");
 		return ret;
 	}
 
@@ -316,20 +326,11 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
 		return ret;
 
 	if (alarm->enabled) {
-		u8 buf[1];
-
 		/* clear AF flag */
-		ret = rv3029_i2c_read_regs(client, RV3029_IRQ_FLAGS,
-					   buf, 1);
-		if (ret < 0) {
-			dev_err(&client->dev, "can't read alarm flag\n");
-			return ret;
-		}
-		buf[0] &= ~RV3029_IRQ_FLAGS_AF;
-		ret = rv3029_i2c_write_regs(client, RV3029_IRQ_FLAGS,
-					    buf, 1);
+		ret = rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
+					     (u8)~RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
-			dev_err(&client->dev, "can't set alarm flag\n");
+			dev_err(&client->dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
@@ -454,5 +455,6 @@ static struct i2c_driver rv3029_driver = {
 module_i2c_driver(rv3029_driver);
 
 MODULE_AUTHOR("Gregory Hermant <[email protected]>");
+MODULE_AUTHOR("Michael Buesch <[email protected]>");
 MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
 MODULE_LICENSE("GPL");
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#14 lore raw

[rtc-linux] Re: [PATCH 4/6] rtc-rv3029: Add i2c register update-bits helper

Quoted 5 lines · On 04/03/2016 at 19:56:11 +0100, Michael B=C3=BCsch wrote :

This simplifies mask/set operations on device I2C registers. =20

---
drivers/rtc/rtc-rv3029c2.c | 54 ++++++++++++++++++++++++----------------=

------

drivers/rtc/rtc-rv3029c2.c rv3029_i2c_write_regs(struct i2c_client *client, u8 =

Quoted 15 lines
 1 file changed, 28 insertions(+), 26 deletions(-)

=20

drivers/rtc/rtc-rv3029c2.c +1 -0
index 29cc871..769f73a 100644
@@ -2,6 +2,7 @@
  * Micro Crystal RV-3029 rtc class driver
  *
  * Author: Gregory Hermant <[email protected]>
+ *         Michael Buesch <[email protected]>
  *
  * based on previously existing rtc class drivers
  *
@@ -143,6 +144,24 @@ rv3029_i2c_write_regs(struct i2c_client *client, u8 =

reg, u8 const buf[],

Quoted 4 lines
drivers/rtc/rtc-rv3029c2.c +0 -0
 }

=20
static int
+rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 se=

t)

drivers/rtc/rtc-rv3029c2.c rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],

Quoted 9 lines
drivers/rtc/rtc-rv3029c2.c +9 -0
+{
+	u8 buf;
+	int ret;
+
+	ret =3D rv3029_i2c_read_regs(client, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
+	buf &=3D mask;
+	buf |=3D set;

Well, this is not exactly what is expected from an update_bits function, it should be:

	buf &=3D ~mask;
	buf |=3D set & mask;

What you pass to the function is the mask of bits you want to set.

drivers/rtc/rtc-rv3029c2.c static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_=

Quoted 12 lines
drivers/rtc/rtc-rv3029c2.c +8 -0
+	ret =3D rv3029_i2c_write_regs(client, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int
 rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
 {
 	int ret =3D rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
@@ -260,22 +279,13 @@ static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_=

client *client,

Quoted 16 lines
drivers/rtc/rtc-rv3029c2.c +0 -12
 					int enable)
 {
 	int ret;
-	u8 buf[1];
-
-	/* enable AIE irq */
-	ret =3D rv3029_i2c_read_regs(client, RV3029_IRQ_CTRL, buf, 1);
-	if (ret < 0) {
-		dev_err(&client->dev, "can't read INT reg\n");
-		return ret;
-	}
-	if (enable)
-		buf[0] |=3D RV3029_IRQ_CTRL_AIE;
-	else
-		buf[0] &=3D ~RV3029_IRQ_CTRL_AIE;

=20

drivers/rtc/rtc-rv3029c2.c static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client, · line 285

Quoted 4 lines
drivers/rtc/rtc-rv3029c2.c +3 -1
-	ret =3D rv3029_i2c_write_regs(client, RV3029_IRQ_CTRL, buf, 1);
+	/* enable/disable AIE irq */
+	ret =3D rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
+				     (u8)~RV3029_IRQ_CTRL_AIE,

This allows to remove the bitwise not here

drivers/rtc/rtc-rv3029c2.c static int rv3029_rtc_i2c_set_alarm(struct i2c_clie=

Quoted 8 lines
drivers/rtc/rtc-rv3029c2.c +2 -1
+				     (enable ? RV3029_IRQ_CTRL_AIE : 0));
 	if (ret < 0) {
-		dev_err(&client->dev, "can't set INT reg\n");
+		dev_err(&client->dev, "can't update INT reg\n");
 		return ret;
 	}

=20

drivers/rtc/rtc-rv3029c2.c +0 -0
@@ -316,20 +326,11 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_clie=

nt *client,

Quoted 7 lines
drivers/rtc/rtc-rv3029c2.c +0 -0
 		return ret;

=20

drivers/rtc/rtc-rv3029c2.c +0 -3
 	if (alarm->enabled) {
-		u8 buf[1];
-
 		/* clear AF flag */
-		ret =3D rv3029_i2c_read_regs(client, RV3029_IRQ_FLAGS,

drivers/rtc/rtc-rv3029c2.c static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client, · line 331

Quoted 10 lines
drivers/rtc/rtc-rv3029c2.c +2 -8
-					   buf, 1);
-		if (ret < 0) {
-			dev_err(&client->dev, "can't read alarm flag\n");
-			return ret;
-		}
-		buf[0] &=3D ~RV3029_IRQ_FLAGS_AF;
-		ret =3D rv3029_i2c_write_regs(client, RV3029_IRQ_FLAGS,
-					    buf, 1);
+		ret =3D rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
+					     (u8)~RV3029_IRQ_FLAGS_AF, 0);

and here.

Quoted 8 lines
drivers/rtc/rtc-rv3029c2.c +1 -1
 		if (ret < 0) {
-			dev_err(&client->dev, "can't set alarm flag\n");
+			dev_err(&client->dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
@@ -454,5 +455,6 @@ static struct i2c_driver rv3029_driver =3D {
 module_i2c_driver(rv3029_driver);
Quoted 8 lines

=20
MODULE_AUTHOR("Gregory Hermant <[email protected]>");
+MODULE_AUTHOR("Michael Buesch <[email protected]>");
MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver"); MODULE_LICENSE("GPL");
--=20
2.7.0
=20

--=20
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

--=20
--=20
You received this message because you are subscribed to "rtc-linux". Membership options at http://groups.google.com/group/rtc-linux . Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---=20
You received this message because you are subscribed to the Google Groups "= rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to [email protected].
For more options, visit https://groups.google.com/d/optout.

#15 lore raw

[rtc-linux] Re: [PATCH 4/6] rtc-rv3029: Add i2c register update-bits helper

Quoted 10 lines · On Fri, 4 Mar 2016 20:42:23 +0100 Alexandre Belloni…

drivers/rtc/rtc-rv3029c2.c rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[], · line 156

Quoted 2 lines
drivers/rtc/rtc-rv3029c2.c +2 -0
+	buf &= mask;
+	buf |= set;  

Well, this is not exactly what is expected from an update_bits function, it should be:

	buf &= ~mask;
	buf |= set & mask;

What you pass to the function is the mask of bits you want to set.

Meh, ok. Everybody does seem to feel differently on that issue. I did it exactly like this with ~mask in the b43 driver and received a lot of bashing for it. :)

But well, to me either way is fine. So I'll change this to do it with ~mask too.

Signature · 12 lines
Michael

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#16 lore raw

PATCH v3 4/6 rtc-rv3029: Add i2c register update-bits helper

In reply to Michael Büsch

This simplifies mask/set operations on device I2C registers.

---
 drivers/rtc/rtc-rv3029c2.c | 54 ++++++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 26 deletions(-)
drivers/rtc/rtc-rv3029c2.c +28 -26
index 29cc871..a58188e 100644
@@ -2,6 +2,7 @@
  * Micro Crystal RV-3029 rtc class driver
  *
  * Author: Gregory Hermant <[email protected]>
+ *         Michael Buesch <[email protected]>
  *
  * based on previously existing rtc class drivers
  *
@@ -143,6 +144,24 @@ rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
 }
 
 static int
+rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set)
+{
+	u8 buf;
+	int ret;
+
+	ret = rv3029_i2c_read_regs(client, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
+	buf &= ~mask;
+	buf |= set & mask;
+	ret = rv3029_i2c_write_regs(client, reg, &buf, 1);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int
 rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
 {
 	int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
@@ -260,22 +279,13 @@ static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
 					int enable)
 {
 	int ret;
-	u8 buf[1];
-
-	/* enable AIE irq */
-	ret = rv3029_i2c_read_regs(client, RV3029_IRQ_CTRL, buf, 1);
-	if (ret < 0) {
-		dev_err(&client->dev, "can't read INT reg\n");
-		return ret;
-	}
-	if (enable)
-		buf[0] |= RV3029_IRQ_CTRL_AIE;
-	else
-		buf[0] &= ~RV3029_IRQ_CTRL_AIE;
 
-	ret = rv3029_i2c_write_regs(client, RV3029_IRQ_CTRL, buf, 1);
+	/* enable/disable AIE irq */
+	ret = rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
+				     RV3029_IRQ_CTRL_AIE,
+				     (enable ? RV3029_IRQ_CTRL_AIE : 0));
 	if (ret < 0) {
-		dev_err(&client->dev, "can't set INT reg\n");
+		dev_err(&client->dev, "can't update INT reg\n");
 		return ret;
 	}
 
@@ -316,20 +326,11 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
 		return ret;
 
 	if (alarm->enabled) {
-		u8 buf[1];
-
 		/* clear AF flag */
-		ret = rv3029_i2c_read_regs(client, RV3029_IRQ_FLAGS,
-					   buf, 1);
-		if (ret < 0) {
-			dev_err(&client->dev, "can't read alarm flag\n");
-			return ret;
-		}
-		buf[0] &= ~RV3029_IRQ_FLAGS_AF;
-		ret = rv3029_i2c_write_regs(client, RV3029_IRQ_FLAGS,
-					    buf, 1);
+		ret = rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
+					     RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
-			dev_err(&client->dev, "can't set alarm flag\n");
+			dev_err(&client->dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
@@ -454,5 +455,6 @@ static struct i2c_driver rv3029_driver = {
 module_i2c_driver(rv3029_driver);
 
 MODULE_AUTHOR("Gregory Hermant <[email protected]>");
+MODULE_AUTHOR("Michael Buesch <[email protected]>");
 MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
 MODULE_LICENSE("GPL");
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#17 lore raw

PATCH 5/6 rtc-rv3029: Add functions for EEPROM access

In reply to a message not in the archive

This adds functions for access to the EEPROM memory on the rv3029.

---
 drivers/rtc/rtc-rv3029c2.c | 124 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)
drivers/rtc/rtc-rv3029c2.c +124 -0
index 769f73a..fb85e0d 100644
@@ -19,6 +19,9 @@
 #include <linux/i2c.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
 
 /* Register map */
 /* control section */
@@ -186,6 +189,127 @@ rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
 	return 0;
 }
 
+static int rv3029_eeprom_busywait(struct i2c_client *client)
+{
+	int i, ret;
+	u8 sr;
+
+	for (i = 100; i > 0; i--) {
+		ret = rv3029_i2c_get_sr(client, &sr);
+		if (ret < 0)
+			break;
+		if (!(sr & RV3029_STATUS_EEBUSY))
+			break;
+		usleep_range(1000, 10000);
+	}
+	if (i <= 0) {
+		dev_err(&client->dev, "EEPROM busy wait timeout.\n");
+		return -ETIMEDOUT;
+	}
+
+	return ret;
+}
+
+static int rv3029_eeprom_exit(struct i2c_client *client)
+{
+	/* Re-enable eeprom refresh */
+	return rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
+				      0xFF, RV3029_ONOFF_CTRL_EERE);
+}
+
+static int rv3029_eeprom_enter(struct i2c_client *client)
+{
+	int ret;
+	u8 sr;
+
+	/* Check whether we are in the allowed voltage range. */
+	ret = rv3029_i2c_get_sr(client, &sr);
+	if (ret < 0)
+		return ret;
+	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+		/* We clear the bits and retry once just in case
+		 * we had a brown out in early startup.
+		 */
+		sr &= ~RV3029_STATUS_VLOW1;
+		sr &= ~RV3029_STATUS_VLOW2;
+		ret = rv3029_i2c_set_sr(client, sr);
+		if (ret < 0)
+			return ret;
+		usleep_range(1000, 10000);
+		ret = rv3029_i2c_get_sr(client, &sr);
+		if (ret < 0)
+			return ret;
+		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+			dev_err(&client->dev,
+				"Supply voltage is too low to safely access the EEPROM.\n");
+			return -ENODEV;
+		}
+	}
+
+	/* Disable eeprom refresh. */
+	ret = rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
+				     (u8)~RV3029_ONOFF_CTRL_EERE, 0);
+	if (ret < 0)
+		return ret;
+
+	/* Wait for any previous eeprom accesses to finish. */
+	ret = rv3029_eeprom_busywait(client);
+	if (ret < 0)
+		rv3029_eeprom_exit(client);
+
+	return ret;
+}
+
+static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
+			      u8 buf[], size_t len)
+{
+	int ret, err;
+
+	err = rv3029_eeprom_enter(client);
+	if (err < 0)
+		return err;
+
+	ret = rv3029_i2c_read_regs(client, reg, buf, len);
+
+	err = rv3029_eeprom_exit(client);
+	if (err < 0)
+		return err;
+
+	return ret;
+}
+
+static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
+			       u8 const buf[], size_t len)
+{
+	int ret, err;
+	size_t i;
+	u8 tmp;
+
+	err = rv3029_eeprom_enter(client);
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < len; i++, reg++) {
+		ret = rv3029_i2c_read_regs(client, reg, &tmp, 1);
+		if (ret < 0)
+			break;
+		if (tmp != buf[i]) {
+			ret = rv3029_i2c_write_regs(client, reg, &buf[i], 1);
+			if (ret < 0)
+				break;
+		}
+		ret = rv3029_eeprom_busywait(client);
+		if (ret < 0)
+			break;
+	}
+
+	err = rv3029_eeprom_exit(client);
+	if (err < 0)
+		return err;
+
+	return ret;
+}
+
 static int
 rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 {
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#18 lore raw

PATCH v3 5/6 rtc-rv3029: Add functions for EEPROM access

This adds functions for access to the EEPROM memory on the rv3029.

---
 drivers/rtc/rtc-rv3029c2.c | 125 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)
drivers/rtc/rtc-rv3029c2.c +125 -0
index a58188e..e59b8a5 100644
@@ -19,6 +19,9 @@
 #include <linux/i2c.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
 
 /* Register map */
 /* control section */
@@ -186,6 +189,128 @@ rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
 	return 0;
 }
 
+static int rv3029_eeprom_busywait(struct i2c_client *client)
+{
+	int i, ret;
+	u8 sr;
+
+	for (i = 100; i > 0; i--) {
+		ret = rv3029_i2c_get_sr(client, &sr);
+		if (ret < 0)
+			break;
+		if (!(sr & RV3029_STATUS_EEBUSY))
+			break;
+		usleep_range(1000, 10000);
+	}
+	if (i <= 0) {
+		dev_err(&client->dev, "EEPROM busy wait timeout.\n");
+		return -ETIMEDOUT;
+	}
+
+	return ret;
+}
+
+static int rv3029_eeprom_exit(struct i2c_client *client)
+{
+	/* Re-enable eeprom refresh */
+	return rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
+				      RV3029_ONOFF_CTRL_EERE,
+				      RV3029_ONOFF_CTRL_EERE);
+}
+
+static int rv3029_eeprom_enter(struct i2c_client *client)
+{
+	int ret;
+	u8 sr;
+
+	/* Check whether we are in the allowed voltage range. */
+	ret = rv3029_i2c_get_sr(client, &sr);
+	if (ret < 0)
+		return ret;
+	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+		/* We clear the bits and retry once just in case
+		 * we had a brown out in early startup.
+		 */
+		sr &= ~RV3029_STATUS_VLOW1;
+		sr &= ~RV3029_STATUS_VLOW2;
+		ret = rv3029_i2c_set_sr(client, sr);
+		if (ret < 0)
+			return ret;
+		usleep_range(1000, 10000);
+		ret = rv3029_i2c_get_sr(client, &sr);
+		if (ret < 0)
+			return ret;
+		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+			dev_err(&client->dev,
+				"Supply voltage is too low to safely access the EEPROM.\n");
+			return -ENODEV;
+		}
+	}
+
+	/* Disable eeprom refresh. */
+	ret = rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
+				     RV3029_ONOFF_CTRL_EERE, 0);
+	if (ret < 0)
+		return ret;
+
+	/* Wait for any previous eeprom accesses to finish. */
+	ret = rv3029_eeprom_busywait(client);
+	if (ret < 0)
+		rv3029_eeprom_exit(client);
+
+	return ret;
+}
+
+static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
+			      u8 buf[], size_t len)
+{
+	int ret, err;
+
+	err = rv3029_eeprom_enter(client);
+	if (err < 0)
+		return err;
+
+	ret = rv3029_i2c_read_regs(client, reg, buf, len);
+
+	err = rv3029_eeprom_exit(client);
+	if (err < 0)
+		return err;
+
+	return ret;
+}
+
+static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
+			       u8 const buf[], size_t len)
+{
+	int ret, err;
+	size_t i;
+	u8 tmp;
+
+	err = rv3029_eeprom_enter(client);
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < len; i++, reg++) {
+		ret = rv3029_i2c_read_regs(client, reg, &tmp, 1);
+		if (ret < 0)
+			break;
+		if (tmp != buf[i]) {
+			ret = rv3029_i2c_write_regs(client, reg, &buf[i], 1);
+			if (ret < 0)
+				break;
+		}
+		ret = rv3029_eeprom_busywait(client);
+		if (ret < 0)
+			break;
+	}
+
+	err = rv3029_eeprom_exit(client);
+	if (err < 0)
+		return err;
+
+	return ret;
+}
+
 static int
 rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 {
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#19 lore raw

PATCH 6/6 rtc-rv3029: Add device tree property for trickle charger

In reply to a message not in the archive

The trickle charger resistor can be enabled via device tree property trickle-resistor-ohms.

---
 drivers/rtc/rtc-rv3029c2.c | 106 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 103 insertions(+), 3 deletions(-)
drivers/rtc/rtc-rv3029c2.c +103 -3
index fb85e0d..8a4e55a 100644
@@ -10,9 +10,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * NOTE: Currently this driver only supports the bare minimum for read
- * and write the RTC and alarms. The extra features provided by this chip
- * (trickle charger, eeprom, T° compensation) are unavailable.
  */
 
 #include <linux/module.h>
@@ -527,6 +524,107 @@ static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	return rv3029_i2c_set_time(to_i2c_client(dev), tm);
 }
 
+static const struct rv3029_trickle_tab_elem {
+	u32 r;		/* resistance in ohms */
+	u8 conf;	/* trickle config bits */
+} rv3029_trickle_tab[] = {
+	{
+		.r	= 1076,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
+			  RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
+	}, {
+		.r	= 1091,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
+			  RV3029_TRICKLE_20K,
+	}, {
+		.r	= 1137,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
+			  RV3029_TRICKLE_80K,
+	}, {
+		.r	= 1154,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K,
+	}, {
+		.r	= 1371,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_20K |
+			  RV3029_TRICKLE_80K,
+	}, {
+		.r	= 1395,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_20K,
+	}, {
+		.r	= 1472,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_80K,
+	}, {
+		.r	= 1500,
+		.conf	= RV3029_TRICKLE_1K,
+	}, {
+		.r	= 3810,
+		.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_20K |
+			  RV3029_TRICKLE_80K,
+	}, {
+		.r	= 4000,
+		.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_20K,
+	}, {
+		.r	= 4706,
+		.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_80K,
+	}, {
+		.r	= 5000,
+		.conf	= RV3029_TRICKLE_5K,
+	}, {
+		.r	= 16000,
+		.conf	= RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
+	}, {
+		.r	= 20000,
+		.conf	= RV3029_TRICKLE_20K,
+	}, {
+		.r	= 80000,
+		.conf	= RV3029_TRICKLE_80K,
+	},
+};
+
+static void rv3029_trickle_config(struct i2c_client *client)
+{
+	struct device_node *of_node = client->dev.of_node;
+	const struct rv3029_trickle_tab_elem *elem;
+	int i, err;
+	u32 ohms;
+	u8 eectrl;
+
+	if (!of_node)
+		return;
+
+	/* Configure the trickle charger. */
+	err = rv3029_eeprom_read(client, RV3029_CONTROL_E2P_EECTRL,
+				 &eectrl, 1);
+	if (err < 0) {
+		dev_err(&client->dev,
+			"Failed to read trickle charger config\n");
+		return;
+	}
+	err = of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms);
+	if (err) {
+		/* Disable trickle charger. */
+		eectrl &= ~RV3029_TRICKLE_MASK;
+	} else {
+		/* Enable trickle charger. */
+		for (i = 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++) {
+			elem = &rv3029_trickle_tab[i];
+			if (elem->r >= ohms)
+				break;
+		}
+		eectrl &= ~RV3029_TRICKLE_MASK;
+		eectrl |= elem->conf;
+		dev_info(&client->dev,
+			 "Trickle charger enabled at %d ohms resistance.\n",
+			 elem->r);
+	}
+	err = rv3029_eeprom_write(client, RV3029_CONTROL_E2P_EECTRL,
+				  &eectrl, 1);
+	if (err < 0) {
+		dev_err(&client->dev,
+			"Failed to write trickle charger config\n");
+	}
+}
+
 static const struct rtc_class_ops rv3029_rtc_ops = {
 	.read_time	= rv3029_rtc_read_time,
 	.set_time	= rv3029_rtc_set_time,
@@ -557,6 +655,8 @@ static int rv3029_probe(struct i2c_client *client,
 		return rc;
 	}
 
+	rv3029_trickle_config(client);
+
 	rtc = devm_rtc_device_register(&client->dev, client->name,
 				       &rv3029_rtc_ops, THIS_MODULE);
 
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#20 lore raw

[rtc-linux] Re: [PATCH 6/6] rtc-rv3029: Add device tree property for trickle charger

Quoted 7 lines · On 04/03/2016 at 19:56:54 +0100, Michael B=C3=BCsch wrote :
drivers/rtc/rtc-rv3029c2.c +7 -0
+	err =3D of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms);
+	if (err) {
+		/* Disable trickle charger. */
+		eectrl &=3D ~RV3029_TRICKLE_MASK;
+	} else {
+		/* Enable trickle charger. */
+		for (i =3D 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++) {

drivers/rtc/rtc-rv3029c2.c static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm) · line 619

Quoted 10 lines
drivers/rtc/rtc-rv3029c2.c +10 -0
+			elem =3D &rv3029_trickle_tab[i];
+			if (elem->r >=3D ohms)
+				break;
+		}
+		eectrl &=3D ~RV3029_TRICKLE_MASK;
+		eectrl |=3D elem->conf;
+		dev_info(&client->dev,
+			 "Trickle charger enabled at %d ohms resistance.\n",
+			 elem->r);
+	}

Now the you have an update_bits functions, you probably want to use it here. This simplifies the function.

Quoted 19 lines
drivers/rtc/rtc-rv3029c2.c +8 -0
+	err =3D rv3029_eeprom_write(client, RV3029_CONTROL_E2P_EECTRL,
+				  &eectrl, 1);
+	if (err < 0) {
+		dev_err(&client->dev,
+			"Failed to write trickle charger config\n");
+	}
+}
+
 static const struct rtc_class_ops rv3029_rtc_ops =3D {
 	.read_time	=3D rv3029_rtc_read_time,
 	.set_time	=3D rv3029_rtc_set_time,
@@ -557,6 +655,8 @@ static int rv3029_probe(struct i2c_client *client,
 		return rc;
 	}

=20

drivers/rtc/rtc-rv3029c2.c +2 -0
+	rv3029_trickle_config(client);
+
 	rtc =3D devm_rtc_device_register(&client->dev, client->name,
 				       &rv3029_rtc_ops, THIS_MODULE);
Quoted 4 lines

=20
--=20
2.7.0
=20

--=20
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

--=20
--=20
You received this message because you are subscribed to "rtc-linux". Membership options at http://groups.google.com/group/rtc-linux . Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---=20
You received this message because you are subscribed to the Google Groups "= rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to [email protected].
For more options, visit https://groups.google.com/d/optout.

#21 lore raw

[rtc-linux] Re: [PATCH 6/6] rtc-rv3029: Add device tree property for trickle charger

Quoted 13 lines · On Fri, 4 Mar 2016 20:43:37 +0100 Alexandre Belloni…
Quoted 12 lines · Michael Büsch
drivers/rtc/rtc-rv3029c2.c +12 -0
+	err = of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms);
+	if (err) {
+		/* Disable trickle charger. */
+		eectrl &= ~RV3029_TRICKLE_MASK;
+	} else {
+		/* Enable trickle charger. */
+		for (i = 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++) {
+			elem = &rv3029_trickle_tab[i];
+			if (elem->r >= ohms)
+				break;
+		}
+		eectrl &= ~RV3029_TRICKLE_MASK;
Quoted 8 lines

drivers/rtc/rtc-rv3029c2.c static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm) · line 619

Quoted 5 lines
drivers/rtc/rtc-rv3029c2.c +5 -0
+		eectrl |= elem->conf;
+		dev_info(&client->dev,
+			 "Trickle charger enabled at %d ohms resistance.\n",
+			 elem->r);
+	}  

Now the you have an update_bits functions, you probably want to use it here. This simplifies the function.

No. This operates on the eeprom. The update_bits function operates on bare registers.
If we have more mask/set operations on the eeprom later, we can add an update_bits function for the eeprom, too.

Signature · 12 lines
Michael

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#22 lore raw

[rtc-linux] Re: [PATCH 6/6] rtc-rv3029: Add device tree property for trickle charger

Quoted 5 lines · On 04/03/2016 at 20:49:54 +0100, Michael B=C3=BCsch wrote :

On Fri, 4 Mar 2016 20:43:37 +0100
Alexandre Belloni <[email protected]> wrote:
=20

Quoted 2 lines · On 04/03/2016 at 19:56:54 +0100, Michael B=C3=BCsch wrote :

Review

Quoted 1 line
(quoted diff) +1 -0
+	err =3D of_property_read_u32(of_node, "trickle-resistor-ohms", &ohm=

s);

Quoted 19 lines
Quoted 11 lines
Quoted 11 lines
drivers/rtc/rtc-rv3029c2.c +11 -0
+	if (err) {
+		/* Disable trickle charger. */
+		eectrl &=3D ~RV3029_TRICKLE_MASK;
+	} else {
+		/* Enable trickle charger. */
+		for (i =3D 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++) {
+			elem =3D &rv3029_trickle_tab[i];
+			if (elem->r >=3D ohms)
+				break;
+		}
+		eectrl &=3D ~RV3029_TRICKLE_MASK;
Quoted 8 lines

drivers/rtc/rtc-rv3029c2.c static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)

Quoted 5 lines
drivers/rtc/rtc-rv3029c2.c +5 -0
+		eectrl |=3D elem->conf;
+		dev_info(&client->dev,
+			 "Trickle charger enabled at %d ohms resistance.\n",
+			 elem->r);
+	} =20

=20
Now the you have an update_bits functions, you probably want to use it here. This simplifies the function.

Quoted 7 lines

=20
=20
No. This operates on the eeprom. The update_bits function operates on bare registers.
If we have more mask/set operations on the eeprom later, we can add an update_bits function for the eeprom, too.
=20

Indeed, I read too fast

Quoted 2 lines

--=20
Michael

--=20
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

--=20
--=20
You received this message because you are subscribed to "rtc-linux". Membership options at http://groups.google.com/group/rtc-linux . Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---=20
You received this message because you are subscribed to the Google Groups "= rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to [email protected].
For more options, visit https://groups.google.com/d/optout.

#23 lore raw

PATCH v3 6/6 rtc-rv3029: Add device tree property for trickle charger

In reply to Michael Büsch

The trickle charger resistor can be enabled via device tree property trickle-resistor-ohms.

---
 drivers/rtc/rtc-rv3029c2.c | 106 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 103 insertions(+), 3 deletions(-)
drivers/rtc/rtc-rv3029c2.c +103 -3
index e59b8a5..b416ed0 100644
@@ -10,9 +10,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * NOTE: Currently this driver only supports the bare minimum for read
- * and write the RTC and alarms. The extra features provided by this chip
- * (trickle charger, eeprom, T° compensation) are unavailable.
  */
 
 #include <linux/module.h>
@@ -528,6 +525,107 @@ static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	return rv3029_i2c_set_time(to_i2c_client(dev), tm);
 }
 
+static const struct rv3029_trickle_tab_elem {
+	u32 r;		/* resistance in ohms */
+	u8 conf;	/* trickle config bits */
+} rv3029_trickle_tab[] = {
+	{
+		.r	= 1076,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
+			  RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
+	}, {
+		.r	= 1091,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
+			  RV3029_TRICKLE_20K,
+	}, {
+		.r	= 1137,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
+			  RV3029_TRICKLE_80K,
+	}, {
+		.r	= 1154,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_5K,
+	}, {
+		.r	= 1371,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_20K |
+			  RV3029_TRICKLE_80K,
+	}, {
+		.r	= 1395,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_20K,
+	}, {
+		.r	= 1472,
+		.conf	= RV3029_TRICKLE_1K | RV3029_TRICKLE_80K,
+	}, {
+		.r	= 1500,
+		.conf	= RV3029_TRICKLE_1K,
+	}, {
+		.r	= 3810,
+		.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_20K |
+			  RV3029_TRICKLE_80K,
+	}, {
+		.r	= 4000,
+		.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_20K,
+	}, {
+		.r	= 4706,
+		.conf	= RV3029_TRICKLE_5K | RV3029_TRICKLE_80K,
+	}, {
+		.r	= 5000,
+		.conf	= RV3029_TRICKLE_5K,
+	}, {
+		.r	= 16000,
+		.conf	= RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
+	}, {
+		.r	= 20000,
+		.conf	= RV3029_TRICKLE_20K,
+	}, {
+		.r	= 80000,
+		.conf	= RV3029_TRICKLE_80K,
+	},
+};
+
+static void rv3029_trickle_config(struct i2c_client *client)
+{
+	struct device_node *of_node = client->dev.of_node;
+	const struct rv3029_trickle_tab_elem *elem;
+	int i, err;
+	u32 ohms;
+	u8 eectrl;
+
+	if (!of_node)
+		return;
+
+	/* Configure the trickle charger. */
+	err = rv3029_eeprom_read(client, RV3029_CONTROL_E2P_EECTRL,
+				 &eectrl, 1);
+	if (err < 0) {
+		dev_err(&client->dev,
+			"Failed to read trickle charger config\n");
+		return;
+	}
+	err = of_property_read_u32(of_node, "trickle-resistor-ohms", &ohms);
+	if (err) {
+		/* Disable trickle charger. */
+		eectrl &= ~RV3029_TRICKLE_MASK;
+	} else {
+		/* Enable trickle charger. */
+		for (i = 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++) {
+			elem = &rv3029_trickle_tab[i];
+			if (elem->r >= ohms)
+				break;
+		}
+		eectrl &= ~RV3029_TRICKLE_MASK;
+		eectrl |= elem->conf;
+		dev_info(&client->dev,
+			 "Trickle charger enabled at %d ohms resistance.\n",
+			 elem->r);
+	}
+	err = rv3029_eeprom_write(client, RV3029_CONTROL_E2P_EECTRL,
+				  &eectrl, 1);
+	if (err < 0) {
+		dev_err(&client->dev,
+			"Failed to write trickle charger config\n");
+	}
+}
+
 static const struct rtc_class_ops rv3029_rtc_ops = {
 	.read_time	= rv3029_rtc_read_time,
 	.set_time	= rv3029_rtc_set_time,
@@ -558,6 +656,8 @@ static int rv3029_probe(struct i2c_client *client,
 		return rc;
 	}
 
+	rv3029_trickle_config(client);
+
 	rtc = devm_rtc_device_register(&client->dev, client->name,
 				       &rv3029_rtc_ops, THIS_MODULE);
 
Signature · 12 lines
2.7.0

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#24 lore raw

cover rtc-rv3029: Add trickle charger

In reply to Alexandre Belloni

This series eventually adds support for the trickle charger mechanism to the MicroCrystal rv3029 RTC driver.

This series includes the changes from the first review round. The tricke charger functionality was verified on a rv3029 connected to a RaspberryPi. The resistance between VCC and the battery pin was measured for some 'trickle-resistor-ohms' settings.

The series is also available in this git repository:

git://git.bues.ch/linux.git rv3029

Signature · 12 lines
Michael

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#25 lore raw

[rtc-linux] Re: [PATCH 0/6] rtc-rv3029: Add trickle charger

Quoted 10 lines · On 04/03/2016 at 20:02:56 +0100, Michael B=C3=BCsch wrote :

This series eventually adds support for the trickle charger mechanism to the MicroCrystal rv3029 RTC driver.
=20
This series includes the changes from the first review round. The tricke charger functionality was verified on a rv3029 connected to a RaspberryPi. The resistance between VCC and the battery pin was measured for some 'trickle-resistor-ohms' settings.
=20
The series is also available in this git repository:
=20

This is mostly good. I still have two small comments.

--=20
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

--=20
--=20
You received this message because you are subscribed to "rtc-linux". Membership options at http://groups.google.com/group/rtc-linux . Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---=20
You received this message because you are subscribed to the Google Groups "= rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to [email protected].
For more options, visit https://groups.google.com/d/optout.

#26 lore raw

v3 cover rtc-rv3029: Add trickle charger

In reply to Michael Büsch

This series eventually adds support for the trickle charger mechanism to the MicroCrystal rv3029 RTC driver.

This series includes the changes from the first and second review round.

The tricke charger functionality was verified on a rv3029 connected to a RaspberryPi. The resistance between VCC and the battery pin was measured for some 'trickle-resistor-ohms' settings.

The series is also available in this git repository:

git://git.bues.ch/linux.git rv3029

Signature · 12 lines
Michael

-- 
-- 
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
--- 
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
#27 lore raw

[rtc-linux] Re: [PATCH v3 0/6] rtc-rv3029: Add trickle charger

Quoted 5 lines · On 04/03/2016 at 22:36:54 +0100, Michael B=C3=BCsch wrote :

This series eventually adds support for the trickle charger mechanism to the MicroCrystal rv3029 RTC driver.
=20
This series includes the changes from the first and second review round. =20

Quoted 8 lines

The tricke charger functionality was verified on a rv3029 connected to a RaspberryPi. The resistance between VCC and the battery pin was measured for some 'trickle-resistor-ohms' settings.
=20
The series is also available in this git repository:
=20
git://git.bues.ch/linux.git rv3029
=20

All applied, thanks!

--=20
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

--=20
--=20
You received this message because you are subscribed to "rtc-linux". Membership options at http://groups.google.com/group/rtc-linux . Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---=20
You received this message because you are subscribed to the Google Groups "= rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to [email protected].
For more options, visit https://groups.google.com/d/optout.