All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] add support for Microcrystal RV-3049
@ 2016-04-21 18:24 ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

The current patchset adds the support of the microcrystal RV-3049 (spi).
This RTC will use the same driver than RV-3029 by updating it to use regmap.
It also adds the alarm IRQ functionality.


Mylène Josserand (6):
  rtc: rv3029: remove 'i2c' in functions names
  rtc: rv3029: convert to use regmap
  rtc: rv3029: Add support of RV3049
  rtc: rv3049: Removes some checks and warnings
  rtc: rv3029: enable AE_x bits on set_alarm
  rtc: rv3029: add alarm IRQ

 drivers/rtc/Kconfig        |  37 +--
 drivers/rtc/rtc-rv3029c2.c | 582 +++++++++++++++++++++++++++++----------------
 2 files changed, 397 insertions(+), 222 deletions(-)

-- 
2.8.0.rc3

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH 0/6] add support for Microcrystal RV-3049
@ 2016-04-21 18:24 ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

The current patchset adds the support of the microcrystal RV-3049 (spi).
This RTC will use the same driver than RV-3029 by updating it to use regmap=
.
It also adds the alarm IRQ functionality.


Myl=C3=A8ne Josserand (6):
  rtc: rv3029: remove 'i2c' in functions names
  rtc: rv3029: convert to use regmap
  rtc: rv3029: Add support of RV3049
  rtc: rv3049: Removes some checks and warnings
  rtc: rv3029: enable AE_x bits on set_alarm
  rtc: rv3029: add alarm IRQ

 drivers/rtc/Kconfig        |  37 +--
 drivers/rtc/rtc-rv3029c2.c | 582 +++++++++++++++++++++++++++++------------=
----
 2 files changed, 397 insertions(+), 222 deletions(-)

--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 1/6] rtc: rv3029: remove 'i2c' in functions names
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-21 18:24   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

To prepare the use of regmap to add the support of RV-3049, all the
'i2c' in functions's names are removed.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 132 ++++++++++++++++++++-------------------------
 1 file changed, 57 insertions(+), 75 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index d0cbf08..091be48 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -116,9 +116,8 @@
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_SECTION_LEN		0x04
 
-static int
-rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
-		     unsigned len)
+static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+			    unsigned len)
 {
 	int ret;
 
@@ -134,9 +133,8 @@ rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
 	return 0;
 }
 
-static int
-rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
-		      unsigned len)
+static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
+			     unsigned len)
 {
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 		(reg + len > RV3029_USR1_RAM_PAGE + 8))
@@ -145,28 +143,27 @@ rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
 	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
 }
 
-static int
-rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set)
+static int rv3029_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);
+	ret = rv3029_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);
+	ret = rv3029_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)
+static int rv3029_get_sr(struct i2c_client *client, u8 *buf)
 {
-	int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
+	int ret = rv3029_read_regs(client, RV3029_STATUS, buf, 1);
 
 	if (ret < 0)
 		return -EIO;
@@ -174,14 +171,13 @@ rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
 	return 0;
 }
 
-static int
-rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
+static int rv3029_set_sr(struct i2c_client *client, u8 val)
 {
 	u8 buf[1];
 	int sr;
 
 	buf[0] = val;
-	sr = rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1);
+	sr = rv3029_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;
@@ -194,7 +190,7 @@ static int rv3029_eeprom_busywait(struct i2c_client *client)
 	u8 sr;
 
 	for (i = 100; i > 0; i--) {
-		ret = rv3029_i2c_get_sr(client, &sr);
+		ret = rv3029_get_sr(client, &sr);
 		if (ret < 0)
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -212,9 +208,9 @@ static int rv3029_eeprom_busywait(struct i2c_client *client)
 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);
+	return rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+				  RV3029_ONOFF_CTRL_EERE,
+				  RV3029_ONOFF_CTRL_EERE);
 }
 
 static int rv3029_eeprom_enter(struct i2c_client *client)
@@ -223,7 +219,7 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
 	u8 sr;
 
 	/* Check whether we are in the allowed voltage range. */
-	ret = rv3029_i2c_get_sr(client, &sr);
+	ret = rv3029_get_sr(client, &sr);
 	if (ret < 0)
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -232,11 +228,11 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
 		 */
 		sr &= ~RV3029_STATUS_VLOW1;
 		sr &= ~RV3029_STATUS_VLOW2;
-		ret = rv3029_i2c_set_sr(client, sr);
+		ret = rv3029_set_sr(client, sr);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
-		ret = rv3029_i2c_get_sr(client, &sr);
+		ret = rv3029_get_sr(client, &sr);
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -247,8 +243,8 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
 	}
 
 	/* Disable eeprom refresh. */
-	ret = rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
-				     RV3029_ONOFF_CTRL_EERE, 0);
+	ret = rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+				 RV3029_ONOFF_CTRL_EERE, 0);
 	if (ret < 0)
 		return ret;
 
@@ -269,7 +265,7 @@ static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
 	if (err < 0)
 		return err;
 
-	ret = rv3029_i2c_read_regs(client, reg, buf, len);
+	ret = rv3029_read_regs(client, reg, buf, len);
 
 	err = rv3029_eeprom_exit(client);
 	if (err < 0)
@@ -290,11 +286,11 @@ static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
 		return err;
 
 	for (i = 0; i < len; i++, reg++) {
-		ret = rv3029_i2c_read_regs(client, reg, &tmp, 1);
+		ret = rv3029_read_regs(client, reg, &tmp, 1);
 		if (ret < 0)
 			break;
 		if (tmp != buf[i]) {
-			ret = rv3029_i2c_write_regs(client, reg, &buf[i], 1);
+			ret = rv3029_write_regs(client, reg, &buf[i], 1);
 			if (ret < 0)
 				break;
 		}
@@ -328,21 +324,20 @@ static int rv3029_eeprom_update_bits(struct i2c_client *client,
 	return 0;
 }
 
-static int
-rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm)
 {
 	u8 buf[1];
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
-	ret = rv3029_i2c_get_sr(client, buf);
+	ret = rv3029_get_sr(client, buf);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029_i2c_read_regs(client, RV3029_W_SEC, regs,
-				   RV3029_WATCH_SECTION_LEN);
+	ret = rv3029_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__);
@@ -375,24 +370,24 @@ rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 
 static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029_i2c_read_time(to_i2c_client(dev), tm);
+	return rv3029_read_time(to_i2c_client(dev), tm);
 }
 
-static int
-rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
+static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
 
-	ret = rv3029_i2c_get_sr(client, regs);
+	ret = rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029_i2c_read_regs(client, RV3029_A_SC, regs,
-				   RV3029_ALARM_SECTION_LEN);
+	ret = rv3029_read_regs(client, RV3029_A_SC, regs,
+			       RV3029_ALARM_SECTION_LEN);
 
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading alarm section failed\n",
@@ -411,21 +406,14 @@ rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
 	return 0;
 }
 
-static int
-rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-	return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm);
-}
-
-static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
-					int enable)
+static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable)
 {
 	int ret;
 
 	/* enable/disable AIE irq */
-	ret = rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
-				     RV3029_IRQ_CTRL_AIE,
-				     (enable ? RV3029_IRQ_CTRL_AIE : 0));
+	ret = rv3029_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 update INT reg\n");
 		return ret;
@@ -434,9 +422,9 @@ static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
 	return 0;
 }
 
-static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
-				    struct rtc_wkalrm *alarm)
+static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
@@ -449,7 +437,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	ret = rv3029_i2c_get_sr(client, regs);
+	ret = rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
@@ -462,28 +450,28 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
 	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);
+	ret = rv3029_write_regs(client, RV3029_A_SC, regs,
+				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
 	if (alarm->enabled) {
 		/* clear AF flag */
-		ret = rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
-					     RV3029_IRQ_FLAGS_AF, 0);
+		ret = rv3029_update_bits(client, RV3029_IRQ_FLAGS,
+					 RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
 			dev_err(&client->dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret = rv3029_rtc_i2c_alarm_set_irq(client, 1);
+		ret = rv3029_rtc_alarm_set_irq(client, 1);
 		if (ret)
 			return ret;
 
 		dev_dbg(&client->dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret = rv3029_rtc_i2c_alarm_set_irq(client, 0);
+		ret = rv3029_rtc_alarm_set_irq(client, 0);
 		if (ret)
 			return ret;
 
@@ -493,13 +481,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
 	return 0;
 }
 
-static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-	return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
-}
-
-static int
-rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
+static int rv3029_set_time(struct i2c_client *client, struct rtc_time const *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -520,18 +502,18 @@ rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 	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 = rv3029_i2c_write_regs(client, RV3029_W_SEC, regs,
-				    RV3029_WATCH_SECTION_LEN);
+	ret = rv3029_write_regs(client, RV3029_W_SEC, regs,
+				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
-	ret = rv3029_i2c_get_sr(client, regs);
+	ret = rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret = rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
+	ret = rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
@@ -542,7 +524,7 @@ rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 
 static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029_i2c_set_time(to_i2c_client(dev), tm);
+	return rv3029_set_time(to_i2c_client(dev), tm);
 }
 
 static const struct rv3029_trickle_tab_elem {
@@ -646,7 +628,7 @@ static int rv3029_read_temp(struct i2c_client *client, int *temp_mC)
 	int ret;
 	u8 temp;
 
-	ret = rv3029_i2c_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
+	ret = rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
 	if (ret < 0)
 		return ret;
 
@@ -743,8 +725,8 @@ static void rv3029_hwmon_register(struct i2c_client *client)
 		&client->dev, client->name, client, rv3029_hwmon_groups);
 	if (IS_ERR(hwmon_dev)) {
 		dev_warn(&client->dev,
-			"unable to register hwmon device %ld\n",
-			PTR_ERR(hwmon_dev));
+			 "unable to register hwmon device %ld\n",
+			 PTR_ERR(hwmon_dev));
 	}
 }
 
@@ -780,7 +762,7 @@ static int rv3029_probe(struct i2c_client *client,
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
 		return -ENODEV;
 
-	rc = rv3029_i2c_get_sr(client, buf);
+	rc = rv3029_get_sr(client, buf);
 	if (rc < 0) {
 		dev_err(&client->dev, "reading status failed\n");
 		return rc;
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH 1/6] rtc: rv3029: remove 'i2c' in functions names
@ 2016-04-21 18:24   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

To prepare the use of regmap to add the support of RV-3049, all the
'i2c' in functions's names are removed.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 132 ++++++++++++++++++++---------------------=
----
 1 file changed, 57 insertions(+), 75 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index d0cbf08..091be48 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -116,9 +116,8 @@
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_SECTION_LEN		0x04
=20
-static int
-rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
-		     unsigned len)
+static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+			    unsigned len)
 {
 	int ret;
=20
@@ -134,9 +133,8 @@ rv3029_i2c_read_regs(struct i2c_client *client, u8 reg,=
 u8 *buf,
 	return 0;
 }
=20
-static int
-rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
-		      unsigned len)
+static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const b=
uf[],
+			     unsigned len)
 {
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 		(reg + len > RV3029_USR1_RAM_PAGE + 8))
@@ -145,28 +143,27 @@ rv3029_i2c_write_regs(struct i2c_client *client, u8 r=
eg, u8 const buf[],
 	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
 }
=20
-static int
-rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set)
+static int rv3029_update_bits(struct i2c_client *client, u8 reg, u8 mask,
+			      u8 set)
 {
 	u8 buf;
 	int ret;
=20
-	ret =3D rv3029_i2c_read_regs(client, reg, &buf, 1);
+	ret =3D rv3029_read_regs(client, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &=3D ~mask;
 	buf |=3D set & mask;
-	ret =3D rv3029_i2c_write_regs(client, reg, &buf, 1);
+	ret =3D rv3029_write_regs(client, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
=20
 	return 0;
 }
=20
-static int
-rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
+static int rv3029_get_sr(struct i2c_client *client, u8 *buf)
 {
-	int ret =3D rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
+	int ret =3D rv3029_read_regs(client, RV3029_STATUS, buf, 1);
=20
 	if (ret < 0)
 		return -EIO;
@@ -174,14 +171,13 @@ rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
 	return 0;
 }
=20
-static int
-rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
+static int rv3029_set_sr(struct i2c_client *client, u8 val)
 {
 	u8 buf[1];
 	int sr;
=20
 	buf[0] =3D val;
-	sr =3D rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1);
+	sr =3D rv3029_write_regs(client, RV3029_STATUS, buf, 1);
 	dev_dbg(&client->dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
 	if (sr < 0)
 		return -EIO;
@@ -194,7 +190,7 @@ static int rv3029_eeprom_busywait(struct i2c_client *cl=
ient)
 	u8 sr;
=20
 	for (i =3D 100; i > 0; i--) {
-		ret =3D rv3029_i2c_get_sr(client, &sr);
+		ret =3D rv3029_get_sr(client, &sr);
 		if (ret < 0)
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -212,9 +208,9 @@ static int rv3029_eeprom_busywait(struct i2c_client *cl=
ient)
 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);
+	return rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+				  RV3029_ONOFF_CTRL_EERE,
+				  RV3029_ONOFF_CTRL_EERE);
 }
=20
 static int rv3029_eeprom_enter(struct i2c_client *client)
@@ -223,7 +219,7 @@ static int rv3029_eeprom_enter(struct i2c_client *clien=
t)
 	u8 sr;
=20
 	/* Check whether we are in the allowed voltage range. */
-	ret =3D rv3029_i2c_get_sr(client, &sr);
+	ret =3D rv3029_get_sr(client, &sr);
 	if (ret < 0)
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -232,11 +228,11 @@ static int rv3029_eeprom_enter(struct i2c_client *cli=
ent)
 		 */
 		sr &=3D ~RV3029_STATUS_VLOW1;
 		sr &=3D ~RV3029_STATUS_VLOW2;
-		ret =3D rv3029_i2c_set_sr(client, sr);
+		ret =3D rv3029_set_sr(client, sr);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
-		ret =3D rv3029_i2c_get_sr(client, &sr);
+		ret =3D rv3029_get_sr(client, &sr);
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -247,8 +243,8 @@ static int rv3029_eeprom_enter(struct i2c_client *clien=
t)
 	}
=20
 	/* Disable eeprom refresh. */
-	ret =3D rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
-				     RV3029_ONOFF_CTRL_EERE, 0);
+	ret =3D rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+				 RV3029_ONOFF_CTRL_EERE, 0);
 	if (ret < 0)
 		return ret;
=20
@@ -269,7 +265,7 @@ static int rv3029_eeprom_read(struct i2c_client *client=
, u8 reg,
 	if (err < 0)
 		return err;
=20
-	ret =3D rv3029_i2c_read_regs(client, reg, buf, len);
+	ret =3D rv3029_read_regs(client, reg, buf, len);
=20
 	err =3D rv3029_eeprom_exit(client);
 	if (err < 0)
@@ -290,11 +286,11 @@ static int rv3029_eeprom_write(struct i2c_client *cli=
ent, u8 reg,
 		return err;
=20
 	for (i =3D 0; i < len; i++, reg++) {
-		ret =3D rv3029_i2c_read_regs(client, reg, &tmp, 1);
+		ret =3D rv3029_read_regs(client, reg, &tmp, 1);
 		if (ret < 0)
 			break;
 		if (tmp !=3D buf[i]) {
-			ret =3D rv3029_i2c_write_regs(client, reg, &buf[i], 1);
+			ret =3D rv3029_write_regs(client, reg, &buf[i], 1);
 			if (ret < 0)
 				break;
 		}
@@ -328,21 +324,20 @@ static int rv3029_eeprom_update_bits(struct i2c_clien=
t *client,
 	return 0;
 }
=20
-static int
-rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm=
)
 {
 	u8 buf[1];
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] =3D { 0, };
=20
-	ret =3D rv3029_i2c_get_sr(client, buf);
+	ret =3D rv3029_get_sr(client, buf);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
=20
-	ret =3D rv3029_i2c_read_regs(client, RV3029_W_SEC, regs,
-				   RV3029_WATCH_SECTION_LEN);
+	ret =3D rv3029_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__);
@@ -375,24 +370,24 @@ rv3029_i2c_read_time(struct i2c_client *client, struc=
t rtc_time *tm)
=20
 static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029_i2c_read_time(to_i2c_client(dev), tm);
+	return rv3029_read_time(to_i2c_client(dev), tm);
 }
=20
-static int
-rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
+static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *al=
arm)
 {
+	struct i2c_client *client =3D to_i2c_client(dev);
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
 	u8 regs[8];
=20
-	ret =3D rv3029_i2c_get_sr(client, regs);
+	ret =3D rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
=20
-	ret =3D rv3029_i2c_read_regs(client, RV3029_A_SC, regs,
-				   RV3029_ALARM_SECTION_LEN);
+	ret =3D rv3029_read_regs(client, RV3029_A_SC, regs,
+			       RV3029_ALARM_SECTION_LEN);
=20
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading alarm section failed\n",
@@ -411,21 +406,14 @@ rv3029_i2c_read_alarm(struct i2c_client *client, stru=
ct rtc_wkalrm *alarm)
 	return 0;
 }
=20
-static int
-rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-	return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm);
-}
-
-static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
-					int enable)
+static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable)
 {
 	int ret;
=20
 	/* enable/disable AIE irq */
-	ret =3D rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
-				     RV3029_IRQ_CTRL_AIE,
-				     (enable ? RV3029_IRQ_CTRL_AIE : 0));
+	ret =3D rv3029_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 update INT reg\n");
 		return ret;
@@ -434,9 +422,9 @@ static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_clie=
nt *client,
 	return 0;
 }
=20
-static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
-				    struct rtc_wkalrm *alarm)
+static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *ala=
rm)
 {
+	struct i2c_client *client =3D to_i2c_client(dev);
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
 	u8 regs[8];
@@ -449,7 +437,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *=
client,
 	if (tm->tm_year < 100)
 		return -EINVAL;
=20
-	ret =3D rv3029_i2c_get_sr(client, regs);
+	ret =3D rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
@@ -462,28 +450,28 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client=
 *client,
 	regs[RV3029_A_DW-RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
 	regs[RV3029_A_YR-RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
=20
-	ret =3D rv3029_i2c_write_regs(client, RV3029_A_SC, regs,
-				    RV3029_ALARM_SECTION_LEN);
+	ret =3D rv3029_write_regs(client, RV3029_A_SC, regs,
+				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
=20
 	if (alarm->enabled) {
 		/* clear AF flag */
-		ret =3D rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
-					     RV3029_IRQ_FLAGS_AF, 0);
+		ret =3D rv3029_update_bits(client, RV3029_IRQ_FLAGS,
+					 RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
 			dev_err(&client->dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret =3D rv3029_rtc_i2c_alarm_set_irq(client, 1);
+		ret =3D rv3029_rtc_alarm_set_irq(client, 1);
 		if (ret)
 			return ret;
=20
 		dev_dbg(&client->dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret =3D rv3029_rtc_i2c_alarm_set_irq(client, 0);
+		ret =3D rv3029_rtc_alarm_set_irq(client, 0);
 		if (ret)
 			return ret;
=20
@@ -493,13 +481,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client =
*client,
 	return 0;
 }
=20
-static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *ala=
rm)
-{
-	return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
-}
-
-static int
-rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
+static int rv3029_set_time(struct i2c_client *client, struct rtc_time cons=
t *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -520,18 +502,18 @@ rv3029_i2c_set_time(struct i2c_client *client, struct=
 rtc_time const *tm)
 	regs[RV3029_W_DAYS-RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7)+1);
 	regs[RV3029_W_YEARS-RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
=20
-	ret =3D rv3029_i2c_write_regs(client, RV3029_W_SEC, regs,
-				    RV3029_WATCH_SECTION_LEN);
+	ret =3D rv3029_write_regs(client, RV3029_W_SEC, regs,
+				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
=20
-	ret =3D rv3029_i2c_get_sr(client, regs);
+	ret =3D rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret =3D rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
+	ret =3D rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
@@ -542,7 +524,7 @@ rv3029_i2c_set_time(struct i2c_client *client, struct r=
tc_time const *tm)
=20
 static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029_i2c_set_time(to_i2c_client(dev), tm);
+	return rv3029_set_time(to_i2c_client(dev), tm);
 }
=20
 static const struct rv3029_trickle_tab_elem {
@@ -646,7 +628,7 @@ static int rv3029_read_temp(struct i2c_client *client, =
int *temp_mC)
 	int ret;
 	u8 temp;
=20
-	ret =3D rv3029_i2c_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
+	ret =3D rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
 	if (ret < 0)
 		return ret;
=20
@@ -743,8 +725,8 @@ static void rv3029_hwmon_register(struct i2c_client *cl=
ient)
 		&client->dev, client->name, client, rv3029_hwmon_groups);
 	if (IS_ERR(hwmon_dev)) {
 		dev_warn(&client->dev,
-			"unable to register hwmon device %ld\n",
-			PTR_ERR(hwmon_dev));
+			 "unable to register hwmon device %ld\n",
+			 PTR_ERR(hwmon_dev));
 	}
 }
=20
@@ -780,7 +762,7 @@ static int rv3029_probe(struct i2c_client *client,
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
 		return -ENODEV;
=20
-	rc =3D rv3029_i2c_get_sr(client, buf);
+	rc =3D rv3029_get_sr(client, buf);
 	if (rc < 0) {
 		dev_err(&client->dev, "reading status failed\n");
 		return rc;
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 2/6] rtc: rv3029: convert to use regmap
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-21 18:24   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

To add support of rv3049, the current driver is converted to use regmap.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 275 +++++++++++++++++++++++----------------------
 1 file changed, 142 insertions(+), 133 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 091be48..96dd166 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -20,7 +20,7 @@
 #include <linux/of.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-
+#include <linux/regmap.h>
 
 /* Register map */
 /* control section */
@@ -116,81 +116,84 @@
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_SECTION_LEN		0x04
 
-static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+struct rv3029_data {
+	struct device		*dev;
+	struct rtc_device	*rtc;
+	struct regmap		*regmap;
+	int irq;
+};
+
+static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
 			    unsigned len)
 {
-	int ret;
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
 	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);
-	if (ret < 0)
-		return ret;
-	if (ret < len)
-		return -EIO;
-	return 0;
+	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
 }
 
-static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
+static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
 			     unsigned len)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+
 	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);
+	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
 }
 
-static int rv3029_update_bits(struct i2c_client *client, u8 reg, u8 mask,
-			      u8 set)
+static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
 {
 	u8 buf;
 	int ret;
 
-	ret = rv3029_read_regs(client, reg, &buf, 1);
+	ret = rv3029_read_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &= ~mask;
 	buf |= set & mask;
-	ret = rv3029_write_regs(client, reg, &buf, 1);
+	ret = rv3029_write_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 
 	return 0;
 }
 
-static int rv3029_get_sr(struct i2c_client *client, u8 *buf)
+static int rv3029_get_sr(struct device *dev, u8 *buf)
 {
-	int ret = rv3029_read_regs(client, RV3029_STATUS, buf, 1);
+	int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
 
 	if (ret < 0)
 		return -EIO;
-	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
+	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
 	return 0;
 }
 
-static int rv3029_set_sr(struct i2c_client *client, u8 val)
+static int rv3029_set_sr(struct device *dev, u8 val)
 {
 	u8 buf[1];
 	int sr;
 
 	buf[0] = val;
-	sr = rv3029_write_regs(client, RV3029_STATUS, buf, 1);
-	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
+	sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
+	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
 	if (sr < 0)
 		return -EIO;
 	return 0;
 }
 
-static int rv3029_eeprom_busywait(struct i2c_client *client)
+static int rv3029_eeprom_busywait(struct device *dev)
 {
 	int i, ret;
 	u8 sr;
 
 	for (i = 100; i > 0; i--) {
-		ret = rv3029_get_sr(client, &sr);
+		ret = rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -198,28 +201,28 @@ static int rv3029_eeprom_busywait(struct i2c_client *client)
 		usleep_range(1000, 10000);
 	}
 	if (i <= 0) {
-		dev_err(&client->dev, "EEPROM busy wait timeout.\n");
+		dev_err(dev, "EEPROM busy wait timeout.\n");
 		return -ETIMEDOUT;
 	}
 
 	return ret;
 }
 
-static int rv3029_eeprom_exit(struct i2c_client *client)
+static int rv3029_eeprom_exit(struct device *dev)
 {
 	/* Re-enable eeprom refresh */
-	return rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+	return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
 				  RV3029_ONOFF_CTRL_EERE,
 				  RV3029_ONOFF_CTRL_EERE);
 }
 
-static int rv3029_eeprom_enter(struct i2c_client *client)
+static int rv3029_eeprom_enter(struct device *dev)
 {
 	int ret;
 	u8 sr;
 
 	/* Check whether we are in the allowed voltage range. */
-	ret = rv3029_get_sr(client, &sr);
+	ret = rv3029_get_sr(dev, &sr);
 	if (ret < 0)
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -228,119 +231,118 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
 		 */
 		sr &= ~RV3029_STATUS_VLOW1;
 		sr &= ~RV3029_STATUS_VLOW2;
-		ret = rv3029_set_sr(client, sr);
+		ret = rv3029_set_sr(dev, sr);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
-		ret = rv3029_get_sr(client, &sr);
+		ret = rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
-			dev_err(&client->dev,
+			dev_err(dev,
 				"Supply voltage is too low to safely access the EEPROM.\n");
 			return -ENODEV;
 		}
 	}
 
 	/* Disable eeprom refresh. */
-	ret = rv3029_update_bits(client, RV3029_ONOFF_CTRL,
-				 RV3029_ONOFF_CTRL_EERE, 0);
+	ret = rv3029_update_bits(dev, 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);
+	ret = rv3029_eeprom_busywait(dev);
 	if (ret < 0)
-		rv3029_eeprom_exit(client);
+		rv3029_eeprom_exit(dev);
 
 	return ret;
 }
 
-static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_read(struct device *dev, u8 reg,
 			      u8 buf[], size_t len)
 {
 	int ret, err;
 
-	err = rv3029_eeprom_enter(client);
+	err = rv3029_eeprom_enter(dev);
 	if (err < 0)
 		return err;
 
-	ret = rv3029_read_regs(client, reg, buf, len);
+	ret = rv3029_read_regs(dev, reg, buf, len);
 
-	err = rv3029_eeprom_exit(client);
+	err = rv3029_eeprom_exit(dev);
 	if (err < 0)
 		return err;
 
 	return ret;
 }
 
-static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_write(struct device *dev, u8 reg,
 			       u8 const buf[], size_t len)
 {
 	int ret, err;
 	size_t i;
 	u8 tmp;
 
-	err = rv3029_eeprom_enter(client);
+	err = rv3029_eeprom_enter(dev);
 	if (err < 0)
 		return err;
 
 	for (i = 0; i < len; i++, reg++) {
-		ret = rv3029_read_regs(client, reg, &tmp, 1);
+		ret = rv3029_read_regs(dev, reg, &tmp, 1);
 		if (ret < 0)
 			break;
 		if (tmp != buf[i]) {
-			ret = rv3029_write_regs(client, reg, &buf[i], 1);
+			ret = rv3029_write_regs(dev, reg, &buf[i], 1);
 			if (ret < 0)
 				break;
 		}
-		ret = rv3029_eeprom_busywait(client);
+		ret = rv3029_eeprom_busywait(dev);
 		if (ret < 0)
 			break;
 	}
 
-	err = rv3029_eeprom_exit(client);
+	err = rv3029_eeprom_exit(dev);
 	if (err < 0)
 		return err;
 
 	return ret;
 }
 
-static int rv3029_eeprom_update_bits(struct i2c_client *client,
+static int rv3029_eeprom_update_bits(struct device *dev,
 				     u8 reg, u8 mask, u8 set)
 {
 	u8 buf;
 	int ret;
 
-	ret = rv3029_eeprom_read(client, reg, &buf, 1);
+	ret = rv3029_eeprom_read(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &= ~mask;
 	buf |= set & mask;
-	ret = rv3029_eeprom_write(client, reg, &buf, 1);
+	ret = rv3029_eeprom_write(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 
 	return 0;
 }
 
-static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm)
+static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 buf[1];
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
-	ret = rv3029_get_sr(client, buf);
+	ret = rv3029_get_sr(dev, buf);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029_read_regs(client, RV3029_W_SEC, regs,
+	ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
 			       RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading RTC section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading RTC section failed\n", __func__);
 		return ret;
 	}
 
@@ -368,30 +370,23 @@ static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm)
 	return 0;
 }
 
-static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_read_time(to_i2c_client(dev), tm);
-}
-
-static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
 
-	ret = rv3029_get_sr(client, regs);
+	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029_read_regs(client, RV3029_A_SC, regs,
+	ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
 			       RV3029_ALARM_SECTION_LEN);
 
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading alarm section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading alarm section failed\n", __func__);
 		return ret;
 	}
 
@@ -406,25 +401,23 @@ static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	return 0;
 }
 
-static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable)
+static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable)
 {
 	int ret;
 
 	/* enable/disable AIE irq */
-	ret = rv3029_update_bits(client, RV3029_IRQ_CTRL,
-				 RV3029_IRQ_CTRL_AIE,
+	ret = rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE,
 				 (enable ? RV3029_IRQ_CTRL_AIE : 0));
 	if (ret < 0) {
-		dev_err(&client->dev, "can't update INT reg\n");
+		dev_err(dev, "can't update INT reg\n");
 		return ret;
 	}
 
 	return 0;
 }
 
-static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
@@ -437,9 +430,9 @@ static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	ret = rv3029_get_sr(client, regs);
+	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 	regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
@@ -450,38 +443,38 @@ static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	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_write_regs(client, RV3029_A_SC, regs,
+	ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
 	if (alarm->enabled) {
 		/* clear AF flag */
-		ret = rv3029_update_bits(client, RV3029_IRQ_FLAGS,
+		ret = rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
 					 RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
-			dev_err(&client->dev, "can't clear alarm flag\n");
+			dev_err(dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret = rv3029_rtc_alarm_set_irq(client, 1);
+		ret = rv3029_rtc_alarm_set_irq(dev, 1);
 		if (ret)
 			return ret;
 
-		dev_dbg(&client->dev, "alarm IRQ armed\n");
+		dev_dbg(dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret = rv3029_rtc_alarm_set_irq(client, 0);
+		ret = rv3029_rtc_alarm_set_irq(dev, 0);
 		if (ret)
 			return ret;
 
-		dev_dbg(&client->dev, "alarm IRQ disabled\n");
+		dev_dbg(dev, "alarm IRQ disabled\n");
 	}
 
 	return 0;
 }
 
-static int rv3029_set_time(struct i2c_client *client, struct rtc_time const *tm)
+static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -502,31 +495,25 @@ static int rv3029_set_time(struct i2c_client *client, struct rtc_time const *tm)
 	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 = rv3029_write_regs(client, RV3029_W_SEC, regs,
+	ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
 				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
-	ret = rv3029_get_sr(client, regs);
+	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret = rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
+	ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 
 	return 0;
 }
-
-static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_set_time(to_i2c_client(dev), tm);
-}
-
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -584,9 +571,9 @@ static const struct rv3029_trickle_tab_elem {
 	},
 };
 
-static void rv3029_trickle_config(struct i2c_client *client)
+static void rv3029_trickle_config(struct device *dev)
 {
-	struct device_node *of_node = client->dev.of_node;
+	struct device_node *of_node = dev->of_node;
 	const struct rv3029_trickle_tab_elem *elem;
 	int i, err;
 	u32 ohms;
@@ -608,27 +595,26 @@ static void rv3029_trickle_config(struct i2c_client *client)
 				break;
 		}
 		trickle_set_bits = elem->conf;
-		dev_info(&client->dev,
+		dev_info(dev,
 			 "Trickle charger enabled at %d ohms resistance.\n",
 			 elem->r);
 	}
-	err = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
 	if (err < 0) {
-		dev_err(&client->dev,
-			"Failed to update trickle charger config\n");
+		dev_err(dev, "Failed to update trickle charger config\n");
 	}
 }
 
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
 
-static int rv3029_read_temp(struct i2c_client *client, int *temp_mC)
+static int rv3029_read_temp(struct device *dev, int *temp_mC)
 {
 	int ret;
 	u8 temp;
 
-	ret = rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
+	ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
 	if (ret < 0)
 		return ret;
 
@@ -641,10 +627,9 @@ static ssize_t rv3029_hwmon_show_temp(struct device *dev,
 				      struct device_attribute *attr,
 				      char *buf)
 {
-	struct i2c_client *client = dev_get_drvdata(dev);
 	int ret, temp_mC;
 
-	ret = rv3029_read_temp(client, &temp_mC);
+	ret = rv3029_read_temp(dev, &temp_mC);
 	if (ret < 0)
 		return ret;
 
@@ -656,7 +641,6 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
 						const char *buf,
 						size_t count)
 {
-	struct i2c_client *client = dev_get_drvdata(dev);
 	unsigned long interval_ms;
 	int ret;
 	u8 th_set_bits = 0;
@@ -670,7 +654,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
 		if (interval_ms >= 16000)
 			th_set_bits |= RV3029_EECTRL_THP;
 	}
-	ret = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_EECTRL_THE | RV3029_EECTRL_THP,
 					th_set_bits);
 	if (ret < 0)
@@ -683,11 +667,10 @@ static ssize_t rv3029_hwmon_show_update_interval(struct device *dev,
 						 struct device_attribute *attr,
 						 char *buf)
 {
-	struct i2c_client *client = dev_get_drvdata(dev);
 	int ret, interval_ms;
 	u8 eectrl;
 
-	ret = rv3029_eeprom_read(client, RV3029_CONTROL_E2P_EECTRL,
+	ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
 				 &eectrl, 1);
 	if (ret < 0)
 		return ret;
@@ -717,32 +700,32 @@ static struct attribute *rv3029_hwmon_attrs[] = {
 };
 ATTRIBUTE_GROUPS(rv3029_hwmon);
 
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	struct device *hwmon_dev;
 
-	hwmon_dev = devm_hwmon_device_register_with_groups(
-		&client->dev, client->name, client, rv3029_hwmon_groups);
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, name, rv3029,
+							   rv3029_hwmon_groups);
 	if (IS_ERR(hwmon_dev)) {
-		dev_warn(&client->dev,
-			 "unable to register hwmon device %ld\n",
+		dev_warn(dev, "unable to register hwmon device %ld\n",
 			 PTR_ERR(hwmon_dev));
 	}
 }
 
 #else /* CONFIG_RTC_DRV_RV3029_HWMON */
 
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
 }
 
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
 
 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,
+	.read_time	= rv3029_read_time,
+	.set_time	= rv3029_set_time,
+	.read_alarm	= rv3029_read_alarm,
+	.set_alarm	= rv3029_set_alarm,
 };
 
 static struct i2c_device_id rv3029_id[] = {
@@ -752,41 +735,67 @@ static struct i2c_device_id rv3029_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, rv3029_id);
 
-static int rv3029_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
+			const char *name)
 {
-	struct rtc_device *rtc;
+	struct rv3029_data *rv3029;
 	int rc = 0;
 	u8 buf[1];
 
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
-		return -ENODEV;
+	rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
+	if (!rv3029)
+		return -ENOMEM;
+
+	rv3029->regmap = regmap;
+	rv3029->irq = irq;
+	rv3029->dev = dev;
+	dev_set_drvdata(dev, rv3029);
 
-	rc = rv3029_get_sr(client, buf);
+	rc = rv3029_get_sr(dev, buf);
 	if (rc < 0) {
-		dev_err(&client->dev, "reading status failed\n");
+		dev_err(dev, "reading status failed\n");
 		return rc;
 	}
 
-	rv3029_trickle_config(client);
-	rv3029_hwmon_register(client);
+	rv3029_trickle_config(dev);
+	rv3029_hwmon_register(dev, name);
+
+	rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
+					       THIS_MODULE);
 
-	rtc = devm_rtc_device_register(&client->dev, client->name,
-				       &rv3029_rtc_ops, THIS_MODULE);
+	return PTR_ERR_OR_ZERO(rv3029->rtc);
+}
 
-	if (IS_ERR(rtc))
-		return PTR_ERR(rtc);
+static int rv3029_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	static const struct regmap_config config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+	};
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
+				     I2C_FUNC_SMBUS_BYTE)) {
+		dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n");
+		return -ENODEV;
+	}
 
-	i2c_set_clientdata(client, rtc);
+	regmap = devm_regmap_init_i2c(client, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
 
-	return 0;
+	return rv3029_probe(&client->dev, regmap, client->irq, client->name);
 }
 
 static struct i2c_driver rv3029_driver = {
 	.driver = {
 		.name = "rtc-rv3029c2",
 	},
-	.probe		= rv3029_probe,
+	.probe		= rv3029_i2c_probe,
 	.id_table	= rv3029_id,
 };
 
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH 2/6] rtc: rv3029: convert to use regmap
@ 2016-04-21 18:24   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

To add support of rv3049, the current driver is converted to use regmap.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 275 +++++++++++++++++++++++------------------=
----
 1 file changed, 142 insertions(+), 133 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 091be48..96dd166 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -20,7 +20,7 @@
 #include <linux/of.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-
+#include <linux/regmap.h>
=20
 /* Register map */
 /* control section */
@@ -116,81 +116,84 @@
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_SECTION_LEN		0x04
=20
-static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+struct rv3029_data {
+	struct device		*dev;
+	struct rtc_device	*rtc;
+	struct regmap		*regmap;
+	int irq;
+};
+
+static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
 			    unsigned len)
 {
-	int ret;
+	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
=20
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 		(reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
=20
-	ret =3D i2c_smbus_read_i2c_block_data(client, reg, len, buf);
-	if (ret < 0)
-		return ret;
-	if (ret < len)
-		return -EIO;
-	return 0;
+	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
 }
=20
-static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const b=
uf[],
+static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
 			     unsigned len)
 {
+	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
+
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 		(reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
=20
-	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
+	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
 }
=20
-static int rv3029_update_bits(struct i2c_client *client, u8 reg, u8 mask,
-			      u8 set)
+static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
 {
 	u8 buf;
 	int ret;
=20
-	ret =3D rv3029_read_regs(client, reg, &buf, 1);
+	ret =3D rv3029_read_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &=3D ~mask;
 	buf |=3D set & mask;
-	ret =3D rv3029_write_regs(client, reg, &buf, 1);
+	ret =3D rv3029_write_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
=20
 	return 0;
 }
=20
-static int rv3029_get_sr(struct i2c_client *client, u8 *buf)
+static int rv3029_get_sr(struct device *dev, u8 *buf)
 {
-	int ret =3D rv3029_read_regs(client, RV3029_STATUS, buf, 1);
+	int ret =3D rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
=20
 	if (ret < 0)
 		return -EIO;
-	dev_dbg(&client->dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
+	dev_dbg(dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
 	return 0;
 }
=20
-static int rv3029_set_sr(struct i2c_client *client, u8 val)
+static int rv3029_set_sr(struct device *dev, u8 val)
 {
 	u8 buf[1];
 	int sr;
=20
 	buf[0] =3D val;
-	sr =3D rv3029_write_regs(client, RV3029_STATUS, buf, 1);
-	dev_dbg(&client->dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
+	sr =3D rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
+	dev_dbg(dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
 	if (sr < 0)
 		return -EIO;
 	return 0;
 }
=20
-static int rv3029_eeprom_busywait(struct i2c_client *client)
+static int rv3029_eeprom_busywait(struct device *dev)
 {
 	int i, ret;
 	u8 sr;
=20
 	for (i =3D 100; i > 0; i--) {
-		ret =3D rv3029_get_sr(client, &sr);
+		ret =3D rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -198,28 +201,28 @@ static int rv3029_eeprom_busywait(struct i2c_client *=
client)
 		usleep_range(1000, 10000);
 	}
 	if (i <=3D 0) {
-		dev_err(&client->dev, "EEPROM busy wait timeout.\n");
+		dev_err(dev, "EEPROM busy wait timeout.\n");
 		return -ETIMEDOUT;
 	}
=20
 	return ret;
 }
=20
-static int rv3029_eeprom_exit(struct i2c_client *client)
+static int rv3029_eeprom_exit(struct device *dev)
 {
 	/* Re-enable eeprom refresh */
-	return rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+	return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
 				  RV3029_ONOFF_CTRL_EERE,
 				  RV3029_ONOFF_CTRL_EERE);
 }
=20
-static int rv3029_eeprom_enter(struct i2c_client *client)
+static int rv3029_eeprom_enter(struct device *dev)
 {
 	int ret;
 	u8 sr;
=20
 	/* Check whether we are in the allowed voltage range. */
-	ret =3D rv3029_get_sr(client, &sr);
+	ret =3D rv3029_get_sr(dev, &sr);
 	if (ret < 0)
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -228,119 +231,118 @@ static int rv3029_eeprom_enter(struct i2c_client *c=
lient)
 		 */
 		sr &=3D ~RV3029_STATUS_VLOW1;
 		sr &=3D ~RV3029_STATUS_VLOW2;
-		ret =3D rv3029_set_sr(client, sr);
+		ret =3D rv3029_set_sr(dev, sr);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
-		ret =3D rv3029_get_sr(client, &sr);
+		ret =3D rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
-			dev_err(&client->dev,
+			dev_err(dev,
 				"Supply voltage is too low to safely access the EEPROM.\n");
 			return -ENODEV;
 		}
 	}
=20
 	/* Disable eeprom refresh. */
-	ret =3D rv3029_update_bits(client, RV3029_ONOFF_CTRL,
-				 RV3029_ONOFF_CTRL_EERE, 0);
+	ret =3D rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE=
,
+				 0);
 	if (ret < 0)
 		return ret;
=20
 	/* Wait for any previous eeprom accesses to finish. */
-	ret =3D rv3029_eeprom_busywait(client);
+	ret =3D rv3029_eeprom_busywait(dev);
 	if (ret < 0)
-		rv3029_eeprom_exit(client);
+		rv3029_eeprom_exit(dev);
=20
 	return ret;
 }
=20
-static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_read(struct device *dev, u8 reg,
 			      u8 buf[], size_t len)
 {
 	int ret, err;
=20
-	err =3D rv3029_eeprom_enter(client);
+	err =3D rv3029_eeprom_enter(dev);
 	if (err < 0)
 		return err;
=20
-	ret =3D rv3029_read_regs(client, reg, buf, len);
+	ret =3D rv3029_read_regs(dev, reg, buf, len);
=20
-	err =3D rv3029_eeprom_exit(client);
+	err =3D rv3029_eeprom_exit(dev);
 	if (err < 0)
 		return err;
=20
 	return ret;
 }
=20
-static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_write(struct device *dev, u8 reg,
 			       u8 const buf[], size_t len)
 {
 	int ret, err;
 	size_t i;
 	u8 tmp;
=20
-	err =3D rv3029_eeprom_enter(client);
+	err =3D rv3029_eeprom_enter(dev);
 	if (err < 0)
 		return err;
=20
 	for (i =3D 0; i < len; i++, reg++) {
-		ret =3D rv3029_read_regs(client, reg, &tmp, 1);
+		ret =3D rv3029_read_regs(dev, reg, &tmp, 1);
 		if (ret < 0)
 			break;
 		if (tmp !=3D buf[i]) {
-			ret =3D rv3029_write_regs(client, reg, &buf[i], 1);
+			ret =3D rv3029_write_regs(dev, reg, &buf[i], 1);
 			if (ret < 0)
 				break;
 		}
-		ret =3D rv3029_eeprom_busywait(client);
+		ret =3D rv3029_eeprom_busywait(dev);
 		if (ret < 0)
 			break;
 	}
=20
-	err =3D rv3029_eeprom_exit(client);
+	err =3D rv3029_eeprom_exit(dev);
 	if (err < 0)
 		return err;
=20
 	return ret;
 }
=20
-static int rv3029_eeprom_update_bits(struct i2c_client *client,
+static int rv3029_eeprom_update_bits(struct device *dev,
 				     u8 reg, u8 mask, u8 set)
 {
 	u8 buf;
 	int ret;
=20
-	ret =3D rv3029_eeprom_read(client, reg, &buf, 1);
+	ret =3D rv3029_eeprom_read(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &=3D ~mask;
 	buf |=3D set & mask;
-	ret =3D rv3029_eeprom_write(client, reg, &buf, 1);
+	ret =3D rv3029_eeprom_write(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
=20
 	return 0;
 }
=20
-static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm=
)
+static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 buf[1];
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] =3D { 0, };
=20
-	ret =3D rv3029_get_sr(client, buf);
+	ret =3D rv3029_get_sr(dev, buf);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
=20
-	ret =3D rv3029_read_regs(client, RV3029_W_SEC, regs,
+	ret =3D rv3029_read_regs(dev, RV3029_W_SEC, regs,
 			       RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading RTC section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading RTC section failed\n", __func__);
 		return ret;
 	}
=20
@@ -368,30 +370,23 @@ static int rv3029_read_time(struct i2c_client *client=
, struct rtc_time *tm)
 	return 0;
 }
=20
-static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_read_time(to_i2c_client(dev), tm);
-}
-
-static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *al=
arm)
+static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	struct i2c_client *client =3D to_i2c_client(dev);
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
 	u8 regs[8];
=20
-	ret =3D rv3029_get_sr(client, regs);
+	ret =3D rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
=20
-	ret =3D rv3029_read_regs(client, RV3029_A_SC, regs,
+	ret =3D rv3029_read_regs(dev, RV3029_A_SC, regs,
 			       RV3029_ALARM_SECTION_LEN);
=20
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading alarm section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading alarm section failed\n", __func__);
 		return ret;
 	}
=20
@@ -406,25 +401,23 @@ static int rv3029_rtc_read_alarm(struct device *dev, =
struct rtc_wkalrm *alarm)
 	return 0;
 }
=20
-static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable)
+static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable)
 {
 	int ret;
=20
 	/* enable/disable AIE irq */
-	ret =3D rv3029_update_bits(client, RV3029_IRQ_CTRL,
-				 RV3029_IRQ_CTRL_AIE,
+	ret =3D rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE,
 				 (enable ? RV3029_IRQ_CTRL_AIE : 0));
 	if (ret < 0) {
-		dev_err(&client->dev, "can't update INT reg\n");
+		dev_err(dev, "can't update INT reg\n");
 		return ret;
 	}
=20
 	return 0;
 }
=20
-static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *ala=
rm)
+static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	struct i2c_client *client =3D to_i2c_client(dev);
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
 	u8 regs[8];
@@ -437,9 +430,9 @@ static int rv3029_rtc_set_alarm(struct device *dev, str=
uct rtc_wkalrm *alarm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
=20
-	ret =3D rv3029_get_sr(client, regs);
+	ret =3D rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 	regs[RV3029_A_SC-RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
@@ -450,38 +443,38 @@ static int rv3029_rtc_set_alarm(struct device *dev, s=
truct rtc_wkalrm *alarm)
 	regs[RV3029_A_DW-RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
 	regs[RV3029_A_YR-RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
=20
-	ret =3D rv3029_write_regs(client, RV3029_A_SC, regs,
+	ret =3D rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
=20
 	if (alarm->enabled) {
 		/* clear AF flag */
-		ret =3D rv3029_update_bits(client, RV3029_IRQ_FLAGS,
+		ret =3D rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
 					 RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
-			dev_err(&client->dev, "can't clear alarm flag\n");
+			dev_err(dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret =3D rv3029_rtc_alarm_set_irq(client, 1);
+		ret =3D rv3029_rtc_alarm_set_irq(dev, 1);
 		if (ret)
 			return ret;
=20
-		dev_dbg(&client->dev, "alarm IRQ armed\n");
+		dev_dbg(dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret =3D rv3029_rtc_alarm_set_irq(client, 0);
+		ret =3D rv3029_rtc_alarm_set_irq(dev, 0);
 		if (ret)
 			return ret;
=20
-		dev_dbg(&client->dev, "alarm IRQ disabled\n");
+		dev_dbg(dev, "alarm IRQ disabled\n");
 	}
=20
 	return 0;
 }
=20
-static int rv3029_set_time(struct i2c_client *client, struct rtc_time cons=
t *tm)
+static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -502,31 +495,25 @@ static int rv3029_set_time(struct i2c_client *client,=
 struct rtc_time const *tm)
 	regs[RV3029_W_DAYS-RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7)+1);
 	regs[RV3029_W_YEARS-RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
=20
-	ret =3D rv3029_write_regs(client, RV3029_W_SEC, regs,
+	ret =3D rv3029_write_regs(dev, RV3029_W_SEC, regs,
 				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
=20
-	ret =3D rv3029_get_sr(client, regs);
+	ret =3D rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret =3D rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
+	ret =3D rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
=20
 	return 0;
 }
-
-static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_set_time(to_i2c_client(dev), tm);
-}
-
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -584,9 +571,9 @@ static const struct rv3029_trickle_tab_elem {
 	},
 };
=20
-static void rv3029_trickle_config(struct i2c_client *client)
+static void rv3029_trickle_config(struct device *dev)
 {
-	struct device_node *of_node =3D client->dev.of_node;
+	struct device_node *of_node =3D dev->of_node;
 	const struct rv3029_trickle_tab_elem *elem;
 	int i, err;
 	u32 ohms;
@@ -608,27 +595,26 @@ static void rv3029_trickle_config(struct i2c_client *=
client)
 				break;
 		}
 		trickle_set_bits =3D elem->conf;
-		dev_info(&client->dev,
+		dev_info(dev,
 			 "Trickle charger enabled at %d ohms resistance.\n",
 			 elem->r);
 	}
-	err =3D rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	err =3D rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
 	if (err < 0) {
-		dev_err(&client->dev,
-			"Failed to update trickle charger config\n");
+		dev_err(dev, "Failed to update trickle charger config\n");
 	}
 }
=20
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
=20
-static int rv3029_read_temp(struct i2c_client *client, int *temp_mC)
+static int rv3029_read_temp(struct device *dev, int *temp_mC)
 {
 	int ret;
 	u8 temp;
=20
-	ret =3D rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
+	ret =3D rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
 	if (ret < 0)
 		return ret;
=20
@@ -641,10 +627,9 @@ static ssize_t rv3029_hwmon_show_temp(struct device *d=
ev,
 				      struct device_attribute *attr,
 				      char *buf)
 {
-	struct i2c_client *client =3D dev_get_drvdata(dev);
 	int ret, temp_mC;
=20
-	ret =3D rv3029_read_temp(client, &temp_mC);
+	ret =3D rv3029_read_temp(dev, &temp_mC);
 	if (ret < 0)
 		return ret;
=20
@@ -656,7 +641,6 @@ static ssize_t rv3029_hwmon_set_update_interval(struct =
device *dev,
 						const char *buf,
 						size_t count)
 {
-	struct i2c_client *client =3D dev_get_drvdata(dev);
 	unsigned long interval_ms;
 	int ret;
 	u8 th_set_bits =3D 0;
@@ -670,7 +654,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct =
device *dev,
 		if (interval_ms >=3D 16000)
 			th_set_bits |=3D RV3029_EECTRL_THP;
 	}
-	ret =3D rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	ret =3D rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_EECTRL_THE | RV3029_EECTRL_THP,
 					th_set_bits);
 	if (ret < 0)
@@ -683,11 +667,10 @@ static ssize_t rv3029_hwmon_show_update_interval(stru=
ct device *dev,
 						 struct device_attribute *attr,
 						 char *buf)
 {
-	struct i2c_client *client =3D dev_get_drvdata(dev);
 	int ret, interval_ms;
 	u8 eectrl;
=20
-	ret =3D rv3029_eeprom_read(client, RV3029_CONTROL_E2P_EECTRL,
+	ret =3D rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
 				 &eectrl, 1);
 	if (ret < 0)
 		return ret;
@@ -717,32 +700,32 @@ static struct attribute *rv3029_hwmon_attrs[] =3D {
 };
 ATTRIBUTE_GROUPS(rv3029_hwmon);
=20
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
+	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
 	struct device *hwmon_dev;
=20
-	hwmon_dev =3D devm_hwmon_device_register_with_groups(
-		&client->dev, client->name, client, rv3029_hwmon_groups);
+	hwmon_dev =3D devm_hwmon_device_register_with_groups(dev, name, rv3029,
+							   rv3029_hwmon_groups);
 	if (IS_ERR(hwmon_dev)) {
-		dev_warn(&client->dev,
-			 "unable to register hwmon device %ld\n",
+		dev_warn(dev, "unable to register hwmon device %ld\n",
 			 PTR_ERR(hwmon_dev));
 	}
 }
=20
 #else /* CONFIG_RTC_DRV_RV3029_HWMON */
=20
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
 }
=20
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
=20
 static const struct rtc_class_ops rv3029_rtc_ops =3D {
-	.read_time	=3D rv3029_rtc_read_time,
-	.set_time	=3D rv3029_rtc_set_time,
-	.read_alarm	=3D rv3029_rtc_read_alarm,
-	.set_alarm	=3D rv3029_rtc_set_alarm,
+	.read_time	=3D rv3029_read_time,
+	.set_time	=3D rv3029_set_time,
+	.read_alarm	=3D rv3029_read_alarm,
+	.set_alarm	=3D rv3029_set_alarm,
 };
=20
 static struct i2c_device_id rv3029_id[] =3D {
@@ -752,41 +735,67 @@ static struct i2c_device_id rv3029_id[] =3D {
 };
 MODULE_DEVICE_TABLE(i2c, rv3029_id);
=20
-static int rv3029_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq=
,
+			const char *name)
 {
-	struct rtc_device *rtc;
+	struct rv3029_data *rv3029;
 	int rc =3D 0;
 	u8 buf[1];
=20
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
-		return -ENODEV;
+	rv3029 =3D devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
+	if (!rv3029)
+		return -ENOMEM;
+
+	rv3029->regmap =3D regmap;
+	rv3029->irq =3D irq;
+	rv3029->dev =3D dev;
+	dev_set_drvdata(dev, rv3029);
=20
-	rc =3D rv3029_get_sr(client, buf);
+	rc =3D rv3029_get_sr(dev, buf);
 	if (rc < 0) {
-		dev_err(&client->dev, "reading status failed\n");
+		dev_err(dev, "reading status failed\n");
 		return rc;
 	}
=20
-	rv3029_trickle_config(client);
-	rv3029_hwmon_register(client);
+	rv3029_trickle_config(dev);
+	rv3029_hwmon_register(dev, name);
+
+	rv3029->rtc =3D devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
+					       THIS_MODULE);
=20
-	rtc =3D devm_rtc_device_register(&client->dev, client->name,
-				       &rv3029_rtc_ops, THIS_MODULE);
+	return PTR_ERR_OR_ZERO(rv3029->rtc);
+}
=20
-	if (IS_ERR(rtc))
-		return PTR_ERR(rtc);
+static int rv3029_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	static const struct regmap_config config =3D {
+		.reg_bits =3D 8,
+		.val_bits =3D 8,
+	};
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
+				     I2C_FUNC_SMBUS_BYTE)) {
+		dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS=
_I2C_BYTE\n");
+		return -ENODEV;
+	}
=20
-	i2c_set_clientdata(client, rtc);
+	regmap =3D devm_regmap_init_i2c(client, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
=20
-	return 0;
+	return rv3029_probe(&client->dev, regmap, client->irq, client->name);
 }
=20
 static struct i2c_driver rv3029_driver =3D {
 	.driver =3D {
 		.name =3D "rtc-rv3029c2",
 	},
-	.probe		=3D rv3029_probe,
+	.probe		=3D rv3029_i2c_probe,
 	.id_table	=3D rv3029_id,
 };
=20
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 3/6] rtc: rv3029: Add support of RV3049
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-21 18:24   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Add support of Microcrystal RV3049 RTC (SPI) using regmap on the
RV3029 (I2C) driver.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/Kconfig        |  37 +++++++--------
 drivers/rtc/rtc-rv3029c2.c | 110 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 126 insertions(+), 21 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index f1e1f50..18639e0 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -573,24 +573,6 @@ config RTC_DRV_EM3027
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-em3027.
 
-config RTC_DRV_RV3029C2
-	tristate "Micro Crystal RV3029"
-	help
-	  If you say yes here you get support for the Micro Crystal
-	  RV3029 RTC chips.
-
-	  This driver can also be built as a module. If so, the module
-	  will be called rtc-rv3029c2.
-
-config RTC_DRV_RV3029_HWMON
-	bool "HWMON support for RV3029"
-	depends on RTC_DRV_RV3029C2 && HWMON
-	depends on !(RTC_DRV_RV3029C2=y && HWMON=m)
-	default y
-	help
-	  Say Y here if you want to expose temperature sensor data on
-	  rtc-rv3029.
-
 config RTC_DRV_RV8803
 	tristate "Micro Crystal RV8803"
 	help
@@ -786,6 +768,25 @@ config RTC_DRV_PCF2127
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-pcf2127.
 
+config RTC_DRV_RV3029C2
+	tristate "Micro Crystal RV3029/3049"
+	depends on RTC_I2C_AND_SPI
+	help
+	  If you say yes here you get support for the Micro Crystal
+	  RV3029 and RV3049 RTC chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-rv3029c2.
+
+config RTC_DRV_RV3029_HWMON
+	bool "HWMON support for RV3029/3049"
+	depends on RTC_DRV_RV3029C2 && HWMON
+	depends on !(RTC_DRV_RV3029C2=y && HWMON=m)
+	default y
+	help
+	  Say Y here if you want to expose temperature sensor data on
+	  rtc-rv3029.
+
 comment "Platform RTC drivers"
 
 # this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 96dd166..470cc1e 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -1,5 +1,5 @@
 /*
- * Micro Crystal RV-3029 rtc class driver
+ * Micro Crystal RV-3029 / RV-3049 rtc class driver
  *
  * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
  *         Michael Buesch <m@bues.ch>
@@ -14,6 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/spi/spi.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
@@ -766,6 +767,8 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 	return PTR_ERR_OR_ZERO(rv3029->rtc);
 }
 
+#if IS_ENABLED(CONFIG_I2C)
+
 static int rv3029_i2c_probe(struct i2c_client *client,
 			    const struct i2c_device_id *id)
 {
@@ -799,9 +802,110 @@ static struct i2c_driver rv3029_driver = {
 	.id_table	= rv3029_id,
 };
 
-module_i2c_driver(rv3029_driver);
+static int rv3029_register_driver(void)
+{
+	return i2c_add_driver(&rv3029_driver);
+}
+
+static void rv3029_unregister_driver(void)
+{
+	i2c_del_driver(&rv3029_driver);
+}
+
+#else
+
+static int rv3029_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3029_unregister_driver(void)
+{
+}
+
+#endif
+
+#if IS_ENABLED(CONFIG_SPI_MASTER)
+
+static int rv3049_probe(struct spi_device *spi)
+{
+	int res;
+	unsigned int tmp;
+	static const struct regmap_config config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+	};
+	struct regmap *regmap;
+
+	regmap = devm_regmap_init_spi(spi, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
+
+	return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
+}
+
+static struct spi_driver rv3049_driver = {
+	.driver = {
+		.name    = "rv3049",
+	},
+	.probe   = rv3049_probe,
+};
+
+static int rv3049_register_driver(void)
+{
+	return spi_register_driver(&rv3049_driver);
+}
+
+static void rv3049_unregister_driver(void)
+{
+	spi_unregister_driver(&rv3049_driver);
+}
+
+#else
+
+static int rv3049_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3049_unregister_driver(void)
+{
+}
+
+#endif
+
+static int __init rv30x9_init(void)
+{
+	int ret;
+
+	ret = rv3029_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3029 driver: %d\n", ret);
+		return ret;
+	}
+
+	ret = rv3049_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3049 driver: %d\n", ret);
+		rv3029_unregister_driver();
+	}
+
+	return ret;
+}
+module_init(rv30x9_init)
+
+static void __exit rv30x9_exit(void)
+{
+	rv3049_unregister_driver();
+	rv3029_unregister_driver();
+}
+module_exit(rv30x9_exit)
 
 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
 MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
-MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
+MODULE_DESCRIPTION("Micro Crystal RV3029/RV3049 RTC driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:rv3049");
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH 3/6] rtc: rv3029: Add support of RV3049
@ 2016-04-21 18:24   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Add support of Microcrystal RV3049 RTC (SPI) using regmap on the
RV3029 (I2C) driver.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/Kconfig        |  37 +++++++--------
 drivers/rtc/rtc-rv3029c2.c | 110 +++++++++++++++++++++++++++++++++++++++++=
++--
 2 files changed, 126 insertions(+), 21 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index f1e1f50..18639e0 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -573,24 +573,6 @@ config RTC_DRV_EM3027
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-em3027.
=20
-config RTC_DRV_RV3029C2
-	tristate "Micro Crystal RV3029"
-	help
-	  If you say yes here you get support for the Micro Crystal
-	  RV3029 RTC chips.
-
-	  This driver can also be built as a module. If so, the module
-	  will be called rtc-rv3029c2.
-
-config RTC_DRV_RV3029_HWMON
-	bool "HWMON support for RV3029"
-	depends on RTC_DRV_RV3029C2 && HWMON
-	depends on !(RTC_DRV_RV3029C2=3Dy && HWMON=3Dm)
-	default y
-	help
-	  Say Y here if you want to expose temperature sensor data on
-	  rtc-rv3029.
-
 config RTC_DRV_RV8803
 	tristate "Micro Crystal RV8803"
 	help
@@ -786,6 +768,25 @@ config RTC_DRV_PCF2127
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-pcf2127.
=20
+config RTC_DRV_RV3029C2
+	tristate "Micro Crystal RV3029/3049"
+	depends on RTC_I2C_AND_SPI
+	help
+	  If you say yes here you get support for the Micro Crystal
+	  RV3029 and RV3049 RTC chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-rv3029c2.
+
+config RTC_DRV_RV3029_HWMON
+	bool "HWMON support for RV3029/3049"
+	depends on RTC_DRV_RV3029C2 && HWMON
+	depends on !(RTC_DRV_RV3029C2=3Dy && HWMON=3Dm)
+	default y
+	help
+	  Say Y here if you want to expose temperature sensor data on
+	  rtc-rv3029.
+
 comment "Platform RTC drivers"
=20
 # this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 96dd166..470cc1e 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -1,5 +1,5 @@
 /*
- * Micro Crystal RV-3029 rtc class driver
+ * Micro Crystal RV-3029 / RV-3049 rtc class driver
  *
  * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
  *         Michael Buesch <m@bues.ch>
@@ -14,6 +14,7 @@
=20
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/spi/spi.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
@@ -766,6 +767,8 @@ static int rv3029_probe(struct device *dev, struct regm=
ap *regmap, int irq,
 	return PTR_ERR_OR_ZERO(rv3029->rtc);
 }
=20
+#if IS_ENABLED(CONFIG_I2C)
+
 static int rv3029_i2c_probe(struct i2c_client *client,
 			    const struct i2c_device_id *id)
 {
@@ -799,9 +802,110 @@ static struct i2c_driver rv3029_driver =3D {
 	.id_table	=3D rv3029_id,
 };
=20
-module_i2c_driver(rv3029_driver);
+static int rv3029_register_driver(void)
+{
+	return i2c_add_driver(&rv3029_driver);
+}
+
+static void rv3029_unregister_driver(void)
+{
+	i2c_del_driver(&rv3029_driver);
+}
+
+#else
+
+static int rv3029_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3029_unregister_driver(void)
+{
+}
+
+#endif
+
+#if IS_ENABLED(CONFIG_SPI_MASTER)
+
+static int rv3049_probe(struct spi_device *spi)
+{
+	int res;
+	unsigned int tmp;
+	static const struct regmap_config config =3D {
+		.reg_bits =3D 8,
+		.val_bits =3D 8,
+	};
+	struct regmap *regmap;
+
+	regmap =3D devm_regmap_init_spi(spi, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
+
+	return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
+}
+
+static struct spi_driver rv3049_driver =3D {
+	.driver =3D {
+		.name    =3D "rv3049",
+	},
+	.probe   =3D rv3049_probe,
+};
+
+static int rv3049_register_driver(void)
+{
+	return spi_register_driver(&rv3049_driver);
+}
+
+static void rv3049_unregister_driver(void)
+{
+	spi_unregister_driver(&rv3049_driver);
+}
+
+#else
+
+static int rv3049_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3049_unregister_driver(void)
+{
+}
+
+#endif
+
+static int __init rv30x9_init(void)
+{
+	int ret;
+
+	ret =3D rv3029_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3029 driver: %d\n", ret);
+		return ret;
+	}
+
+	ret =3D rv3049_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3049 driver: %d\n", ret);
+		rv3029_unregister_driver();
+	}
+
+	return ret;
+}
+module_init(rv30x9_init)
+
+static void __exit rv30x9_exit(void)
+{
+	rv3049_unregister_driver();
+	rv3029_unregister_driver();
+}
+module_exit(rv30x9_exit)
=20
 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
 MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
-MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
+MODULE_DESCRIPTION("Micro Crystal RV3029/RV3049 RTC driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:rv3049");
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 4/6] rtc: rv3029: Removes some checks and warnings
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-21 18:24   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Removes some checks from checkpatch such as spaces around arithmetic
operations.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 66 ++++++++++++++++++++++------------------------
 1 file changed, 32 insertions(+), 34 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 470cc1e..a849005 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -130,7 +130,7 @@ static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
 	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 
 	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
@@ -142,7 +142,7 @@ static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
 	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 
 	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
@@ -347,12 +347,12 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	tm->tm_sec = bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
-	tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES-RV3029_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[RV3029_W_HOURS-RV3029_W_SEC];
+		const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC];
 
 		if (_hr & RV3029_REG_HR_12_24) {
 			/* 12h format */
@@ -363,10 +363,10 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 			tm->tm_hour = bcd2bin(_hr & 0x3f);
 	}
 
-	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;
+	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;
 }
@@ -391,13 +391,13 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		return ret;
 	}
 
-	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;
+	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;
 }
@@ -436,13 +436,13 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	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);
+	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_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
@@ -488,13 +488,13 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	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);
+	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 = rv3029_write_regs(dev, RV3029_W_SEC, regs,
 				RV3029_WATCH_SECTION_LEN);
@@ -515,6 +515,7 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 
 	return 0;
 }
+
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -603,9 +604,8 @@ static void rv3029_trickle_config(struct device *dev)
 	err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
-	if (err < 0) {
+	if (err < 0)
 		dev_err(dev, "Failed to update trickle charger config\n");
-	}
 }
 
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
@@ -829,8 +829,6 @@ static void rv3029_unregister_driver(void)
 
 static int rv3049_probe(struct spi_device *spi)
 {
-	int res;
-	unsigned int tmp;
 	static const struct regmap_config config = {
 		.reg_bits = 8,
 		.val_bits = 8,
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH 4/6] rtc: rv3029: Removes some checks and warnings
@ 2016-04-21 18:24   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Removes some checks from checkpatch such as spaces around arithmetic
operations.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 66 ++++++++++++++++++++++--------------------=
----
 1 file changed, 32 insertions(+), 34 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 470cc1e..a849005 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -130,7 +130,7 @@ static int rv3029_read_regs(struct device *dev, u8 reg,=
 u8 *buf,
 	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
=20
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
=20
 	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
@@ -142,7 +142,7 @@ static int rv3029_write_regs(struct device *dev, u8 reg=
, u8 const buf[],
 	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
=20
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
=20
 	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
@@ -347,12 +347,12 @@ static int rv3029_read_time(struct device *dev, struc=
t rtc_time *tm)
 		return ret;
 	}
=20
-	tm->tm_sec =3D bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
-	tm->tm_min =3D bcd2bin(regs[RV3029_W_MINUTES-RV3029_W_SEC]);
+	tm->tm_sec =3D bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
+	tm->tm_min =3D bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
=20
 	/* HR field has a more complex interpretation */
 	{
-		const u8 _hr =3D regs[RV3029_W_HOURS-RV3029_W_SEC];
+		const u8 _hr =3D regs[RV3029_W_HOURS - RV3029_W_SEC];
=20
 		if (_hr & RV3029_REG_HR_12_24) {
 			/* 12h format */
@@ -363,10 +363,10 @@ static int rv3029_read_time(struct device *dev, struc=
t rtc_time *tm)
 			tm->tm_hour =3D bcd2bin(_hr & 0x3f);
 	}
=20
-	tm->tm_mday =3D bcd2bin(regs[RV3029_W_DATE-RV3029_W_SEC]);
-	tm->tm_mon =3D bcd2bin(regs[RV3029_W_MONTHS-RV3029_W_SEC]) - 1;
-	tm->tm_year =3D bcd2bin(regs[RV3029_W_YEARS-RV3029_W_SEC]) + 100;
-	tm->tm_wday =3D bcd2bin(regs[RV3029_W_DAYS-RV3029_W_SEC]) - 1;
+	tm->tm_mday =3D bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]);
+	tm->tm_mon =3D bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1;
+	tm->tm_year =3D bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 100;
+	tm->tm_wday =3D bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1;
=20
 	return 0;
 }
@@ -391,13 +391,13 @@ static int rv3029_read_alarm(struct device *dev, stru=
ct rtc_wkalrm *alarm)
 		return ret;
 	}
=20
-	tm->tm_sec =3D bcd2bin(regs[RV3029_A_SC-RV3029_A_SC] & 0x7f);
-	tm->tm_min =3D bcd2bin(regs[RV3029_A_MN-RV3029_A_SC] & 0x7f);
-	tm->tm_hour =3D bcd2bin(regs[RV3029_A_HR-RV3029_A_SC] & 0x3f);
-	tm->tm_mday =3D bcd2bin(regs[RV3029_A_DT-RV3029_A_SC] & 0x3f);
-	tm->tm_mon =3D bcd2bin(regs[RV3029_A_MO-RV3029_A_SC] & 0x1f) - 1;
-	tm->tm_year =3D bcd2bin(regs[RV3029_A_YR-RV3029_A_SC] & 0x7f) + 100;
-	tm->tm_wday =3D bcd2bin(regs[RV3029_A_DW-RV3029_A_SC] & 0x07) - 1;
+	tm->tm_sec =3D bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
+	tm->tm_min =3D bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
+	tm->tm_hour =3D bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f);
+	tm->tm_mday =3D bcd2bin(regs[RV3029_A_DT - RV3029_A_SC] & 0x3f);
+	tm->tm_mon =3D bcd2bin(regs[RV3029_A_MO - RV3029_A_SC] & 0x1f) - 1;
+	tm->tm_year =3D bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100;
+	tm->tm_wday =3D bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1;
=20
 	return 0;
 }
@@ -436,13 +436,13 @@ static int rv3029_set_alarm(struct device *dev, struc=
t rtc_wkalrm *alarm)
 		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	regs[RV3029_A_SC-RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
-	regs[RV3029_A_MN-RV3029_A_SC] =3D bin2bcd(tm->tm_min & 0x7f);
-	regs[RV3029_A_HR-RV3029_A_SC] =3D bin2bcd(tm->tm_hour & 0x3f);
-	regs[RV3029_A_DT-RV3029_A_SC] =3D bin2bcd(tm->tm_mday & 0x3f);
-	regs[RV3029_A_MO-RV3029_A_SC] =3D bin2bcd((tm->tm_mon & 0x1f) - 1);
-	regs[RV3029_A_DW-RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
-	regs[RV3029_A_YR-RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
+	regs[RV3029_A_SC - RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
+	regs[RV3029_A_MN - RV3029_A_SC] =3D bin2bcd(tm->tm_min & 0x7f);
+	regs[RV3029_A_HR - RV3029_A_SC] =3D bin2bcd(tm->tm_hour & 0x3f);
+	regs[RV3029_A_DT - RV3029_A_SC] =3D bin2bcd(tm->tm_mday & 0x3f);
+	regs[RV3029_A_MO - RV3029_A_SC] =3D bin2bcd((tm->tm_mon & 0x1f) - 1);
+	regs[RV3029_A_DW - RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
+	regs[RV3029_A_YR - RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
=20
 	ret =3D rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
@@ -488,13 +488,13 @@ static int rv3029_set_time(struct device *dev, struct=
 rtc_time *tm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
=20
-	regs[RV3029_W_SEC-RV3029_W_SEC] =3D bin2bcd(tm->tm_sec);
-	regs[RV3029_W_MINUTES-RV3029_W_SEC] =3D bin2bcd(tm->tm_min);
-	regs[RV3029_W_HOURS-RV3029_W_SEC] =3D bin2bcd(tm->tm_hour);
-	regs[RV3029_W_DATE-RV3029_W_SEC] =3D bin2bcd(tm->tm_mday);
-	regs[RV3029_W_MONTHS-RV3029_W_SEC] =3D bin2bcd(tm->tm_mon+1);
-	regs[RV3029_W_DAYS-RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7)+1);
-	regs[RV3029_W_YEARS-RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
+	regs[RV3029_W_SEC - RV3029_W_SEC] =3D bin2bcd(tm->tm_sec);
+	regs[RV3029_W_MINUTES - RV3029_W_SEC] =3D bin2bcd(tm->tm_min);
+	regs[RV3029_W_HOURS - RV3029_W_SEC] =3D bin2bcd(tm->tm_hour);
+	regs[RV3029_W_DATE - RV3029_W_SEC] =3D bin2bcd(tm->tm_mday);
+	regs[RV3029_W_MONTHS - RV3029_W_SEC] =3D bin2bcd(tm->tm_mon + 1);
+	regs[RV3029_W_DAYS - RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7) + 1);
+	regs[RV3029_W_YEARS - RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
=20
 	ret =3D rv3029_write_regs(dev, RV3029_W_SEC, regs,
 				RV3029_WATCH_SECTION_LEN);
@@ -515,6 +515,7 @@ static int rv3029_set_time(struct device *dev, struct r=
tc_time *tm)
=20
 	return 0;
 }
+
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -603,9 +604,8 @@ static void rv3029_trickle_config(struct device *dev)
 	err =3D rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
-	if (err < 0) {
+	if (err < 0)
 		dev_err(dev, "Failed to update trickle charger config\n");
-	}
 }
=20
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
@@ -829,8 +829,6 @@ static void rv3029_unregister_driver(void)
=20
 static int rv3049_probe(struct spi_device *spi)
 {
-	int res;
-	unsigned int tmp;
 	static const struct regmap_config config =3D {
 		.reg_bits =3D 8,
 		.val_bits =3D 8,
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 5/6] rtc: rv3029: enable AE_x bits on set_alarm
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-21 18:24   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

The RTC RV3029 handles different types of alarms : seconds, minutes, ...
These alarms can be enabled or disabled individually using an AE_x bit
which is the last bit (BIT(7)) on each alarm registers.

To prepare the alarm IRQ support, the current code enables all the alarm
types by setting each AE_x to 1.
It also fixes month and weekday errors : it was performing -1 instead
of +1.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index a849005..42de1a3 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -76,6 +76,7 @@
 #define RV3029_A_DW			0x14
 #define RV3029_A_MO			0x15
 #define RV3029_A_YR			0x16
+#define RV3029_A_AE_X			BIT(7)
 #define RV3029_ALARM_SECTION_LEN	0x07
 
 /* timer section */
@@ -436,14 +437,22 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	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);
 
+	/* Activate all the alarms with AE_x bit */
+	regs[RV3029_A_SC - RV3029_A_SC] = (bin2bcd(tm->tm_sec)) | RV3029_A_AE_X;
+	regs[RV3029_A_MN - RV3029_A_SC] = (bin2bcd(tm->tm_min)) | RV3029_A_AE_X;
+	regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour & 0x3f))
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday & 0x3f))
+		| RV3029_A_AE_X;
+	regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd((tm->tm_mon & 0x1f) + 1))
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd((tm->tm_wday & 7) + 1))
+		| RV3029_A_AE_X;
+	regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd((tm->tm_year) - 100))
+		| RV3029_A_AE_X;
+
+	/* Write the alarm */
 	ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH 5/6] rtc: rv3029: enable AE_x bits on set_alarm
@ 2016-04-21 18:24   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

The RTC RV3029 handles different types of alarms : seconds, minutes, ...
These alarms can be enabled or disabled individually using an AE_x bit
which is the last bit (BIT(7)) on each alarm registers.

To prepare the alarm IRQ support, the current code enables all the alarm
types by setting each AE_x to 1.
It also fixes month and weekday errors : it was performing -1 instead
of +1.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index a849005..42de1a3 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -76,6 +76,7 @@
 #define RV3029_A_DW			0x14
 #define RV3029_A_MO			0x15
 #define RV3029_A_YR			0x16
+#define RV3029_A_AE_X			BIT(7)
 #define RV3029_ALARM_SECTION_LEN	0x07
=20
 /* timer section */
@@ -436,14 +437,22 @@ static int rv3029_set_alarm(struct device *dev, struc=
t rtc_wkalrm *alarm)
 		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	regs[RV3029_A_SC - RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
-	regs[RV3029_A_MN - RV3029_A_SC] =3D bin2bcd(tm->tm_min & 0x7f);
-	regs[RV3029_A_HR - RV3029_A_SC] =3D bin2bcd(tm->tm_hour & 0x3f);
-	regs[RV3029_A_DT - RV3029_A_SC] =3D bin2bcd(tm->tm_mday & 0x3f);
-	regs[RV3029_A_MO - RV3029_A_SC] =3D bin2bcd((tm->tm_mon & 0x1f) - 1);
-	regs[RV3029_A_DW - RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
-	regs[RV3029_A_YR - RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
=20
+	/* Activate all the alarms with AE_x bit */
+	regs[RV3029_A_SC - RV3029_A_SC] =3D (bin2bcd(tm->tm_sec)) | RV3029_A_AE_X=
;
+	regs[RV3029_A_MN - RV3029_A_SC] =3D (bin2bcd(tm->tm_min)) | RV3029_A_AE_X=
;
+	regs[RV3029_A_HR - RV3029_A_SC] =3D (bin2bcd(tm->tm_hour & 0x3f))
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DT - RV3029_A_SC] =3D (bin2bcd(tm->tm_mday & 0x3f))
+		| RV3029_A_AE_X;
+	regs[RV3029_A_MO - RV3029_A_SC] =3D (bin2bcd((tm->tm_mon & 0x1f) + 1))
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DW - RV3029_A_SC] =3D (bin2bcd((tm->tm_wday & 7) + 1))
+		| RV3029_A_AE_X;
+	regs[RV3029_A_YR - RV3029_A_SC] =3D (bin2bcd((tm->tm_year) - 100))
+		| RV3029_A_AE_X;
+
+	/* Write the alarm */
 	ret =3D rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 6/6] rtc: rv3029: add alarm IRQ
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-21 18:24   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Add the alarm IRQ functionality.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 114 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 93 insertions(+), 21 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 42de1a3..152ca9d 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -329,6 +329,47 @@ static int rv3029_eeprom_update_bits(struct device *dev,
 	return 0;
 }
 
+static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
+{
+	struct device *dev = dev_id;
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+	struct mutex *lock = &rv3029->rtc->ops_lock;
+	unsigned long events = 0;
+	u8 flags, controls;
+	int ret;
+
+	mutex_lock(lock);
+
+	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	if (flags & RV3029_IRQ_FLAGS_AF) {
+		flags &= ~RV3029_IRQ_FLAGS_AF;
+		controls &= ~RV3029_IRQ_CTRL_AIE;
+		events |= RTC_AF;
+	}
+
+	if (events) {
+		rtc_update_irq(rv3029->rtc, 1, events);
+		rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+		rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	}
+	mutex_unlock(lock);
+
+	return IRQ_HANDLED;
+}
+
 static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 buf[1];
@@ -376,7 +417,7 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
-	u8 regs[8];
+	u8 regs[8], controls, flags;
 
 	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
@@ -392,6 +433,17 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		return ret;
 	}
 
+	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_err(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
+	ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret < 0) {
+		dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
+		return ret;
+	}
+
 	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);
@@ -400,16 +452,30 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	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;
 
+	alarm->enabled = !!(controls & RV3029_IRQ_CTRL_AIE);
+	alarm->pending = (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled;
+
 	return 0;
 }
 
-static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable)
+static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
 {
 	int ret;
+	u8 controls;
+
+	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret < 0) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
 
 	/* enable/disable AIE irq */
-	ret = rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE,
-				 (enable ? RV3029_IRQ_CTRL_AIE : 0));
+	if (enable)
+		controls |= RV3029_IRQ_CTRL_AIE;
+	else
+		controls &= ~RV3029_IRQ_CTRL_AIE;
+
+	ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
 	if (ret < 0) {
 		dev_err(dev, "can't update INT reg\n");
 		return ret;
@@ -459,26 +525,15 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		return ret;
 
 	if (alarm->enabled) {
-		/* clear AF flag */
-		ret = rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
-					 RV3029_IRQ_FLAGS_AF, 0);
-		if (ret < 0) {
-			dev_err(dev, "can't clear alarm flag\n");
-			return ret;
-		}
 		/* enable AIE irq */
-		ret = rv3029_rtc_alarm_set_irq(dev, 1);
+		ret = rv3029_alarm_irq_enable(dev, 1);
 		if (ret)
 			return ret;
-
-		dev_dbg(dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret = rv3029_rtc_alarm_set_irq(dev, 0);
+		ret = rv3029_alarm_irq_enable(dev, 0);
 		if (ret)
 			return ret;
-
-		dev_dbg(dev, "alarm IRQ disabled\n");
 	}
 
 	return 0;
@@ -731,11 +786,9 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
 
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
 
-static const struct rtc_class_ops rv3029_rtc_ops = {
+static struct rtc_class_ops rv3029_rtc_ops = {
 	.read_time	= rv3029_read_time,
 	.set_time	= rv3029_set_time,
-	.read_alarm	= rv3029_read_alarm,
-	.set_alarm	= rv3029_set_alarm,
 };
 
 static struct i2c_device_id rv3029_id[] = {
@@ -772,8 +825,27 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 
 	rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
 					       THIS_MODULE);
+	if (IS_ERR(rv3029->rtc)) {
+		dev_err(dev, "unable to register the class device\n");
+		return PTR_ERR(rv3029->rtc);
+	}
 
-	return PTR_ERR_OR_ZERO(rv3029->rtc);
+	if (rv3029->irq > 0) {
+		rc = devm_request_threaded_irq(dev, rv3029->irq,
+					       NULL, rv3029_handle_irq,
+					       IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					       "rv3029", dev);
+		if (rc) {
+			dev_warn(dev, "unable to request IRQ, alarms disabled\n");
+			rv3029->irq = 0;
+		} else {
+			rv3029_rtc_ops.read_alarm = rv3029_read_alarm;
+			rv3029_rtc_ops.set_alarm = rv3029_set_alarm;
+			rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable;
+		}
+	}
+
+	return 0;
 }
 
 #if IS_ENABLED(CONFIG_I2C)
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH 6/6] rtc: rv3029: add alarm IRQ
@ 2016-04-21 18:24   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-21 18:24 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Add the alarm IRQ functionality.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 114 ++++++++++++++++++++++++++++++++++++-----=
----
 1 file changed, 93 insertions(+), 21 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 42de1a3..152ca9d 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -329,6 +329,47 @@ static int rv3029_eeprom_update_bits(struct device *de=
v,
 	return 0;
 }
=20
+static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
+{
+	struct device *dev =3D dev_id;
+	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
+	struct mutex *lock =3D &rv3029->rtc->ops_lock;
+	unsigned long events =3D 0;
+	u8 flags, controls;
+	int ret;
+
+	mutex_lock(lock);
+
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	if (flags & RV3029_IRQ_FLAGS_AF) {
+		flags &=3D ~RV3029_IRQ_FLAGS_AF;
+		controls &=3D ~RV3029_IRQ_CTRL_AIE;
+		events |=3D RTC_AF;
+	}
+
+	if (events) {
+		rtc_update_irq(rv3029->rtc, 1, events);
+		rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+		rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	}
+	mutex_unlock(lock);
+
+	return IRQ_HANDLED;
+}
+
 static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 buf[1];
@@ -376,7 +417,7 @@ static int rv3029_read_alarm(struct device *dev, struct=
 rtc_wkalrm *alarm)
 {
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
-	u8 regs[8];
+	u8 regs[8], controls, flags;
=20
 	ret =3D rv3029_get_sr(dev, regs);
 	if (ret < 0) {
@@ -392,6 +433,17 @@ static int rv3029_read_alarm(struct device *dev, struc=
t rtc_wkalrm *alarm)
 		return ret;
 	}
=20
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_err(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret < 0) {
+		dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
+		return ret;
+	}
+
 	tm->tm_sec =3D bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
 	tm->tm_min =3D bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
 	tm->tm_hour =3D bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f);
@@ -400,16 +452,30 @@ static int rv3029_read_alarm(struct device *dev, stru=
ct rtc_wkalrm *alarm)
 	tm->tm_year =3D bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100;
 	tm->tm_wday =3D bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1;
=20
+	alarm->enabled =3D !!(controls & RV3029_IRQ_CTRL_AIE);
+	alarm->pending =3D (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled;
+
 	return 0;
 }
=20
-static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable)
+static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable=
)
 {
 	int ret;
+	u8 controls;
+
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret < 0) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
=20
 	/* enable/disable AIE irq */
-	ret =3D rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE,
-				 (enable ? RV3029_IRQ_CTRL_AIE : 0));
+	if (enable)
+		controls |=3D RV3029_IRQ_CTRL_AIE;
+	else
+		controls &=3D ~RV3029_IRQ_CTRL_AIE;
+
+	ret =3D rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
 	if (ret < 0) {
 		dev_err(dev, "can't update INT reg\n");
 		return ret;
@@ -459,26 +525,15 @@ static int rv3029_set_alarm(struct device *dev, struc=
t rtc_wkalrm *alarm)
 		return ret;
=20
 	if (alarm->enabled) {
-		/* clear AF flag */
-		ret =3D rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
-					 RV3029_IRQ_FLAGS_AF, 0);
-		if (ret < 0) {
-			dev_err(dev, "can't clear alarm flag\n");
-			return ret;
-		}
 		/* enable AIE irq */
-		ret =3D rv3029_rtc_alarm_set_irq(dev, 1);
+		ret =3D rv3029_alarm_irq_enable(dev, 1);
 		if (ret)
 			return ret;
-
-		dev_dbg(dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret =3D rv3029_rtc_alarm_set_irq(dev, 0);
+		ret =3D rv3029_alarm_irq_enable(dev, 0);
 		if (ret)
 			return ret;
-
-		dev_dbg(dev, "alarm IRQ disabled\n");
 	}
=20
 	return 0;
@@ -731,11 +786,9 @@ static void rv3029_hwmon_register(struct device *dev, =
const char *name)
=20
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
=20
-static const struct rtc_class_ops rv3029_rtc_ops =3D {
+static struct rtc_class_ops rv3029_rtc_ops =3D {
 	.read_time	=3D rv3029_read_time,
 	.set_time	=3D rv3029_set_time,
-	.read_alarm	=3D rv3029_read_alarm,
-	.set_alarm	=3D rv3029_set_alarm,
 };
=20
 static struct i2c_device_id rv3029_id[] =3D {
@@ -772,8 +825,27 @@ static int rv3029_probe(struct device *dev, struct reg=
map *regmap, int irq,
=20
 	rv3029->rtc =3D devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
 					       THIS_MODULE);
+	if (IS_ERR(rv3029->rtc)) {
+		dev_err(dev, "unable to register the class device\n");
+		return PTR_ERR(rv3029->rtc);
+	}
=20
-	return PTR_ERR_OR_ZERO(rv3029->rtc);
+	if (rv3029->irq > 0) {
+		rc =3D devm_request_threaded_irq(dev, rv3029->irq,
+					       NULL, rv3029_handle_irq,
+					       IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					       "rv3029", dev);
+		if (rc) {
+			dev_warn(dev, "unable to request IRQ, alarms disabled\n");
+			rv3029->irq =3D 0;
+		} else {
+			rv3029_rtc_ops.read_alarm =3D rv3029_read_alarm;
+			rv3029_rtc_ops.set_alarm =3D rv3029_set_alarm;
+			rv3029_rtc_ops.alarm_irq_enable =3D rv3029_alarm_irq_enable;
+		}
+	}
+
+	return 0;
 }
=20
 #if IS_ENABLED(CONFIG_I2C)
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH 4/6] rtc: rv3029: Removes some checks and warnings
  2016-04-21 18:24   ` [rtc-linux] " Mylène Josserand
@ 2016-04-22 23:29     ` Alexandre Belloni
  -1 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-04-22 23:29 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

Hi,

On 21/04/2016 at 20:24:17 +0200, Mylène Josserand wrote :
> @@ -829,8 +829,6 @@ static void rv3029_unregister_driver(void)
>  
>  static int rv3049_probe(struct spi_device *spi)
>  {
> -	int res;
> -	unsigned int tmp;

Well, you just introduced those variables in the previous patch.

>  	static const struct regmap_config config = {
>  		.reg_bits = 8,
>  		.val_bits = 8,
> -- 
> 2.8.0.rc3
> 

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [rtc-linux] Re: [PATCH 4/6] rtc: rv3029: Removes some checks and warnings
@ 2016-04-22 23:29     ` Alexandre Belloni
  0 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-04-22 23:29 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

Hi,

On 21/04/2016 at 20:24:17 +0200, Myl=C4=8Dne Josserand wrote :
> @@ -829,8 +829,6 @@ static void rv3029_unregister_driver(void)
> =20
>  static int rv3049_probe(struct spi_device *spi)
>  {
> -	int res;
> -	unsigned int tmp;

Well, you just introduced those variables in the previous patch.

>  	static const struct regmap_config config =3D {
>  		.reg_bits =3D 8,
>  		.val_bits =3D 8,
> --=20
> 2.8.0.rc3
>=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 4/6] rtc: rv3029: Removes some checks and warnings
  2016-04-22 23:29     ` [rtc-linux] " Alexandre Belloni
@ 2016-04-22 23:31       ` Alexandre Belloni
  -1 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-04-22 23:31 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

On 23/04/2016 at 01:29:46 +0200, Alexandre Belloni wrote :
> Hi,
> 
> On 21/04/2016 at 20:24:17 +0200, Mylène Josserand wrote :
> > @@ -829,8 +829,6 @@ static void rv3029_unregister_driver(void)
> >  
> >  static int rv3049_probe(struct spi_device *spi)
> >  {
> > -	int res;
> > -	unsigned int tmp;
> 
> Well, you just introduced those variables in the previous patch.
> 

And I forgot to add that you still have a few checkpatch warnings to
remove while at it:

WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
#129: FILE: drivers/rtc/rtc-rv3029c2.c:129:
+			    unsigned len)

WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
#141: FILE: drivers/rtc/rtc-rv3029c2.c:141:
+			     unsigned len)


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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [rtc-linux] Re: [PATCH 4/6] rtc: rv3029: Removes some checks and warnings
@ 2016-04-22 23:31       ` Alexandre Belloni
  0 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-04-22 23:31 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

On 23/04/2016 at 01:29:46 +0200, Alexandre Belloni wrote :
> Hi,
>=20
> On 21/04/2016 at 20:24:17 +0200, Myl=C4=8Dne Josserand wrote :
> > @@ -829,8 +829,6 @@ static void rv3029_unregister_driver(void)
> > =20
> >  static int rv3049_probe(struct spi_device *spi)
> >  {
> > -	int res;
> > -	unsigned int tmp;
>=20
> Well, you just introduced those variables in the previous patch.
>=20

And I forgot to add that you still have a few checkpatch warnings to
remove while at it:

WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
#129: FILE: drivers/rtc/rtc-rv3029c2.c:129:
+			    unsigned len)

WARNING: Prefer 'unsigned int' to bare use of 'unsigned'
#141: FILE: drivers/rtc/rtc-rv3029c2.c:141:
+			     unsigned len)


--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 5/6] rtc: rv3029: enable AE_x bits on set_alarm
  2016-04-21 18:24   ` [rtc-linux] " Mylène Josserand
@ 2016-04-22 23:37     ` Alexandre Belloni
  -1 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-04-22 23:37 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

On 21/04/2016 at 20:24:18 +0200, Mylène Josserand wrote :
> The RTC RV3029 handles different types of alarms : seconds, minutes, ...
> These alarms can be enabled or disabled individually using an AE_x bit
> which is the last bit (BIT(7)) on each alarm registers.
> 
> To prepare the alarm IRQ support, the current code enables all the alarm
> types by setting each AE_x to 1.
> It also fixes month and weekday errors : it was performing -1 instead
> of +1.
> 
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/rtc/rtc-rv3029c2.c | 23 ++++++++++++++++-------
>  1 file changed, 16 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
> index a849005..42de1a3 100644
> --- a/drivers/rtc/rtc-rv3029c2.c
> +++ b/drivers/rtc/rtc-rv3029c2.c
> @@ -76,6 +76,7 @@
>  #define RV3029_A_DW			0x14
>  #define RV3029_A_MO			0x15
>  #define RV3029_A_YR			0x16
> +#define RV3029_A_AE_X			BIT(7)
>  #define RV3029_ALARM_SECTION_LEN	0x07
>  
>  /* timer section */
> @@ -436,14 +437,22 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
>  		dev_err(dev, "%s: reading SR failed\n", __func__);
>  		return -EIO;
>  	}
> -	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);
>  
> +	/* Activate all the alarms with AE_x bit */
> +	regs[RV3029_A_SC - RV3029_A_SC] = (bin2bcd(tm->tm_sec)) | RV3029_A_AE_X;
> +	regs[RV3029_A_MN - RV3029_A_SC] = (bin2bcd(tm->tm_min)) | RV3029_A_AE_X;
> +	regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour & 0x3f))
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday & 0x3f))
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd((tm->tm_mon & 0x1f) + 1))
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd((tm->tm_wday & 7) + 1))
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd((tm->tm_year) - 100))
> +		| RV3029_A_AE_X;
> +

Alarms probably never worked anyway because this still suffers form
another bug:
(bin2bcd(tm->tm_hour & 0x3f)) should be (bin2bcd(tm->tm_hour) & 0x3f),
and the same for the other members.

note that (bin2bcd((tm->tm_mon & 0x1f) + 1)) must be
(bin2bcd(tm->tm_mon + 1) & 0x1f)

etc...

> +	/* Write the alarm */
>  	ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
>  				RV3029_ALARM_SECTION_LEN);
>  	if (ret < 0)
> -- 
> 2.8.0.rc3
> 

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [rtc-linux] Re: [PATCH 5/6] rtc: rv3029: enable AE_x bits on set_alarm
@ 2016-04-22 23:37     ` Alexandre Belloni
  0 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-04-22 23:37 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

On 21/04/2016 at 20:24:18 +0200, Myl=C4=8Dne Josserand wrote :
> The RTC RV3029 handles different types of alarms : seconds, minutes, ...
> These alarms can be enabled or disabled individually using an AE_x bit
> which is the last bit (BIT(7)) on each alarm registers.
>=20
> To prepare the alarm IRQ support, the current code enables all the alarm
> types by setting each AE_x to 1.
> It also fixes month and weekday errors : it was performing -1 instead
> of +1.
>=20
> Signed-off-by: Myl=C4=8Dne Josserand <mylene.josserand@free-electrons.com=
>
> ---
>  drivers/rtc/rtc-rv3029c2.c | 23 ++++++++++++++++-------
>  1 file changed, 16 insertions(+), 7 deletions(-)
>=20
> diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
> index a849005..42de1a3 100644
> --- a/drivers/rtc/rtc-rv3029c2.c
> +++ b/drivers/rtc/rtc-rv3029c2.c
> @@ -76,6 +76,7 @@
>  #define RV3029_A_DW			0x14
>  #define RV3029_A_MO			0x15
>  #define RV3029_A_YR			0x16
> +#define RV3029_A_AE_X			BIT(7)
>  #define RV3029_ALARM_SECTION_LEN	0x07
> =20
>  /* timer section */
> @@ -436,14 +437,22 @@ static int rv3029_set_alarm(struct device *dev, str=
uct rtc_wkalrm *alarm)
>  		dev_err(dev, "%s: reading SR failed\n", __func__);
>  		return -EIO;
>  	}
> -	regs[RV3029_A_SC - RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
> -	regs[RV3029_A_MN - RV3029_A_SC] =3D bin2bcd(tm->tm_min & 0x7f);
> -	regs[RV3029_A_HR - RV3029_A_SC] =3D bin2bcd(tm->tm_hour & 0x3f);
> -	regs[RV3029_A_DT - RV3029_A_SC] =3D bin2bcd(tm->tm_mday & 0x3f);
> -	regs[RV3029_A_MO - RV3029_A_SC] =3D bin2bcd((tm->tm_mon & 0x1f) - 1);
> -	regs[RV3029_A_DW - RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
> -	regs[RV3029_A_YR - RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100)=
;
> =20
> +	/* Activate all the alarms with AE_x bit */
> +	regs[RV3029_A_SC - RV3029_A_SC] =3D (bin2bcd(tm->tm_sec)) | RV3029_A_AE=
_X;
> +	regs[RV3029_A_MN - RV3029_A_SC] =3D (bin2bcd(tm->tm_min)) | RV3029_A_AE=
_X;
> +	regs[RV3029_A_HR - RV3029_A_SC] =3D (bin2bcd(tm->tm_hour & 0x3f))
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_DT - RV3029_A_SC] =3D (bin2bcd(tm->tm_mday & 0x3f))
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_MO - RV3029_A_SC] =3D (bin2bcd((tm->tm_mon & 0x1f) + 1))
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_DW - RV3029_A_SC] =3D (bin2bcd((tm->tm_wday & 7) + 1))
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_YR - RV3029_A_SC] =3D (bin2bcd((tm->tm_year) - 100))
> +		| RV3029_A_AE_X;
> +

Alarms probably never worked anyway because this still suffers form
another bug:
(bin2bcd(tm->tm_hour & 0x3f)) should be (bin2bcd(tm->tm_hour) & 0x3f),
and the same for the other members.

note that (bin2bcd((tm->tm_mon & 0x1f) + 1)) must be
(bin2bcd(tm->tm_mon + 1) & 0x1f)

etc...

> +	/* Write the alarm */
>  	ret =3D rv3029_write_regs(dev, RV3029_A_SC, regs,
>  				RV3029_ALARM_SECTION_LEN);
>  	if (ret < 0)
> --=20
> 2.8.0.rc3
>=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 6/6] rtc: rv3029: add alarm IRQ
  2016-04-21 18:24   ` [rtc-linux] " Mylène Josserand
@ 2016-04-22 23:48     ` Alexandre Belloni
  -1 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-04-22 23:48 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

On 21/04/2016 at 20:24:19 +0200, Mylène Josserand wrote :
> @@ -731,11 +786,9 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
>  
>  #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
>  
> -static const struct rtc_class_ops rv3029_rtc_ops = {
> +static struct rtc_class_ops rv3029_rtc_ops = {
>  	.read_time	= rv3029_read_time,
>  	.set_time	= rv3029_set_time,
> -	.read_alarm	= rv3029_read_alarm,
> -	.set_alarm	= rv3029_set_alarm,
>  };
>  
>  static struct i2c_device_id rv3029_id[] = {
> @@ -772,8 +825,27 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
>  
>  	rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
>  					       THIS_MODULE);
> +	if (IS_ERR(rv3029->rtc)) {
> +		dev_err(dev, "unable to register the class device\n");
> +		return PTR_ERR(rv3029->rtc);
> +	}
>  
> -	return PTR_ERR_OR_ZERO(rv3029->rtc);
> +	if (rv3029->irq > 0) {
> +		rc = devm_request_threaded_irq(dev, rv3029->irq,
> +					       NULL, rv3029_handle_irq,
> +					       IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> +					       "rv3029", dev);
> +		if (rc) {
> +			dev_warn(dev, "unable to request IRQ, alarms disabled\n");
> +			rv3029->irq = 0;
> +		} else {
> +			rv3029_rtc_ops.read_alarm = rv3029_read_alarm;
> +			rv3029_rtc_ops.set_alarm = rv3029_set_alarm;
> +			rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable;
> +		}
> +	}
> +

While this work, devm_rtc_device_register() needs to know whether the
alarms are enabled and will try to call .read_alarm(). That is not
completely an issue right now and as we discussed, I'm planning to send
a rework of the rtc core to overcome that issue.

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [rtc-linux] Re: [PATCH 6/6] rtc: rv3029: add alarm IRQ
@ 2016-04-22 23:48     ` Alexandre Belloni
  0 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-04-22 23:48 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

On 21/04/2016 at 20:24:19 +0200, Myl=C4=8Dne Josserand wrote :
> @@ -731,11 +786,9 @@ static void rv3029_hwmon_register(struct device *dev=
, const char *name)
> =20
>  #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
> =20
> -static const struct rtc_class_ops rv3029_rtc_ops =3D {
> +static struct rtc_class_ops rv3029_rtc_ops =3D {
>  	.read_time	=3D rv3029_read_time,
>  	.set_time	=3D rv3029_set_time,
> -	.read_alarm	=3D rv3029_read_alarm,
> -	.set_alarm	=3D rv3029_set_alarm,
>  };
> =20
>  static struct i2c_device_id rv3029_id[] =3D {
> @@ -772,8 +825,27 @@ static int rv3029_probe(struct device *dev, struct r=
egmap *regmap, int irq,
> =20
>  	rv3029->rtc =3D devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
>  					       THIS_MODULE);
> +	if (IS_ERR(rv3029->rtc)) {
> +		dev_err(dev, "unable to register the class device\n");
> +		return PTR_ERR(rv3029->rtc);
> +	}
> =20
> -	return PTR_ERR_OR_ZERO(rv3029->rtc);
> +	if (rv3029->irq > 0) {
> +		rc =3D devm_request_threaded_irq(dev, rv3029->irq,
> +					       NULL, rv3029_handle_irq,
> +					       IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> +					       "rv3029", dev);
> +		if (rc) {
> +			dev_warn(dev, "unable to request IRQ, alarms disabled\n");
> +			rv3029->irq =3D 0;
> +		} else {
> +			rv3029_rtc_ops.read_alarm =3D rv3029_read_alarm;
> +			rv3029_rtc_ops.set_alarm =3D rv3029_set_alarm;
> +			rv3029_rtc_ops.alarm_irq_enable =3D rv3029_alarm_irq_enable;
> +		}
> +	}
> +

While this work, devm_rtc_device_register() needs to know whether the
alarms are enabled and will try to call .read_alarm(). That is not
completely an issue right now and as we discussed, I'm planning to send
a rework of the rtc core to overcome that issue.

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH V2 0/6] add support for Microcrystal RV-3049
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-28 22:00   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

The current patchset adds the support of the microcrystal RV-3049 (spi).
This RTC will use the same driver than RV-3029 by updating it to use regmap.
It also adds the alarm IRQ functionality.

V2 :
 - Add some checks removal from checkpatch
 - Fix the alarm support with a wrong use of bit mask on bin2bcd

Mylène Josserand (6):
  rtc: rv3029: remove 'i2c' in functions names
  rtc: rv3029: convert to use regmap
  rtc: rv3029: Add support of RV3049
  rtc: rv3029: Removes some checks and warnings
  rtc: rv3029: fix alarm support
  rtc: rv3029: add alarm IRQ

 drivers/rtc/Kconfig        |  37 +--
 drivers/rtc/rtc-rv3029c2.c | 582 +++++++++++++++++++++++++++++----------------
 2 files changed, 397 insertions(+), 222 deletions(-)

-- 
2.8.0.rc3

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH V2 0/6] add support for Microcrystal RV-3049
@ 2016-04-28 22:00   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

The current patchset adds the support of the microcrystal RV-3049 (spi).
This RTC will use the same driver than RV-3029 by updating it to use regmap=
.
It also adds the alarm IRQ functionality.

V2 :
 - Add some checks removal from checkpatch
 - Fix the alarm support with a wrong use of bit mask on bin2bcd

Myl=C3=A8ne Josserand (6):
  rtc: rv3029: remove 'i2c' in functions names
  rtc: rv3029: convert to use regmap
  rtc: rv3029: Add support of RV3049
  rtc: rv3029: Removes some checks and warnings
  rtc: rv3029: fix alarm support
  rtc: rv3029: add alarm IRQ

 drivers/rtc/Kconfig        |  37 +--
 drivers/rtc/rtc-rv3029c2.c | 582 +++++++++++++++++++++++++++++------------=
----
 2 files changed, 397 insertions(+), 222 deletions(-)

--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH V2 1/6] rtc: rv3029: remove 'i2c' in functions names
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-28 22:00   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

To prepare the use of regmap to add the support of RV-3049, all the
'i2c' in functions's names are removed.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 132 ++++++++++++++++++++-------------------------
 1 file changed, 57 insertions(+), 75 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index d0cbf08..091be48 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -116,9 +116,8 @@
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_SECTION_LEN		0x04
 
-static int
-rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
-		     unsigned len)
+static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+			    unsigned len)
 {
 	int ret;
 
@@ -134,9 +133,8 @@ rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
 	return 0;
 }
 
-static int
-rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
-		      unsigned len)
+static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
+			     unsigned len)
 {
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 		(reg + len > RV3029_USR1_RAM_PAGE + 8))
@@ -145,28 +143,27 @@ rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
 	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
 }
 
-static int
-rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set)
+static int rv3029_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);
+	ret = rv3029_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);
+	ret = rv3029_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)
+static int rv3029_get_sr(struct i2c_client *client, u8 *buf)
 {
-	int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
+	int ret = rv3029_read_regs(client, RV3029_STATUS, buf, 1);
 
 	if (ret < 0)
 		return -EIO;
@@ -174,14 +171,13 @@ rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
 	return 0;
 }
 
-static int
-rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
+static int rv3029_set_sr(struct i2c_client *client, u8 val)
 {
 	u8 buf[1];
 	int sr;
 
 	buf[0] = val;
-	sr = rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1);
+	sr = rv3029_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;
@@ -194,7 +190,7 @@ static int rv3029_eeprom_busywait(struct i2c_client *client)
 	u8 sr;
 
 	for (i = 100; i > 0; i--) {
-		ret = rv3029_i2c_get_sr(client, &sr);
+		ret = rv3029_get_sr(client, &sr);
 		if (ret < 0)
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -212,9 +208,9 @@ static int rv3029_eeprom_busywait(struct i2c_client *client)
 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);
+	return rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+				  RV3029_ONOFF_CTRL_EERE,
+				  RV3029_ONOFF_CTRL_EERE);
 }
 
 static int rv3029_eeprom_enter(struct i2c_client *client)
@@ -223,7 +219,7 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
 	u8 sr;
 
 	/* Check whether we are in the allowed voltage range. */
-	ret = rv3029_i2c_get_sr(client, &sr);
+	ret = rv3029_get_sr(client, &sr);
 	if (ret < 0)
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -232,11 +228,11 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
 		 */
 		sr &= ~RV3029_STATUS_VLOW1;
 		sr &= ~RV3029_STATUS_VLOW2;
-		ret = rv3029_i2c_set_sr(client, sr);
+		ret = rv3029_set_sr(client, sr);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
-		ret = rv3029_i2c_get_sr(client, &sr);
+		ret = rv3029_get_sr(client, &sr);
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -247,8 +243,8 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
 	}
 
 	/* Disable eeprom refresh. */
-	ret = rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
-				     RV3029_ONOFF_CTRL_EERE, 0);
+	ret = rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+				 RV3029_ONOFF_CTRL_EERE, 0);
 	if (ret < 0)
 		return ret;
 
@@ -269,7 +265,7 @@ static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
 	if (err < 0)
 		return err;
 
-	ret = rv3029_i2c_read_regs(client, reg, buf, len);
+	ret = rv3029_read_regs(client, reg, buf, len);
 
 	err = rv3029_eeprom_exit(client);
 	if (err < 0)
@@ -290,11 +286,11 @@ static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
 		return err;
 
 	for (i = 0; i < len; i++, reg++) {
-		ret = rv3029_i2c_read_regs(client, reg, &tmp, 1);
+		ret = rv3029_read_regs(client, reg, &tmp, 1);
 		if (ret < 0)
 			break;
 		if (tmp != buf[i]) {
-			ret = rv3029_i2c_write_regs(client, reg, &buf[i], 1);
+			ret = rv3029_write_regs(client, reg, &buf[i], 1);
 			if (ret < 0)
 				break;
 		}
@@ -328,21 +324,20 @@ static int rv3029_eeprom_update_bits(struct i2c_client *client,
 	return 0;
 }
 
-static int
-rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm)
 {
 	u8 buf[1];
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
-	ret = rv3029_i2c_get_sr(client, buf);
+	ret = rv3029_get_sr(client, buf);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029_i2c_read_regs(client, RV3029_W_SEC, regs,
-				   RV3029_WATCH_SECTION_LEN);
+	ret = rv3029_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__);
@@ -375,24 +370,24 @@ rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
 
 static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029_i2c_read_time(to_i2c_client(dev), tm);
+	return rv3029_read_time(to_i2c_client(dev), tm);
 }
 
-static int
-rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
+static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
 
-	ret = rv3029_i2c_get_sr(client, regs);
+	ret = rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029_i2c_read_regs(client, RV3029_A_SC, regs,
-				   RV3029_ALARM_SECTION_LEN);
+	ret = rv3029_read_regs(client, RV3029_A_SC, regs,
+			       RV3029_ALARM_SECTION_LEN);
 
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading alarm section failed\n",
@@ -411,21 +406,14 @@ rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
 	return 0;
 }
 
-static int
-rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-	return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm);
-}
-
-static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
-					int enable)
+static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable)
 {
 	int ret;
 
 	/* enable/disable AIE irq */
-	ret = rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
-				     RV3029_IRQ_CTRL_AIE,
-				     (enable ? RV3029_IRQ_CTRL_AIE : 0));
+	ret = rv3029_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 update INT reg\n");
 		return ret;
@@ -434,9 +422,9 @@ static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
 	return 0;
 }
 
-static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
-				    struct rtc_wkalrm *alarm)
+static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
@@ -449,7 +437,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	ret = rv3029_i2c_get_sr(client, regs);
+	ret = rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
@@ -462,28 +450,28 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
 	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);
+	ret = rv3029_write_regs(client, RV3029_A_SC, regs,
+				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
 	if (alarm->enabled) {
 		/* clear AF flag */
-		ret = rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
-					     RV3029_IRQ_FLAGS_AF, 0);
+		ret = rv3029_update_bits(client, RV3029_IRQ_FLAGS,
+					 RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
 			dev_err(&client->dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret = rv3029_rtc_i2c_alarm_set_irq(client, 1);
+		ret = rv3029_rtc_alarm_set_irq(client, 1);
 		if (ret)
 			return ret;
 
 		dev_dbg(&client->dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret = rv3029_rtc_i2c_alarm_set_irq(client, 0);
+		ret = rv3029_rtc_alarm_set_irq(client, 0);
 		if (ret)
 			return ret;
 
@@ -493,13 +481,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
 	return 0;
 }
 
-static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-	return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
-}
-
-static int
-rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
+static int rv3029_set_time(struct i2c_client *client, struct rtc_time const *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -520,18 +502,18 @@ rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 	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 = rv3029_i2c_write_regs(client, RV3029_W_SEC, regs,
-				    RV3029_WATCH_SECTION_LEN);
+	ret = rv3029_write_regs(client, RV3029_W_SEC, regs,
+				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
-	ret = rv3029_i2c_get_sr(client, regs);
+	ret = rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret = rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
+	ret = rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
@@ -542,7 +524,7 @@ rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
 
 static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029_i2c_set_time(to_i2c_client(dev), tm);
+	return rv3029_set_time(to_i2c_client(dev), tm);
 }
 
 static const struct rv3029_trickle_tab_elem {
@@ -646,7 +628,7 @@ static int rv3029_read_temp(struct i2c_client *client, int *temp_mC)
 	int ret;
 	u8 temp;
 
-	ret = rv3029_i2c_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
+	ret = rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
 	if (ret < 0)
 		return ret;
 
@@ -743,8 +725,8 @@ static void rv3029_hwmon_register(struct i2c_client *client)
 		&client->dev, client->name, client, rv3029_hwmon_groups);
 	if (IS_ERR(hwmon_dev)) {
 		dev_warn(&client->dev,
-			"unable to register hwmon device %ld\n",
-			PTR_ERR(hwmon_dev));
+			 "unable to register hwmon device %ld\n",
+			 PTR_ERR(hwmon_dev));
 	}
 }
 
@@ -780,7 +762,7 @@ static int rv3029_probe(struct i2c_client *client,
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
 		return -ENODEV;
 
-	rc = rv3029_i2c_get_sr(client, buf);
+	rc = rv3029_get_sr(client, buf);
 	if (rc < 0) {
 		dev_err(&client->dev, "reading status failed\n");
 		return rc;
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH V2 1/6] rtc: rv3029: remove 'i2c' in functions names
@ 2016-04-28 22:00   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

To prepare the use of regmap to add the support of RV-3049, all the
'i2c' in functions's names are removed.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 132 ++++++++++++++++++++---------------------=
----
 1 file changed, 57 insertions(+), 75 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index d0cbf08..091be48 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -116,9 +116,8 @@
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_SECTION_LEN		0x04
=20
-static int
-rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
-		     unsigned len)
+static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+			    unsigned len)
 {
 	int ret;
=20
@@ -134,9 +133,8 @@ rv3029_i2c_read_regs(struct i2c_client *client, u8 reg,=
 u8 *buf,
 	return 0;
 }
=20
-static int
-rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
-		      unsigned len)
+static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const b=
uf[],
+			     unsigned len)
 {
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 		(reg + len > RV3029_USR1_RAM_PAGE + 8))
@@ -145,28 +143,27 @@ rv3029_i2c_write_regs(struct i2c_client *client, u8 r=
eg, u8 const buf[],
 	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
 }
=20
-static int
-rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set)
+static int rv3029_update_bits(struct i2c_client *client, u8 reg, u8 mask,
+			      u8 set)
 {
 	u8 buf;
 	int ret;
=20
-	ret =3D rv3029_i2c_read_regs(client, reg, &buf, 1);
+	ret =3D rv3029_read_regs(client, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &=3D ~mask;
 	buf |=3D set & mask;
-	ret =3D rv3029_i2c_write_regs(client, reg, &buf, 1);
+	ret =3D rv3029_write_regs(client, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
=20
 	return 0;
 }
=20
-static int
-rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
+static int rv3029_get_sr(struct i2c_client *client, u8 *buf)
 {
-	int ret =3D rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
+	int ret =3D rv3029_read_regs(client, RV3029_STATUS, buf, 1);
=20
 	if (ret < 0)
 		return -EIO;
@@ -174,14 +171,13 @@ rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
 	return 0;
 }
=20
-static int
-rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
+static int rv3029_set_sr(struct i2c_client *client, u8 val)
 {
 	u8 buf[1];
 	int sr;
=20
 	buf[0] =3D val;
-	sr =3D rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1);
+	sr =3D rv3029_write_regs(client, RV3029_STATUS, buf, 1);
 	dev_dbg(&client->dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
 	if (sr < 0)
 		return -EIO;
@@ -194,7 +190,7 @@ static int rv3029_eeprom_busywait(struct i2c_client *cl=
ient)
 	u8 sr;
=20
 	for (i =3D 100; i > 0; i--) {
-		ret =3D rv3029_i2c_get_sr(client, &sr);
+		ret =3D rv3029_get_sr(client, &sr);
 		if (ret < 0)
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -212,9 +208,9 @@ static int rv3029_eeprom_busywait(struct i2c_client *cl=
ient)
 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);
+	return rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+				  RV3029_ONOFF_CTRL_EERE,
+				  RV3029_ONOFF_CTRL_EERE);
 }
=20
 static int rv3029_eeprom_enter(struct i2c_client *client)
@@ -223,7 +219,7 @@ static int rv3029_eeprom_enter(struct i2c_client *clien=
t)
 	u8 sr;
=20
 	/* Check whether we are in the allowed voltage range. */
-	ret =3D rv3029_i2c_get_sr(client, &sr);
+	ret =3D rv3029_get_sr(client, &sr);
 	if (ret < 0)
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -232,11 +228,11 @@ static int rv3029_eeprom_enter(struct i2c_client *cli=
ent)
 		 */
 		sr &=3D ~RV3029_STATUS_VLOW1;
 		sr &=3D ~RV3029_STATUS_VLOW2;
-		ret =3D rv3029_i2c_set_sr(client, sr);
+		ret =3D rv3029_set_sr(client, sr);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
-		ret =3D rv3029_i2c_get_sr(client, &sr);
+		ret =3D rv3029_get_sr(client, &sr);
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -247,8 +243,8 @@ static int rv3029_eeprom_enter(struct i2c_client *clien=
t)
 	}
=20
 	/* Disable eeprom refresh. */
-	ret =3D rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
-				     RV3029_ONOFF_CTRL_EERE, 0);
+	ret =3D rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+				 RV3029_ONOFF_CTRL_EERE, 0);
 	if (ret < 0)
 		return ret;
=20
@@ -269,7 +265,7 @@ static int rv3029_eeprom_read(struct i2c_client *client=
, u8 reg,
 	if (err < 0)
 		return err;
=20
-	ret =3D rv3029_i2c_read_regs(client, reg, buf, len);
+	ret =3D rv3029_read_regs(client, reg, buf, len);
=20
 	err =3D rv3029_eeprom_exit(client);
 	if (err < 0)
@@ -290,11 +286,11 @@ static int rv3029_eeprom_write(struct i2c_client *cli=
ent, u8 reg,
 		return err;
=20
 	for (i =3D 0; i < len; i++, reg++) {
-		ret =3D rv3029_i2c_read_regs(client, reg, &tmp, 1);
+		ret =3D rv3029_read_regs(client, reg, &tmp, 1);
 		if (ret < 0)
 			break;
 		if (tmp !=3D buf[i]) {
-			ret =3D rv3029_i2c_write_regs(client, reg, &buf[i], 1);
+			ret =3D rv3029_write_regs(client, reg, &buf[i], 1);
 			if (ret < 0)
 				break;
 		}
@@ -328,21 +324,20 @@ static int rv3029_eeprom_update_bits(struct i2c_clien=
t *client,
 	return 0;
 }
=20
-static int
-rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm=
)
 {
 	u8 buf[1];
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] =3D { 0, };
=20
-	ret =3D rv3029_i2c_get_sr(client, buf);
+	ret =3D rv3029_get_sr(client, buf);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
=20
-	ret =3D rv3029_i2c_read_regs(client, RV3029_W_SEC, regs,
-				   RV3029_WATCH_SECTION_LEN);
+	ret =3D rv3029_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__);
@@ -375,24 +370,24 @@ rv3029_i2c_read_time(struct i2c_client *client, struc=
t rtc_time *tm)
=20
 static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029_i2c_read_time(to_i2c_client(dev), tm);
+	return rv3029_read_time(to_i2c_client(dev), tm);
 }
=20
-static int
-rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
+static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *al=
arm)
 {
+	struct i2c_client *client =3D to_i2c_client(dev);
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
 	u8 regs[8];
=20
-	ret =3D rv3029_i2c_get_sr(client, regs);
+	ret =3D rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
=20
-	ret =3D rv3029_i2c_read_regs(client, RV3029_A_SC, regs,
-				   RV3029_ALARM_SECTION_LEN);
+	ret =3D rv3029_read_regs(client, RV3029_A_SC, regs,
+			       RV3029_ALARM_SECTION_LEN);
=20
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading alarm section failed\n",
@@ -411,21 +406,14 @@ rv3029_i2c_read_alarm(struct i2c_client *client, stru=
ct rtc_wkalrm *alarm)
 	return 0;
 }
=20
-static int
-rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
-{
-	return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm);
-}
-
-static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
-					int enable)
+static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable)
 {
 	int ret;
=20
 	/* enable/disable AIE irq */
-	ret =3D rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
-				     RV3029_IRQ_CTRL_AIE,
-				     (enable ? RV3029_IRQ_CTRL_AIE : 0));
+	ret =3D rv3029_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 update INT reg\n");
 		return ret;
@@ -434,9 +422,9 @@ static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_clie=
nt *client,
 	return 0;
 }
=20
-static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
-				    struct rtc_wkalrm *alarm)
+static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *ala=
rm)
 {
+	struct i2c_client *client =3D to_i2c_client(dev);
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
 	u8 regs[8];
@@ -449,7 +437,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *=
client,
 	if (tm->tm_year < 100)
 		return -EINVAL;
=20
-	ret =3D rv3029_i2c_get_sr(client, regs);
+	ret =3D rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
@@ -462,28 +450,28 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client=
 *client,
 	regs[RV3029_A_DW-RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
 	regs[RV3029_A_YR-RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
=20
-	ret =3D rv3029_i2c_write_regs(client, RV3029_A_SC, regs,
-				    RV3029_ALARM_SECTION_LEN);
+	ret =3D rv3029_write_regs(client, RV3029_A_SC, regs,
+				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
=20
 	if (alarm->enabled) {
 		/* clear AF flag */
-		ret =3D rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
-					     RV3029_IRQ_FLAGS_AF, 0);
+		ret =3D rv3029_update_bits(client, RV3029_IRQ_FLAGS,
+					 RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
 			dev_err(&client->dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret =3D rv3029_rtc_i2c_alarm_set_irq(client, 1);
+		ret =3D rv3029_rtc_alarm_set_irq(client, 1);
 		if (ret)
 			return ret;
=20
 		dev_dbg(&client->dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret =3D rv3029_rtc_i2c_alarm_set_irq(client, 0);
+		ret =3D rv3029_rtc_alarm_set_irq(client, 0);
 		if (ret)
 			return ret;
=20
@@ -493,13 +481,7 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client =
*client,
 	return 0;
 }
=20
-static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *ala=
rm)
-{
-	return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
-}
-
-static int
-rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
+static int rv3029_set_time(struct i2c_client *client, struct rtc_time cons=
t *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -520,18 +502,18 @@ rv3029_i2c_set_time(struct i2c_client *client, struct=
 rtc_time const *tm)
 	regs[RV3029_W_DAYS-RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7)+1);
 	regs[RV3029_W_YEARS-RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
=20
-	ret =3D rv3029_i2c_write_regs(client, RV3029_W_SEC, regs,
-				    RV3029_WATCH_SECTION_LEN);
+	ret =3D rv3029_write_regs(client, RV3029_W_SEC, regs,
+				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
=20
-	ret =3D rv3029_i2c_get_sr(client, regs);
+	ret =3D rv3029_get_sr(client, regs);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret =3D rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
+	ret =3D rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
 		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
 		return ret;
@@ -542,7 +524,7 @@ rv3029_i2c_set_time(struct i2c_client *client, struct r=
tc_time const *tm)
=20
 static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	return rv3029_i2c_set_time(to_i2c_client(dev), tm);
+	return rv3029_set_time(to_i2c_client(dev), tm);
 }
=20
 static const struct rv3029_trickle_tab_elem {
@@ -646,7 +628,7 @@ static int rv3029_read_temp(struct i2c_client *client, =
int *temp_mC)
 	int ret;
 	u8 temp;
=20
-	ret =3D rv3029_i2c_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
+	ret =3D rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
 	if (ret < 0)
 		return ret;
=20
@@ -743,8 +725,8 @@ static void rv3029_hwmon_register(struct i2c_client *cl=
ient)
 		&client->dev, client->name, client, rv3029_hwmon_groups);
 	if (IS_ERR(hwmon_dev)) {
 		dev_warn(&client->dev,
-			"unable to register hwmon device %ld\n",
-			PTR_ERR(hwmon_dev));
+			 "unable to register hwmon device %ld\n",
+			 PTR_ERR(hwmon_dev));
 	}
 }
=20
@@ -780,7 +762,7 @@ static int rv3029_probe(struct i2c_client *client,
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
 		return -ENODEV;
=20
-	rc =3D rv3029_i2c_get_sr(client, buf);
+	rc =3D rv3029_get_sr(client, buf);
 	if (rc < 0) {
 		dev_err(&client->dev, "reading status failed\n");
 		return rc;
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH V2 2/6] rtc: rv3029: convert to use regmap
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-28 22:00   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

To add support of rv3049, the current driver is converted to use regmap.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 275 +++++++++++++++++++++++----------------------
 1 file changed, 142 insertions(+), 133 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 091be48..96dd166 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -20,7 +20,7 @@
 #include <linux/of.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-
+#include <linux/regmap.h>
 
 /* Register map */
 /* control section */
@@ -116,81 +116,84 @@
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_SECTION_LEN		0x04
 
-static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+struct rv3029_data {
+	struct device		*dev;
+	struct rtc_device	*rtc;
+	struct regmap		*regmap;
+	int irq;
+};
+
+static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
 			    unsigned len)
 {
-	int ret;
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
 	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);
-	if (ret < 0)
-		return ret;
-	if (ret < len)
-		return -EIO;
-	return 0;
+	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
 }
 
-static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
+static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
 			     unsigned len)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+
 	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);
+	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
 }
 
-static int rv3029_update_bits(struct i2c_client *client, u8 reg, u8 mask,
-			      u8 set)
+static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
 {
 	u8 buf;
 	int ret;
 
-	ret = rv3029_read_regs(client, reg, &buf, 1);
+	ret = rv3029_read_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &= ~mask;
 	buf |= set & mask;
-	ret = rv3029_write_regs(client, reg, &buf, 1);
+	ret = rv3029_write_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 
 	return 0;
 }
 
-static int rv3029_get_sr(struct i2c_client *client, u8 *buf)
+static int rv3029_get_sr(struct device *dev, u8 *buf)
 {
-	int ret = rv3029_read_regs(client, RV3029_STATUS, buf, 1);
+	int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
 
 	if (ret < 0)
 		return -EIO;
-	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
+	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
 	return 0;
 }
 
-static int rv3029_set_sr(struct i2c_client *client, u8 val)
+static int rv3029_set_sr(struct device *dev, u8 val)
 {
 	u8 buf[1];
 	int sr;
 
 	buf[0] = val;
-	sr = rv3029_write_regs(client, RV3029_STATUS, buf, 1);
-	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
+	sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
+	dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
 	if (sr < 0)
 		return -EIO;
 	return 0;
 }
 
-static int rv3029_eeprom_busywait(struct i2c_client *client)
+static int rv3029_eeprom_busywait(struct device *dev)
 {
 	int i, ret;
 	u8 sr;
 
 	for (i = 100; i > 0; i--) {
-		ret = rv3029_get_sr(client, &sr);
+		ret = rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -198,28 +201,28 @@ static int rv3029_eeprom_busywait(struct i2c_client *client)
 		usleep_range(1000, 10000);
 	}
 	if (i <= 0) {
-		dev_err(&client->dev, "EEPROM busy wait timeout.\n");
+		dev_err(dev, "EEPROM busy wait timeout.\n");
 		return -ETIMEDOUT;
 	}
 
 	return ret;
 }
 
-static int rv3029_eeprom_exit(struct i2c_client *client)
+static int rv3029_eeprom_exit(struct device *dev)
 {
 	/* Re-enable eeprom refresh */
-	return rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+	return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
 				  RV3029_ONOFF_CTRL_EERE,
 				  RV3029_ONOFF_CTRL_EERE);
 }
 
-static int rv3029_eeprom_enter(struct i2c_client *client)
+static int rv3029_eeprom_enter(struct device *dev)
 {
 	int ret;
 	u8 sr;
 
 	/* Check whether we are in the allowed voltage range. */
-	ret = rv3029_get_sr(client, &sr);
+	ret = rv3029_get_sr(dev, &sr);
 	if (ret < 0)
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -228,119 +231,118 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
 		 */
 		sr &= ~RV3029_STATUS_VLOW1;
 		sr &= ~RV3029_STATUS_VLOW2;
-		ret = rv3029_set_sr(client, sr);
+		ret = rv3029_set_sr(dev, sr);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
-		ret = rv3029_get_sr(client, &sr);
+		ret = rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
-			dev_err(&client->dev,
+			dev_err(dev,
 				"Supply voltage is too low to safely access the EEPROM.\n");
 			return -ENODEV;
 		}
 	}
 
 	/* Disable eeprom refresh. */
-	ret = rv3029_update_bits(client, RV3029_ONOFF_CTRL,
-				 RV3029_ONOFF_CTRL_EERE, 0);
+	ret = rv3029_update_bits(dev, 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);
+	ret = rv3029_eeprom_busywait(dev);
 	if (ret < 0)
-		rv3029_eeprom_exit(client);
+		rv3029_eeprom_exit(dev);
 
 	return ret;
 }
 
-static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_read(struct device *dev, u8 reg,
 			      u8 buf[], size_t len)
 {
 	int ret, err;
 
-	err = rv3029_eeprom_enter(client);
+	err = rv3029_eeprom_enter(dev);
 	if (err < 0)
 		return err;
 
-	ret = rv3029_read_regs(client, reg, buf, len);
+	ret = rv3029_read_regs(dev, reg, buf, len);
 
-	err = rv3029_eeprom_exit(client);
+	err = rv3029_eeprom_exit(dev);
 	if (err < 0)
 		return err;
 
 	return ret;
 }
 
-static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_write(struct device *dev, u8 reg,
 			       u8 const buf[], size_t len)
 {
 	int ret, err;
 	size_t i;
 	u8 tmp;
 
-	err = rv3029_eeprom_enter(client);
+	err = rv3029_eeprom_enter(dev);
 	if (err < 0)
 		return err;
 
 	for (i = 0; i < len; i++, reg++) {
-		ret = rv3029_read_regs(client, reg, &tmp, 1);
+		ret = rv3029_read_regs(dev, reg, &tmp, 1);
 		if (ret < 0)
 			break;
 		if (tmp != buf[i]) {
-			ret = rv3029_write_regs(client, reg, &buf[i], 1);
+			ret = rv3029_write_regs(dev, reg, &buf[i], 1);
 			if (ret < 0)
 				break;
 		}
-		ret = rv3029_eeprom_busywait(client);
+		ret = rv3029_eeprom_busywait(dev);
 		if (ret < 0)
 			break;
 	}
 
-	err = rv3029_eeprom_exit(client);
+	err = rv3029_eeprom_exit(dev);
 	if (err < 0)
 		return err;
 
 	return ret;
 }
 
-static int rv3029_eeprom_update_bits(struct i2c_client *client,
+static int rv3029_eeprom_update_bits(struct device *dev,
 				     u8 reg, u8 mask, u8 set)
 {
 	u8 buf;
 	int ret;
 
-	ret = rv3029_eeprom_read(client, reg, &buf, 1);
+	ret = rv3029_eeprom_read(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &= ~mask;
 	buf |= set & mask;
-	ret = rv3029_eeprom_write(client, reg, &buf, 1);
+	ret = rv3029_eeprom_write(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 
 	return 0;
 }
 
-static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm)
+static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 buf[1];
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
-	ret = rv3029_get_sr(client, buf);
+	ret = rv3029_get_sr(dev, buf);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029_read_regs(client, RV3029_W_SEC, regs,
+	ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
 			       RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading RTC section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading RTC section failed\n", __func__);
 		return ret;
 	}
 
@@ -368,30 +370,23 @@ static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm)
 	return 0;
 }
 
-static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_read_time(to_i2c_client(dev), tm);
-}
-
-static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
 
-	ret = rv3029_get_sr(client, regs);
+	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 
-	ret = rv3029_read_regs(client, RV3029_A_SC, regs,
+	ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
 			       RV3029_ALARM_SECTION_LEN);
 
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading alarm section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading alarm section failed\n", __func__);
 		return ret;
 	}
 
@@ -406,25 +401,23 @@ static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	return 0;
 }
 
-static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable)
+static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable)
 {
 	int ret;
 
 	/* enable/disable AIE irq */
-	ret = rv3029_update_bits(client, RV3029_IRQ_CTRL,
-				 RV3029_IRQ_CTRL_AIE,
+	ret = rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE,
 				 (enable ? RV3029_IRQ_CTRL_AIE : 0));
 	if (ret < 0) {
-		dev_err(&client->dev, "can't update INT reg\n");
+		dev_err(dev, "can't update INT reg\n");
 		return ret;
 	}
 
 	return 0;
 }
 
-static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
 	u8 regs[8];
@@ -437,9 +430,9 @@ static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	ret = rv3029_get_sr(client, regs);
+	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 	regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
@@ -450,38 +443,38 @@ static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	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_write_regs(client, RV3029_A_SC, regs,
+	ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
 	if (alarm->enabled) {
 		/* clear AF flag */
-		ret = rv3029_update_bits(client, RV3029_IRQ_FLAGS,
+		ret = rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
 					 RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
-			dev_err(&client->dev, "can't clear alarm flag\n");
+			dev_err(dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret = rv3029_rtc_alarm_set_irq(client, 1);
+		ret = rv3029_rtc_alarm_set_irq(dev, 1);
 		if (ret)
 			return ret;
 
-		dev_dbg(&client->dev, "alarm IRQ armed\n");
+		dev_dbg(dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret = rv3029_rtc_alarm_set_irq(client, 0);
+		ret = rv3029_rtc_alarm_set_irq(dev, 0);
 		if (ret)
 			return ret;
 
-		dev_dbg(&client->dev, "alarm IRQ disabled\n");
+		dev_dbg(dev, "alarm IRQ disabled\n");
 	}
 
 	return 0;
 }
 
-static int rv3029_set_time(struct i2c_client *client, struct rtc_time const *tm)
+static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -502,31 +495,25 @@ static int rv3029_set_time(struct i2c_client *client, struct rtc_time const *tm)
 	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 = rv3029_write_regs(client, RV3029_W_SEC, regs,
+	ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
 				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
 
-	ret = rv3029_get_sr(client, regs);
+	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret = rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
+	ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 
 	return 0;
 }
-
-static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_set_time(to_i2c_client(dev), tm);
-}
-
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -584,9 +571,9 @@ static const struct rv3029_trickle_tab_elem {
 	},
 };
 
-static void rv3029_trickle_config(struct i2c_client *client)
+static void rv3029_trickle_config(struct device *dev)
 {
-	struct device_node *of_node = client->dev.of_node;
+	struct device_node *of_node = dev->of_node;
 	const struct rv3029_trickle_tab_elem *elem;
 	int i, err;
 	u32 ohms;
@@ -608,27 +595,26 @@ static void rv3029_trickle_config(struct i2c_client *client)
 				break;
 		}
 		trickle_set_bits = elem->conf;
-		dev_info(&client->dev,
+		dev_info(dev,
 			 "Trickle charger enabled at %d ohms resistance.\n",
 			 elem->r);
 	}
-	err = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
 	if (err < 0) {
-		dev_err(&client->dev,
-			"Failed to update trickle charger config\n");
+		dev_err(dev, "Failed to update trickle charger config\n");
 	}
 }
 
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
 
-static int rv3029_read_temp(struct i2c_client *client, int *temp_mC)
+static int rv3029_read_temp(struct device *dev, int *temp_mC)
 {
 	int ret;
 	u8 temp;
 
-	ret = rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
+	ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
 	if (ret < 0)
 		return ret;
 
@@ -641,10 +627,9 @@ static ssize_t rv3029_hwmon_show_temp(struct device *dev,
 				      struct device_attribute *attr,
 				      char *buf)
 {
-	struct i2c_client *client = dev_get_drvdata(dev);
 	int ret, temp_mC;
 
-	ret = rv3029_read_temp(client, &temp_mC);
+	ret = rv3029_read_temp(dev, &temp_mC);
 	if (ret < 0)
 		return ret;
 
@@ -656,7 +641,6 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
 						const char *buf,
 						size_t count)
 {
-	struct i2c_client *client = dev_get_drvdata(dev);
 	unsigned long interval_ms;
 	int ret;
 	u8 th_set_bits = 0;
@@ -670,7 +654,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
 		if (interval_ms >= 16000)
 			th_set_bits |= RV3029_EECTRL_THP;
 	}
-	ret = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_EECTRL_THE | RV3029_EECTRL_THP,
 					th_set_bits);
 	if (ret < 0)
@@ -683,11 +667,10 @@ static ssize_t rv3029_hwmon_show_update_interval(struct device *dev,
 						 struct device_attribute *attr,
 						 char *buf)
 {
-	struct i2c_client *client = dev_get_drvdata(dev);
 	int ret, interval_ms;
 	u8 eectrl;
 
-	ret = rv3029_eeprom_read(client, RV3029_CONTROL_E2P_EECTRL,
+	ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
 				 &eectrl, 1);
 	if (ret < 0)
 		return ret;
@@ -717,32 +700,32 @@ static struct attribute *rv3029_hwmon_attrs[] = {
 };
 ATTRIBUTE_GROUPS(rv3029_hwmon);
 
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 	struct device *hwmon_dev;
 
-	hwmon_dev = devm_hwmon_device_register_with_groups(
-		&client->dev, client->name, client, rv3029_hwmon_groups);
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, name, rv3029,
+							   rv3029_hwmon_groups);
 	if (IS_ERR(hwmon_dev)) {
-		dev_warn(&client->dev,
-			 "unable to register hwmon device %ld\n",
+		dev_warn(dev, "unable to register hwmon device %ld\n",
 			 PTR_ERR(hwmon_dev));
 	}
 }
 
 #else /* CONFIG_RTC_DRV_RV3029_HWMON */
 
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
 }
 
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
 
 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,
+	.read_time	= rv3029_read_time,
+	.set_time	= rv3029_set_time,
+	.read_alarm	= rv3029_read_alarm,
+	.set_alarm	= rv3029_set_alarm,
 };
 
 static struct i2c_device_id rv3029_id[] = {
@@ -752,41 +735,67 @@ static struct i2c_device_id rv3029_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, rv3029_id);
 
-static int rv3029_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
+			const char *name)
 {
-	struct rtc_device *rtc;
+	struct rv3029_data *rv3029;
 	int rc = 0;
 	u8 buf[1];
 
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
-		return -ENODEV;
+	rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
+	if (!rv3029)
+		return -ENOMEM;
+
+	rv3029->regmap = regmap;
+	rv3029->irq = irq;
+	rv3029->dev = dev;
+	dev_set_drvdata(dev, rv3029);
 
-	rc = rv3029_get_sr(client, buf);
+	rc = rv3029_get_sr(dev, buf);
 	if (rc < 0) {
-		dev_err(&client->dev, "reading status failed\n");
+		dev_err(dev, "reading status failed\n");
 		return rc;
 	}
 
-	rv3029_trickle_config(client);
-	rv3029_hwmon_register(client);
+	rv3029_trickle_config(dev);
+	rv3029_hwmon_register(dev, name);
+
+	rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
+					       THIS_MODULE);
 
-	rtc = devm_rtc_device_register(&client->dev, client->name,
-				       &rv3029_rtc_ops, THIS_MODULE);
+	return PTR_ERR_OR_ZERO(rv3029->rtc);
+}
 
-	if (IS_ERR(rtc))
-		return PTR_ERR(rtc);
+static int rv3029_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	static const struct regmap_config config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+	};
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
+				     I2C_FUNC_SMBUS_BYTE)) {
+		dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n");
+		return -ENODEV;
+	}
 
-	i2c_set_clientdata(client, rtc);
+	regmap = devm_regmap_init_i2c(client, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
 
-	return 0;
+	return rv3029_probe(&client->dev, regmap, client->irq, client->name);
 }
 
 static struct i2c_driver rv3029_driver = {
 	.driver = {
 		.name = "rtc-rv3029c2",
 	},
-	.probe		= rv3029_probe,
+	.probe		= rv3029_i2c_probe,
 	.id_table	= rv3029_id,
 };
 
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH V2 2/6] rtc: rv3029: convert to use regmap
@ 2016-04-28 22:00   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

To add support of rv3049, the current driver is converted to use regmap.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 275 +++++++++++++++++++++++------------------=
----
 1 file changed, 142 insertions(+), 133 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 091be48..96dd166 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -20,7 +20,7 @@
 #include <linux/of.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-
+#include <linux/regmap.h>
=20
 /* Register map */
 /* control section */
@@ -116,81 +116,84 @@
 #define RV3029_USR2_RAM_PAGE		0x3C
 #define RV3029_USR2_SECTION_LEN		0x04
=20
-static int rv3029_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+struct rv3029_data {
+	struct device		*dev;
+	struct rtc_device	*rtc;
+	struct regmap		*regmap;
+	int irq;
+};
+
+static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
 			    unsigned len)
 {
-	int ret;
+	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
=20
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 		(reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
=20
-	ret =3D i2c_smbus_read_i2c_block_data(client, reg, len, buf);
-	if (ret < 0)
-		return ret;
-	if (ret < len)
-		return -EIO;
-	return 0;
+	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
 }
=20
-static int rv3029_write_regs(struct i2c_client *client, u8 reg, u8 const b=
uf[],
+static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
 			     unsigned len)
 {
+	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
+
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
 		(reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
=20
-	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
+	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
 }
=20
-static int rv3029_update_bits(struct i2c_client *client, u8 reg, u8 mask,
-			      u8 set)
+static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
 {
 	u8 buf;
 	int ret;
=20
-	ret =3D rv3029_read_regs(client, reg, &buf, 1);
+	ret =3D rv3029_read_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &=3D ~mask;
 	buf |=3D set & mask;
-	ret =3D rv3029_write_regs(client, reg, &buf, 1);
+	ret =3D rv3029_write_regs(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
=20
 	return 0;
 }
=20
-static int rv3029_get_sr(struct i2c_client *client, u8 *buf)
+static int rv3029_get_sr(struct device *dev, u8 *buf)
 {
-	int ret =3D rv3029_read_regs(client, RV3029_STATUS, buf, 1);
+	int ret =3D rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
=20
 	if (ret < 0)
 		return -EIO;
-	dev_dbg(&client->dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
+	dev_dbg(dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
 	return 0;
 }
=20
-static int rv3029_set_sr(struct i2c_client *client, u8 val)
+static int rv3029_set_sr(struct device *dev, u8 val)
 {
 	u8 buf[1];
 	int sr;
=20
 	buf[0] =3D val;
-	sr =3D rv3029_write_regs(client, RV3029_STATUS, buf, 1);
-	dev_dbg(&client->dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
+	sr =3D rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
+	dev_dbg(dev, "status =3D 0x%.2x (%d)\n", buf[0], buf[0]);
 	if (sr < 0)
 		return -EIO;
 	return 0;
 }
=20
-static int rv3029_eeprom_busywait(struct i2c_client *client)
+static int rv3029_eeprom_busywait(struct device *dev)
 {
 	int i, ret;
 	u8 sr;
=20
 	for (i =3D 100; i > 0; i--) {
-		ret =3D rv3029_get_sr(client, &sr);
+		ret =3D rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 			break;
 		if (!(sr & RV3029_STATUS_EEBUSY))
@@ -198,28 +201,28 @@ static int rv3029_eeprom_busywait(struct i2c_client *=
client)
 		usleep_range(1000, 10000);
 	}
 	if (i <=3D 0) {
-		dev_err(&client->dev, "EEPROM busy wait timeout.\n");
+		dev_err(dev, "EEPROM busy wait timeout.\n");
 		return -ETIMEDOUT;
 	}
=20
 	return ret;
 }
=20
-static int rv3029_eeprom_exit(struct i2c_client *client)
+static int rv3029_eeprom_exit(struct device *dev)
 {
 	/* Re-enable eeprom refresh */
-	return rv3029_update_bits(client, RV3029_ONOFF_CTRL,
+	return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
 				  RV3029_ONOFF_CTRL_EERE,
 				  RV3029_ONOFF_CTRL_EERE);
 }
=20
-static int rv3029_eeprom_enter(struct i2c_client *client)
+static int rv3029_eeprom_enter(struct device *dev)
 {
 	int ret;
 	u8 sr;
=20
 	/* Check whether we are in the allowed voltage range. */
-	ret =3D rv3029_get_sr(client, &sr);
+	ret =3D rv3029_get_sr(dev, &sr);
 	if (ret < 0)
 		return ret;
 	if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@@ -228,119 +231,118 @@ static int rv3029_eeprom_enter(struct i2c_client *c=
lient)
 		 */
 		sr &=3D ~RV3029_STATUS_VLOW1;
 		sr &=3D ~RV3029_STATUS_VLOW2;
-		ret =3D rv3029_set_sr(client, sr);
+		ret =3D rv3029_set_sr(dev, sr);
 		if (ret < 0)
 			return ret;
 		usleep_range(1000, 10000);
-		ret =3D rv3029_get_sr(client, &sr);
+		ret =3D rv3029_get_sr(dev, &sr);
 		if (ret < 0)
 			return ret;
 		if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
-			dev_err(&client->dev,
+			dev_err(dev,
 				"Supply voltage is too low to safely access the EEPROM.\n");
 			return -ENODEV;
 		}
 	}
=20
 	/* Disable eeprom refresh. */
-	ret =3D rv3029_update_bits(client, RV3029_ONOFF_CTRL,
-				 RV3029_ONOFF_CTRL_EERE, 0);
+	ret =3D rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE=
,
+				 0);
 	if (ret < 0)
 		return ret;
=20
 	/* Wait for any previous eeprom accesses to finish. */
-	ret =3D rv3029_eeprom_busywait(client);
+	ret =3D rv3029_eeprom_busywait(dev);
 	if (ret < 0)
-		rv3029_eeprom_exit(client);
+		rv3029_eeprom_exit(dev);
=20
 	return ret;
 }
=20
-static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_read(struct device *dev, u8 reg,
 			      u8 buf[], size_t len)
 {
 	int ret, err;
=20
-	err =3D rv3029_eeprom_enter(client);
+	err =3D rv3029_eeprom_enter(dev);
 	if (err < 0)
 		return err;
=20
-	ret =3D rv3029_read_regs(client, reg, buf, len);
+	ret =3D rv3029_read_regs(dev, reg, buf, len);
=20
-	err =3D rv3029_eeprom_exit(client);
+	err =3D rv3029_eeprom_exit(dev);
 	if (err < 0)
 		return err;
=20
 	return ret;
 }
=20
-static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
+static int rv3029_eeprom_write(struct device *dev, u8 reg,
 			       u8 const buf[], size_t len)
 {
 	int ret, err;
 	size_t i;
 	u8 tmp;
=20
-	err =3D rv3029_eeprom_enter(client);
+	err =3D rv3029_eeprom_enter(dev);
 	if (err < 0)
 		return err;
=20
 	for (i =3D 0; i < len; i++, reg++) {
-		ret =3D rv3029_read_regs(client, reg, &tmp, 1);
+		ret =3D rv3029_read_regs(dev, reg, &tmp, 1);
 		if (ret < 0)
 			break;
 		if (tmp !=3D buf[i]) {
-			ret =3D rv3029_write_regs(client, reg, &buf[i], 1);
+			ret =3D rv3029_write_regs(dev, reg, &buf[i], 1);
 			if (ret < 0)
 				break;
 		}
-		ret =3D rv3029_eeprom_busywait(client);
+		ret =3D rv3029_eeprom_busywait(dev);
 		if (ret < 0)
 			break;
 	}
=20
-	err =3D rv3029_eeprom_exit(client);
+	err =3D rv3029_eeprom_exit(dev);
 	if (err < 0)
 		return err;
=20
 	return ret;
 }
=20
-static int rv3029_eeprom_update_bits(struct i2c_client *client,
+static int rv3029_eeprom_update_bits(struct device *dev,
 				     u8 reg, u8 mask, u8 set)
 {
 	u8 buf;
 	int ret;
=20
-	ret =3D rv3029_eeprom_read(client, reg, &buf, 1);
+	ret =3D rv3029_eeprom_read(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
 	buf &=3D ~mask;
 	buf |=3D set & mask;
-	ret =3D rv3029_eeprom_write(client, reg, &buf, 1);
+	ret =3D rv3029_eeprom_write(dev, reg, &buf, 1);
 	if (ret < 0)
 		return ret;
=20
 	return 0;
 }
=20
-static int rv3029_read_time(struct i2c_client *client, struct rtc_time *tm=
)
+static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 buf[1];
 	int ret;
 	u8 regs[RV3029_WATCH_SECTION_LEN] =3D { 0, };
=20
-	ret =3D rv3029_get_sr(client, buf);
+	ret =3D rv3029_get_sr(dev, buf);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
=20
-	ret =3D rv3029_read_regs(client, RV3029_W_SEC, regs,
+	ret =3D rv3029_read_regs(dev, RV3029_W_SEC, regs,
 			       RV3029_WATCH_SECTION_LEN);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading RTC section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading RTC section failed\n", __func__);
 		return ret;
 	}
=20
@@ -368,30 +370,23 @@ static int rv3029_read_time(struct i2c_client *client=
, struct rtc_time *tm)
 	return 0;
 }
=20
-static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_read_time(to_i2c_client(dev), tm);
-}
-
-static int rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *al=
arm)
+static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	struct i2c_client *client =3D to_i2c_client(dev);
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
 	u8 regs[8];
=20
-	ret =3D rv3029_get_sr(client, regs);
+	ret =3D rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
=20
-	ret =3D rv3029_read_regs(client, RV3029_A_SC, regs,
+	ret =3D rv3029_read_regs(dev, RV3029_A_SC, regs,
 			       RV3029_ALARM_SECTION_LEN);
=20
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading alarm section failed\n",
-			__func__);
+		dev_err(dev, "%s: reading alarm section failed\n", __func__);
 		return ret;
 	}
=20
@@ -406,25 +401,23 @@ static int rv3029_rtc_read_alarm(struct device *dev, =
struct rtc_wkalrm *alarm)
 	return 0;
 }
=20
-static int rv3029_rtc_alarm_set_irq(struct i2c_client *client, int enable)
+static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable)
 {
 	int ret;
=20
 	/* enable/disable AIE irq */
-	ret =3D rv3029_update_bits(client, RV3029_IRQ_CTRL,
-				 RV3029_IRQ_CTRL_AIE,
+	ret =3D rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE,
 				 (enable ? RV3029_IRQ_CTRL_AIE : 0));
 	if (ret < 0) {
-		dev_err(&client->dev, "can't update INT reg\n");
+		dev_err(dev, "can't update INT reg\n");
 		return ret;
 	}
=20
 	return 0;
 }
=20
-static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *ala=
rm)
+static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	struct i2c_client *client =3D to_i2c_client(dev);
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
 	u8 regs[8];
@@ -437,9 +430,9 @@ static int rv3029_rtc_set_alarm(struct device *dev, str=
uct rtc_wkalrm *alarm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
=20
-	ret =3D rv3029_get_sr(client, regs);
+	ret =3D rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
 	regs[RV3029_A_SC-RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
@@ -450,38 +443,38 @@ static int rv3029_rtc_set_alarm(struct device *dev, s=
truct rtc_wkalrm *alarm)
 	regs[RV3029_A_DW-RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
 	regs[RV3029_A_YR-RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
=20
-	ret =3D rv3029_write_regs(client, RV3029_A_SC, regs,
+	ret =3D rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
 		return ret;
=20
 	if (alarm->enabled) {
 		/* clear AF flag */
-		ret =3D rv3029_update_bits(client, RV3029_IRQ_FLAGS,
+		ret =3D rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
 					 RV3029_IRQ_FLAGS_AF, 0);
 		if (ret < 0) {
-			dev_err(&client->dev, "can't clear alarm flag\n");
+			dev_err(dev, "can't clear alarm flag\n");
 			return ret;
 		}
 		/* enable AIE irq */
-		ret =3D rv3029_rtc_alarm_set_irq(client, 1);
+		ret =3D rv3029_rtc_alarm_set_irq(dev, 1);
 		if (ret)
 			return ret;
=20
-		dev_dbg(&client->dev, "alarm IRQ armed\n");
+		dev_dbg(dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret =3D rv3029_rtc_alarm_set_irq(client, 0);
+		ret =3D rv3029_rtc_alarm_set_irq(dev, 0);
 		if (ret)
 			return ret;
=20
-		dev_dbg(&client->dev, "alarm IRQ disabled\n");
+		dev_dbg(dev, "alarm IRQ disabled\n");
 	}
=20
 	return 0;
 }
=20
-static int rv3029_set_time(struct i2c_client *client, struct rtc_time cons=
t *tm)
+static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 regs[8];
 	int ret;
@@ -502,31 +495,25 @@ static int rv3029_set_time(struct i2c_client *client,=
 struct rtc_time const *tm)
 	regs[RV3029_W_DAYS-RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7)+1);
 	regs[RV3029_W_YEARS-RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
=20
-	ret =3D rv3029_write_regs(client, RV3029_W_SEC, regs,
+	ret =3D rv3029_write_regs(dev, RV3029_W_SEC, regs,
 				RV3029_WATCH_SECTION_LEN);
 	if (ret < 0)
 		return ret;
=20
-	ret =3D rv3029_get_sr(client, regs);
+	ret =3D rv3029_get_sr(dev, regs);
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
 	/* clear PON bit */
-	ret =3D rv3029_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
+	ret =3D rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
 	if (ret < 0) {
-		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return ret;
 	}
=20
 	return 0;
 }
-
-static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	return rv3029_set_time(to_i2c_client(dev), tm);
-}
-
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -584,9 +571,9 @@ static const struct rv3029_trickle_tab_elem {
 	},
 };
=20
-static void rv3029_trickle_config(struct i2c_client *client)
+static void rv3029_trickle_config(struct device *dev)
 {
-	struct device_node *of_node =3D client->dev.of_node;
+	struct device_node *of_node =3D dev->of_node;
 	const struct rv3029_trickle_tab_elem *elem;
 	int i, err;
 	u32 ohms;
@@ -608,27 +595,26 @@ static void rv3029_trickle_config(struct i2c_client *=
client)
 				break;
 		}
 		trickle_set_bits =3D elem->conf;
-		dev_info(&client->dev,
+		dev_info(dev,
 			 "Trickle charger enabled at %d ohms resistance.\n",
 			 elem->r);
 	}
-	err =3D rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	err =3D rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
 	if (err < 0) {
-		dev_err(&client->dev,
-			"Failed to update trickle charger config\n");
+		dev_err(dev, "Failed to update trickle charger config\n");
 	}
 }
=20
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
=20
-static int rv3029_read_temp(struct i2c_client *client, int *temp_mC)
+static int rv3029_read_temp(struct device *dev, int *temp_mC)
 {
 	int ret;
 	u8 temp;
=20
-	ret =3D rv3029_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
+	ret =3D rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
 	if (ret < 0)
 		return ret;
=20
@@ -641,10 +627,9 @@ static ssize_t rv3029_hwmon_show_temp(struct device *d=
ev,
 				      struct device_attribute *attr,
 				      char *buf)
 {
-	struct i2c_client *client =3D dev_get_drvdata(dev);
 	int ret, temp_mC;
=20
-	ret =3D rv3029_read_temp(client, &temp_mC);
+	ret =3D rv3029_read_temp(dev, &temp_mC);
 	if (ret < 0)
 		return ret;
=20
@@ -656,7 +641,6 @@ static ssize_t rv3029_hwmon_set_update_interval(struct =
device *dev,
 						const char *buf,
 						size_t count)
 {
-	struct i2c_client *client =3D dev_get_drvdata(dev);
 	unsigned long interval_ms;
 	int ret;
 	u8 th_set_bits =3D 0;
@@ -670,7 +654,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct =
device *dev,
 		if (interval_ms >=3D 16000)
 			th_set_bits |=3D RV3029_EECTRL_THP;
 	}
-	ret =3D rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
+	ret =3D rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_EECTRL_THE | RV3029_EECTRL_THP,
 					th_set_bits);
 	if (ret < 0)
@@ -683,11 +667,10 @@ static ssize_t rv3029_hwmon_show_update_interval(stru=
ct device *dev,
 						 struct device_attribute *attr,
 						 char *buf)
 {
-	struct i2c_client *client =3D dev_get_drvdata(dev);
 	int ret, interval_ms;
 	u8 eectrl;
=20
-	ret =3D rv3029_eeprom_read(client, RV3029_CONTROL_E2P_EECTRL,
+	ret =3D rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
 				 &eectrl, 1);
 	if (ret < 0)
 		return ret;
@@ -717,32 +700,32 @@ static struct attribute *rv3029_hwmon_attrs[] =3D {
 };
 ATTRIBUTE_GROUPS(rv3029_hwmon);
=20
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
+	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
 	struct device *hwmon_dev;
=20
-	hwmon_dev =3D devm_hwmon_device_register_with_groups(
-		&client->dev, client->name, client, rv3029_hwmon_groups);
+	hwmon_dev =3D devm_hwmon_device_register_with_groups(dev, name, rv3029,
+							   rv3029_hwmon_groups);
 	if (IS_ERR(hwmon_dev)) {
-		dev_warn(&client->dev,
-			 "unable to register hwmon device %ld\n",
+		dev_warn(dev, "unable to register hwmon device %ld\n",
 			 PTR_ERR(hwmon_dev));
 	}
 }
=20
 #else /* CONFIG_RTC_DRV_RV3029_HWMON */
=20
-static void rv3029_hwmon_register(struct i2c_client *client)
+static void rv3029_hwmon_register(struct device *dev, const char *name)
 {
 }
=20
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
=20
 static const struct rtc_class_ops rv3029_rtc_ops =3D {
-	.read_time	=3D rv3029_rtc_read_time,
-	.set_time	=3D rv3029_rtc_set_time,
-	.read_alarm	=3D rv3029_rtc_read_alarm,
-	.set_alarm	=3D rv3029_rtc_set_alarm,
+	.read_time	=3D rv3029_read_time,
+	.set_time	=3D rv3029_set_time,
+	.read_alarm	=3D rv3029_read_alarm,
+	.set_alarm	=3D rv3029_set_alarm,
 };
=20
 static struct i2c_device_id rv3029_id[] =3D {
@@ -752,41 +735,67 @@ static struct i2c_device_id rv3029_id[] =3D {
 };
 MODULE_DEVICE_TABLE(i2c, rv3029_id);
=20
-static int rv3029_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq=
,
+			const char *name)
 {
-	struct rtc_device *rtc;
+	struct rv3029_data *rv3029;
 	int rc =3D 0;
 	u8 buf[1];
=20
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
-		return -ENODEV;
+	rv3029 =3D devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
+	if (!rv3029)
+		return -ENOMEM;
+
+	rv3029->regmap =3D regmap;
+	rv3029->irq =3D irq;
+	rv3029->dev =3D dev;
+	dev_set_drvdata(dev, rv3029);
=20
-	rc =3D rv3029_get_sr(client, buf);
+	rc =3D rv3029_get_sr(dev, buf);
 	if (rc < 0) {
-		dev_err(&client->dev, "reading status failed\n");
+		dev_err(dev, "reading status failed\n");
 		return rc;
 	}
=20
-	rv3029_trickle_config(client);
-	rv3029_hwmon_register(client);
+	rv3029_trickle_config(dev);
+	rv3029_hwmon_register(dev, name);
+
+	rv3029->rtc =3D devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
+					       THIS_MODULE);
=20
-	rtc =3D devm_rtc_device_register(&client->dev, client->name,
-				       &rv3029_rtc_ops, THIS_MODULE);
+	return PTR_ERR_OR_ZERO(rv3029->rtc);
+}
=20
-	if (IS_ERR(rtc))
-		return PTR_ERR(rtc);
+static int rv3029_i2c_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	static const struct regmap_config config =3D {
+		.reg_bits =3D 8,
+		.val_bits =3D 8,
+	};
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
+				     I2C_FUNC_SMBUS_BYTE)) {
+		dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS=
_I2C_BYTE\n");
+		return -ENODEV;
+	}
=20
-	i2c_set_clientdata(client, rtc);
+	regmap =3D devm_regmap_init_i2c(client, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
=20
-	return 0;
+	return rv3029_probe(&client->dev, regmap, client->irq, client->name);
 }
=20
 static struct i2c_driver rv3029_driver =3D {
 	.driver =3D {
 		.name =3D "rtc-rv3029c2",
 	},
-	.probe		=3D rv3029_probe,
+	.probe		=3D rv3029_i2c_probe,
 	.id_table	=3D rv3029_id,
 };
=20
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH V2 3/6] rtc: rv3029: Add support of RV3049
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-28 22:00   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Add support of Microcrystal RV3049 RTC (SPI) using regmap on the
RV3029 (I2C) driver.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/Kconfig        |  37 ++++++++--------
 drivers/rtc/rtc-rv3029c2.c | 108 +++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 124 insertions(+), 21 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index f1e1f50..18639e0 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -573,24 +573,6 @@ config RTC_DRV_EM3027
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-em3027.
 
-config RTC_DRV_RV3029C2
-	tristate "Micro Crystal RV3029"
-	help
-	  If you say yes here you get support for the Micro Crystal
-	  RV3029 RTC chips.
-
-	  This driver can also be built as a module. If so, the module
-	  will be called rtc-rv3029c2.
-
-config RTC_DRV_RV3029_HWMON
-	bool "HWMON support for RV3029"
-	depends on RTC_DRV_RV3029C2 && HWMON
-	depends on !(RTC_DRV_RV3029C2=y && HWMON=m)
-	default y
-	help
-	  Say Y here if you want to expose temperature sensor data on
-	  rtc-rv3029.
-
 config RTC_DRV_RV8803
 	tristate "Micro Crystal RV8803"
 	help
@@ -786,6 +768,25 @@ config RTC_DRV_PCF2127
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-pcf2127.
 
+config RTC_DRV_RV3029C2
+	tristate "Micro Crystal RV3029/3049"
+	depends on RTC_I2C_AND_SPI
+	help
+	  If you say yes here you get support for the Micro Crystal
+	  RV3029 and RV3049 RTC chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-rv3029c2.
+
+config RTC_DRV_RV3029_HWMON
+	bool "HWMON support for RV3029/3049"
+	depends on RTC_DRV_RV3029C2 && HWMON
+	depends on !(RTC_DRV_RV3029C2=y && HWMON=m)
+	default y
+	help
+	  Say Y here if you want to expose temperature sensor data on
+	  rtc-rv3029.
+
 comment "Platform RTC drivers"
 
 # this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 96dd166..1310646 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -1,5 +1,5 @@
 /*
- * Micro Crystal RV-3029 rtc class driver
+ * Micro Crystal RV-3029 / RV-3049 rtc class driver
  *
  * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
  *         Michael Buesch <m@bues.ch>
@@ -14,6 +14,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/spi/spi.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
@@ -766,6 +767,8 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 	return PTR_ERR_OR_ZERO(rv3029->rtc);
 }
 
+#if IS_ENABLED(CONFIG_I2C)
+
 static int rv3029_i2c_probe(struct i2c_client *client,
 			    const struct i2c_device_id *id)
 {
@@ -799,9 +802,108 @@ static struct i2c_driver rv3029_driver = {
 	.id_table	= rv3029_id,
 };
 
-module_i2c_driver(rv3029_driver);
+static int rv3029_register_driver(void)
+{
+	return i2c_add_driver(&rv3029_driver);
+}
+
+static void rv3029_unregister_driver(void)
+{
+	i2c_del_driver(&rv3029_driver);
+}
+
+#else
+
+static int rv3029_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3029_unregister_driver(void)
+{
+}
+
+#endif
+
+#if IS_ENABLED(CONFIG_SPI_MASTER)
+
+static int rv3049_probe(struct spi_device *spi)
+{
+	static const struct regmap_config config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+	};
+	struct regmap *regmap;
+
+	regmap = devm_regmap_init_spi(spi, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
+
+	return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
+}
+
+static struct spi_driver rv3049_driver = {
+	.driver = {
+		.name    = "rv3049",
+	},
+	.probe   = rv3049_probe,
+};
+
+static int rv3049_register_driver(void)
+{
+	return spi_register_driver(&rv3049_driver);
+}
+
+static void rv3049_unregister_driver(void)
+{
+	spi_unregister_driver(&rv3049_driver);
+}
+
+#else
+
+static int rv3049_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3049_unregister_driver(void)
+{
+}
+
+#endif
+
+static int __init rv30x9_init(void)
+{
+	int ret;
+
+	ret = rv3029_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3029 driver: %d\n", ret);
+		return ret;
+	}
+
+	ret = rv3049_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3049 driver: %d\n", ret);
+		rv3029_unregister_driver();
+	}
+
+	return ret;
+}
+module_init(rv30x9_init)
+
+static void __exit rv30x9_exit(void)
+{
+	rv3049_unregister_driver();
+	rv3029_unregister_driver();
+}
+module_exit(rv30x9_exit)
 
 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
 MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
-MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
+MODULE_DESCRIPTION("Micro Crystal RV3029/RV3049 RTC driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:rv3049");
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH V2 3/6] rtc: rv3029: Add support of RV3049
@ 2016-04-28 22:00   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Add support of Microcrystal RV3049 RTC (SPI) using regmap on the
RV3029 (I2C) driver.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/Kconfig        |  37 ++++++++--------
 drivers/rtc/rtc-rv3029c2.c | 108 +++++++++++++++++++++++++++++++++++++++++=
++--
 2 files changed, 124 insertions(+), 21 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index f1e1f50..18639e0 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -573,24 +573,6 @@ config RTC_DRV_EM3027
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-em3027.
=20
-config RTC_DRV_RV3029C2
-	tristate "Micro Crystal RV3029"
-	help
-	  If you say yes here you get support for the Micro Crystal
-	  RV3029 RTC chips.
-
-	  This driver can also be built as a module. If so, the module
-	  will be called rtc-rv3029c2.
-
-config RTC_DRV_RV3029_HWMON
-	bool "HWMON support for RV3029"
-	depends on RTC_DRV_RV3029C2 && HWMON
-	depends on !(RTC_DRV_RV3029C2=3Dy && HWMON=3Dm)
-	default y
-	help
-	  Say Y here if you want to expose temperature sensor data on
-	  rtc-rv3029.
-
 config RTC_DRV_RV8803
 	tristate "Micro Crystal RV8803"
 	help
@@ -786,6 +768,25 @@ config RTC_DRV_PCF2127
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-pcf2127.
=20
+config RTC_DRV_RV3029C2
+	tristate "Micro Crystal RV3029/3049"
+	depends on RTC_I2C_AND_SPI
+	help
+	  If you say yes here you get support for the Micro Crystal
+	  RV3029 and RV3049 RTC chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-rv3029c2.
+
+config RTC_DRV_RV3029_HWMON
+	bool "HWMON support for RV3029/3049"
+	depends on RTC_DRV_RV3029C2 && HWMON
+	depends on !(RTC_DRV_RV3029C2=3Dy && HWMON=3Dm)
+	default y
+	help
+	  Say Y here if you want to expose temperature sensor data on
+	  rtc-rv3029.
+
 comment "Platform RTC drivers"
=20
 # this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 96dd166..1310646 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -1,5 +1,5 @@
 /*
- * Micro Crystal RV-3029 rtc class driver
+ * Micro Crystal RV-3029 / RV-3049 rtc class driver
  *
  * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
  *         Michael Buesch <m@bues.ch>
@@ -14,6 +14,7 @@
=20
 #include <linux/module.h>
 #include <linux/i2c.h>
+#include <linux/spi/spi.h>
 #include <linux/bcd.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
@@ -766,6 +767,8 @@ static int rv3029_probe(struct device *dev, struct regm=
ap *regmap, int irq,
 	return PTR_ERR_OR_ZERO(rv3029->rtc);
 }
=20
+#if IS_ENABLED(CONFIG_I2C)
+
 static int rv3029_i2c_probe(struct i2c_client *client,
 			    const struct i2c_device_id *id)
 {
@@ -799,9 +802,108 @@ static struct i2c_driver rv3029_driver =3D {
 	.id_table	=3D rv3029_id,
 };
=20
-module_i2c_driver(rv3029_driver);
+static int rv3029_register_driver(void)
+{
+	return i2c_add_driver(&rv3029_driver);
+}
+
+static void rv3029_unregister_driver(void)
+{
+	i2c_del_driver(&rv3029_driver);
+}
+
+#else
+
+static int rv3029_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3029_unregister_driver(void)
+{
+}
+
+#endif
+
+#if IS_ENABLED(CONFIG_SPI_MASTER)
+
+static int rv3049_probe(struct spi_device *spi)
+{
+	static const struct regmap_config config =3D {
+		.reg_bits =3D 8,
+		.val_bits =3D 8,
+	};
+	struct regmap *regmap;
+
+	regmap =3D devm_regmap_init_spi(spi, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
+			__func__, PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
+
+	return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
+}
+
+static struct spi_driver rv3049_driver =3D {
+	.driver =3D {
+		.name    =3D "rv3049",
+	},
+	.probe   =3D rv3049_probe,
+};
+
+static int rv3049_register_driver(void)
+{
+	return spi_register_driver(&rv3049_driver);
+}
+
+static void rv3049_unregister_driver(void)
+{
+	spi_unregister_driver(&rv3049_driver);
+}
+
+#else
+
+static int rv3049_register_driver(void)
+{
+	return 0;
+}
+
+static void rv3049_unregister_driver(void)
+{
+}
+
+#endif
+
+static int __init rv30x9_init(void)
+{
+	int ret;
+
+	ret =3D rv3029_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3029 driver: %d\n", ret);
+		return ret;
+	}
+
+	ret =3D rv3049_register_driver();
+	if (ret) {
+		pr_err("Failed to register rv3049 driver: %d\n", ret);
+		rv3029_unregister_driver();
+	}
+
+	return ret;
+}
+module_init(rv30x9_init)
+
+static void __exit rv30x9_exit(void)
+{
+	rv3049_unregister_driver();
+	rv3029_unregister_driver();
+}
+module_exit(rv30x9_exit)
=20
 MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
 MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
-MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
+MODULE_DESCRIPTION("Micro Crystal RV3029/RV3049 RTC driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:rv3049");
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH V2 4/6] rtc: rv3029: Removes some checks and warnings
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-28 22:00   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Removes some checks from checkpatch such as spaces around arithmetic
operations or prefer "unsigned int".

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 68 +++++++++++++++++++++++-----------------------
 1 file changed, 34 insertions(+), 34 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 1310646..cf8d465 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -125,24 +125,24 @@ struct rv3029_data {
 };
 
 static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
-			    unsigned len)
+			    unsigned int len)
 {
 	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 
 	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
 }
 
 static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
-			     unsigned len)
+			     unsigned int len)
 {
 	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
 
 	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
@@ -347,12 +347,12 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 		return ret;
 	}
 
-	tm->tm_sec = bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
-	tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES-RV3029_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[RV3029_W_HOURS-RV3029_W_SEC];
+		const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC];
 
 		if (_hr & RV3029_REG_HR_12_24) {
 			/* 12h format */
@@ -363,10 +363,10 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 			tm->tm_hour = bcd2bin(_hr & 0x3f);
 	}
 
-	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;
+	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;
 }
@@ -391,13 +391,13 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		return ret;
 	}
 
-	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;
+	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;
 }
@@ -436,13 +436,13 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	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);
+	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_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
@@ -488,13 +488,13 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
 
-	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);
+	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 = rv3029_write_regs(dev, RV3029_W_SEC, regs,
 				RV3029_WATCH_SECTION_LEN);
@@ -515,6 +515,7 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 
 	return 0;
 }
+
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -603,9 +604,8 @@ static void rv3029_trickle_config(struct device *dev)
 	err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
-	if (err < 0) {
+	if (err < 0)
 		dev_err(dev, "Failed to update trickle charger config\n");
-	}
 }
 
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH V2 4/6] rtc: rv3029: Removes some checks and warnings
@ 2016-04-28 22:00   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Removes some checks from checkpatch such as spaces around arithmetic
operations or prefer "unsigned int".

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 68 +++++++++++++++++++++++-------------------=
----
 1 file changed, 34 insertions(+), 34 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 1310646..cf8d465 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -125,24 +125,24 @@ struct rv3029_data {
 };
=20
 static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
-			    unsigned len)
+			    unsigned int len)
 {
 	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
=20
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
=20
 	return regmap_bulk_read(rv3029->regmap, reg, buf, len);
 }
=20
 static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
-			     unsigned len)
+			     unsigned int len)
 {
 	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
=20
 	if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-		(reg + len > RV3029_USR1_RAM_PAGE + 8))
+	    (reg + len > RV3029_USR1_RAM_PAGE + 8))
 		return -EINVAL;
=20
 	return regmap_bulk_write(rv3029->regmap, reg, buf, len);
@@ -347,12 +347,12 @@ static int rv3029_read_time(struct device *dev, struc=
t rtc_time *tm)
 		return ret;
 	}
=20
-	tm->tm_sec =3D bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
-	tm->tm_min =3D bcd2bin(regs[RV3029_W_MINUTES-RV3029_W_SEC]);
+	tm->tm_sec =3D bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
+	tm->tm_min =3D bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
=20
 	/* HR field has a more complex interpretation */
 	{
-		const u8 _hr =3D regs[RV3029_W_HOURS-RV3029_W_SEC];
+		const u8 _hr =3D regs[RV3029_W_HOURS - RV3029_W_SEC];
=20
 		if (_hr & RV3029_REG_HR_12_24) {
 			/* 12h format */
@@ -363,10 +363,10 @@ static int rv3029_read_time(struct device *dev, struc=
t rtc_time *tm)
 			tm->tm_hour =3D bcd2bin(_hr & 0x3f);
 	}
=20
-	tm->tm_mday =3D bcd2bin(regs[RV3029_W_DATE-RV3029_W_SEC]);
-	tm->tm_mon =3D bcd2bin(regs[RV3029_W_MONTHS-RV3029_W_SEC]) - 1;
-	tm->tm_year =3D bcd2bin(regs[RV3029_W_YEARS-RV3029_W_SEC]) + 100;
-	tm->tm_wday =3D bcd2bin(regs[RV3029_W_DAYS-RV3029_W_SEC]) - 1;
+	tm->tm_mday =3D bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]);
+	tm->tm_mon =3D bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1;
+	tm->tm_year =3D bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 100;
+	tm->tm_wday =3D bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1;
=20
 	return 0;
 }
@@ -391,13 +391,13 @@ static int rv3029_read_alarm(struct device *dev, stru=
ct rtc_wkalrm *alarm)
 		return ret;
 	}
=20
-	tm->tm_sec =3D bcd2bin(regs[RV3029_A_SC-RV3029_A_SC] & 0x7f);
-	tm->tm_min =3D bcd2bin(regs[RV3029_A_MN-RV3029_A_SC] & 0x7f);
-	tm->tm_hour =3D bcd2bin(regs[RV3029_A_HR-RV3029_A_SC] & 0x3f);
-	tm->tm_mday =3D bcd2bin(regs[RV3029_A_DT-RV3029_A_SC] & 0x3f);
-	tm->tm_mon =3D bcd2bin(regs[RV3029_A_MO-RV3029_A_SC] & 0x1f) - 1;
-	tm->tm_year =3D bcd2bin(regs[RV3029_A_YR-RV3029_A_SC] & 0x7f) + 100;
-	tm->tm_wday =3D bcd2bin(regs[RV3029_A_DW-RV3029_A_SC] & 0x07) - 1;
+	tm->tm_sec =3D bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
+	tm->tm_min =3D bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
+	tm->tm_hour =3D bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f);
+	tm->tm_mday =3D bcd2bin(regs[RV3029_A_DT - RV3029_A_SC] & 0x3f);
+	tm->tm_mon =3D bcd2bin(regs[RV3029_A_MO - RV3029_A_SC] & 0x1f) - 1;
+	tm->tm_year =3D bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100;
+	tm->tm_wday =3D bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1;
=20
 	return 0;
 }
@@ -436,13 +436,13 @@ static int rv3029_set_alarm(struct device *dev, struc=
t rtc_wkalrm *alarm)
 		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	regs[RV3029_A_SC-RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
-	regs[RV3029_A_MN-RV3029_A_SC] =3D bin2bcd(tm->tm_min & 0x7f);
-	regs[RV3029_A_HR-RV3029_A_SC] =3D bin2bcd(tm->tm_hour & 0x3f);
-	regs[RV3029_A_DT-RV3029_A_SC] =3D bin2bcd(tm->tm_mday & 0x3f);
-	regs[RV3029_A_MO-RV3029_A_SC] =3D bin2bcd((tm->tm_mon & 0x1f) - 1);
-	regs[RV3029_A_DW-RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
-	regs[RV3029_A_YR-RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
+	regs[RV3029_A_SC - RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
+	regs[RV3029_A_MN - RV3029_A_SC] =3D bin2bcd(tm->tm_min & 0x7f);
+	regs[RV3029_A_HR - RV3029_A_SC] =3D bin2bcd(tm->tm_hour & 0x3f);
+	regs[RV3029_A_DT - RV3029_A_SC] =3D bin2bcd(tm->tm_mday & 0x3f);
+	regs[RV3029_A_MO - RV3029_A_SC] =3D bin2bcd((tm->tm_mon & 0x1f) - 1);
+	regs[RV3029_A_DW - RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
+	regs[RV3029_A_YR - RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
=20
 	ret =3D rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
@@ -488,13 +488,13 @@ static int rv3029_set_time(struct device *dev, struct=
 rtc_time *tm)
 	if (tm->tm_year < 100)
 		return -EINVAL;
=20
-	regs[RV3029_W_SEC-RV3029_W_SEC] =3D bin2bcd(tm->tm_sec);
-	regs[RV3029_W_MINUTES-RV3029_W_SEC] =3D bin2bcd(tm->tm_min);
-	regs[RV3029_W_HOURS-RV3029_W_SEC] =3D bin2bcd(tm->tm_hour);
-	regs[RV3029_W_DATE-RV3029_W_SEC] =3D bin2bcd(tm->tm_mday);
-	regs[RV3029_W_MONTHS-RV3029_W_SEC] =3D bin2bcd(tm->tm_mon+1);
-	regs[RV3029_W_DAYS-RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7)+1);
-	regs[RV3029_W_YEARS-RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
+	regs[RV3029_W_SEC - RV3029_W_SEC] =3D bin2bcd(tm->tm_sec);
+	regs[RV3029_W_MINUTES - RV3029_W_SEC] =3D bin2bcd(tm->tm_min);
+	regs[RV3029_W_HOURS - RV3029_W_SEC] =3D bin2bcd(tm->tm_hour);
+	regs[RV3029_W_DATE - RV3029_W_SEC] =3D bin2bcd(tm->tm_mday);
+	regs[RV3029_W_MONTHS - RV3029_W_SEC] =3D bin2bcd(tm->tm_mon + 1);
+	regs[RV3029_W_DAYS - RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7) + 1);
+	regs[RV3029_W_YEARS - RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
=20
 	ret =3D rv3029_write_regs(dev, RV3029_W_SEC, regs,
 				RV3029_WATCH_SECTION_LEN);
@@ -515,6 +515,7 @@ static int rv3029_set_time(struct device *dev, struct r=
tc_time *tm)
=20
 	return 0;
 }
+
 static const struct rv3029_trickle_tab_elem {
 	u32 r;		/* resistance in ohms */
 	u8 conf;	/* trickle config bits */
@@ -603,9 +604,8 @@ static void rv3029_trickle_config(struct device *dev)
 	err =3D rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
 					RV3029_TRICKLE_MASK,
 					trickle_set_bits);
-	if (err < 0) {
+	if (err < 0)
 		dev_err(dev, "Failed to update trickle charger config\n");
-	}
 }
=20
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH V2 5/6] rtc: rv3029: fix alarm support
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-28 22:00   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

The RTC RV3029 handles different types of alarms : seconds, minutes, ...
These alarms can be enabled or disabled individually using an AE_x bit
which is the last bit (BIT(7)) on each alarm registers.

To prepare the alarm IRQ support, the current code enables all the alarm
types by setting each AE_x to 1.
It also fixes others alarms issues :
   - month and weekday errors : it was performing -1 instead of +1.
   - wrong use of bit mask with bin2bcd

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index cf8d465..916bbc2 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -76,6 +76,7 @@
 #define RV3029_A_DW			0x14
 #define RV3029_A_MO			0x15
 #define RV3029_A_YR			0x16
+#define RV3029_A_AE_X			BIT(7)
 #define RV3029_ALARM_SECTION_LEN	0x07
 
 /* timer section */
@@ -436,14 +437,22 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	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);
 
+	/* Activate all the alarms with AE_x bit */
+	regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
+	regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X;
+	regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour) & 0x3f)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday) & 0x3f)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd(tm->tm_mon + 1) & 0x1f)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd(tm->tm_wday + 1) & 0x7)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd(tm->tm_year - 100))
+		| RV3029_A_AE_X;
+
+	/* Write the alarm */
 	ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
@@ -493,7 +502,7 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 	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_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
 	regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
 
 	ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH V2 5/6] rtc: rv3029: fix alarm support
@ 2016-04-28 22:00   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

The RTC RV3029 handles different types of alarms : seconds, minutes, ...
These alarms can be enabled or disabled individually using an AE_x bit
which is the last bit (BIT(7)) on each alarm registers.

To prepare the alarm IRQ support, the current code enables all the alarm
types by setting each AE_x to 1.
It also fixes others alarms issues :
   - month and weekday errors : it was performing -1 instead of +1.
   - wrong use of bit mask with bin2bcd

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index cf8d465..916bbc2 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -76,6 +76,7 @@
 #define RV3029_A_DW			0x14
 #define RV3029_A_MO			0x15
 #define RV3029_A_YR			0x16
+#define RV3029_A_AE_X			BIT(7)
 #define RV3029_ALARM_SECTION_LEN	0x07
=20
 /* timer section */
@@ -436,14 +437,22 @@ static int rv3029_set_alarm(struct device *dev, struc=
t rtc_wkalrm *alarm)
 		dev_err(dev, "%s: reading SR failed\n", __func__);
 		return -EIO;
 	}
-	regs[RV3029_A_SC - RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
-	regs[RV3029_A_MN - RV3029_A_SC] =3D bin2bcd(tm->tm_min & 0x7f);
-	regs[RV3029_A_HR - RV3029_A_SC] =3D bin2bcd(tm->tm_hour & 0x3f);
-	regs[RV3029_A_DT - RV3029_A_SC] =3D bin2bcd(tm->tm_mday & 0x3f);
-	regs[RV3029_A_MO - RV3029_A_SC] =3D bin2bcd((tm->tm_mon & 0x1f) - 1);
-	regs[RV3029_A_DW - RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
-	regs[RV3029_A_YR - RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100);
=20
+	/* Activate all the alarms with AE_x bit */
+	regs[RV3029_A_SC - RV3029_A_SC] =3D bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
+	regs[RV3029_A_MN - RV3029_A_SC] =3D bin2bcd(tm->tm_min) | RV3029_A_AE_X;
+	regs[RV3029_A_HR - RV3029_A_SC] =3D (bin2bcd(tm->tm_hour) & 0x3f)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DT - RV3029_A_SC] =3D (bin2bcd(tm->tm_mday) & 0x3f)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_MO - RV3029_A_SC] =3D (bin2bcd(tm->tm_mon + 1) & 0x1f)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_DW - RV3029_A_SC] =3D (bin2bcd(tm->tm_wday + 1) & 0x7)
+		| RV3029_A_AE_X;
+	regs[RV3029_A_YR - RV3029_A_SC] =3D (bin2bcd(tm->tm_year - 100))
+		| RV3029_A_AE_X;
+
+	/* Write the alarm */
 	ret =3D rv3029_write_regs(dev, RV3029_A_SC, regs,
 				RV3029_ALARM_SECTION_LEN);
 	if (ret < 0)
@@ -493,7 +502,7 @@ static int rv3029_set_time(struct device *dev, struct r=
tc_time *tm)
 	regs[RV3029_W_HOURS - RV3029_W_SEC] =3D bin2bcd(tm->tm_hour);
 	regs[RV3029_W_DATE - RV3029_W_SEC] =3D bin2bcd(tm->tm_mday);
 	regs[RV3029_W_MONTHS - RV3029_W_SEC] =3D bin2bcd(tm->tm_mon + 1);
-	regs[RV3029_W_DAYS - RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7) + 1);
+	regs[RV3029_W_DAYS - RV3029_W_SEC] =3D bin2bcd(tm->tm_wday + 1) & 0x7;
 	regs[RV3029_W_YEARS - RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
=20
 	ret =3D rv3029_write_regs(dev, RV3029_W_SEC, regs,
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH V2 6/6] rtc: rv3029: add alarm IRQ
  2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
@ 2016-04-28 22:00   ` Mylène Josserand
  -1 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Add the alarm IRQ functionality.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 114 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 93 insertions(+), 21 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 916bbc2..c2ef64f 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -329,6 +329,47 @@ static int rv3029_eeprom_update_bits(struct device *dev,
 	return 0;
 }
 
+static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
+{
+	struct device *dev = dev_id;
+	struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+	struct mutex *lock = &rv3029->rtc->ops_lock;
+	unsigned long events = 0;
+	u8 flags, controls;
+	int ret;
+
+	mutex_lock(lock);
+
+	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	if (flags & RV3029_IRQ_FLAGS_AF) {
+		flags &= ~RV3029_IRQ_FLAGS_AF;
+		controls &= ~RV3029_IRQ_CTRL_AIE;
+		events |= RTC_AF;
+	}
+
+	if (events) {
+		rtc_update_irq(rv3029->rtc, 1, events);
+		rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+		rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	}
+	mutex_unlock(lock);
+
+	return IRQ_HANDLED;
+}
+
 static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 buf[1];
@@ -376,7 +417,7 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct rtc_time *const tm = &alarm->time;
 	int ret;
-	u8 regs[8];
+	u8 regs[8], controls, flags;
 
 	ret = rv3029_get_sr(dev, regs);
 	if (ret < 0) {
@@ -392,6 +433,17 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		return ret;
 	}
 
+	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_err(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
+	ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret < 0) {
+		dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
+		return ret;
+	}
+
 	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);
@@ -400,16 +452,30 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	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;
 
+	alarm->enabled = !!(controls & RV3029_IRQ_CTRL_AIE);
+	alarm->pending = (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled;
+
 	return 0;
 }
 
-static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable)
+static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
 {
 	int ret;
+	u8 controls;
+
+	ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret < 0) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
 
 	/* enable/disable AIE irq */
-	ret = rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE,
-				 (enable ? RV3029_IRQ_CTRL_AIE : 0));
+	if (enable)
+		controls |= RV3029_IRQ_CTRL_AIE;
+	else
+		controls &= ~RV3029_IRQ_CTRL_AIE;
+
+	ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
 	if (ret < 0) {
 		dev_err(dev, "can't update INT reg\n");
 		return ret;
@@ -459,26 +525,15 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 		return ret;
 
 	if (alarm->enabled) {
-		/* clear AF flag */
-		ret = rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
-					 RV3029_IRQ_FLAGS_AF, 0);
-		if (ret < 0) {
-			dev_err(dev, "can't clear alarm flag\n");
-			return ret;
-		}
 		/* enable AIE irq */
-		ret = rv3029_rtc_alarm_set_irq(dev, 1);
+		ret = rv3029_alarm_irq_enable(dev, 1);
 		if (ret)
 			return ret;
-
-		dev_dbg(dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret = rv3029_rtc_alarm_set_irq(dev, 0);
+		ret = rv3029_alarm_irq_enable(dev, 0);
 		if (ret)
 			return ret;
-
-		dev_dbg(dev, "alarm IRQ disabled\n");
 	}
 
 	return 0;
@@ -731,11 +786,9 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
 
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
 
-static const struct rtc_class_ops rv3029_rtc_ops = {
+static struct rtc_class_ops rv3029_rtc_ops = {
 	.read_time	= rv3029_read_time,
 	.set_time	= rv3029_set_time,
-	.read_alarm	= rv3029_read_alarm,
-	.set_alarm	= rv3029_set_alarm,
 };
 
 static struct i2c_device_id rv3029_id[] = {
@@ -772,8 +825,27 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
 
 	rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
 					       THIS_MODULE);
+	if (IS_ERR(rv3029->rtc)) {
+		dev_err(dev, "unable to register the class device\n");
+		return PTR_ERR(rv3029->rtc);
+	}
 
-	return PTR_ERR_OR_ZERO(rv3029->rtc);
+	if (rv3029->irq > 0) {
+		rc = devm_request_threaded_irq(dev, rv3029->irq,
+					       NULL, rv3029_handle_irq,
+					       IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					       "rv3029", dev);
+		if (rc) {
+			dev_warn(dev, "unable to request IRQ, alarms disabled\n");
+			rv3029->irq = 0;
+		} else {
+			rv3029_rtc_ops.read_alarm = rv3029_read_alarm;
+			rv3029_rtc_ops.set_alarm = rv3029_set_alarm;
+			rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable;
+		}
+	}
+
+	return 0;
 }
 
 #if IS_ENABLED(CONFIG_I2C)
-- 
2.8.0.rc3

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [rtc-linux] [PATCH V2 6/6] rtc: rv3029: add alarm IRQ
@ 2016-04-28 22:00   ` Mylène Josserand
  0 siblings, 0 replies; 38+ messages in thread
From: Mylène Josserand @ 2016-04-28 22:00 UTC (permalink / raw)
  To: alexandre.belloni, rtc-linux
  Cc: Alessandro Zummo, linux-kernel, mylene.josserand

Add the alarm IRQ functionality.

Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/rtc/rtc-rv3029c2.c | 114 ++++++++++++++++++++++++++++++++++++-----=
----
 1 file changed, 93 insertions(+), 21 deletions(-)

diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
index 916bbc2..c2ef64f 100644
--- a/drivers/rtc/rtc-rv3029c2.c
+++ b/drivers/rtc/rtc-rv3029c2.c
@@ -329,6 +329,47 @@ static int rv3029_eeprom_update_bits(struct device *de=
v,
 	return 0;
 }
=20
+static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
+{
+	struct device *dev =3D dev_id;
+	struct rv3029_data *rv3029 =3D dev_get_drvdata(dev);
+	struct mutex *lock =3D &rv3029->rtc->ops_lock;
+	unsigned long events =3D 0;
+	u8 flags, controls;
+	int ret;
+
+	mutex_lock(lock);
+
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret) {
+		dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
+		mutex_unlock(lock);
+		return IRQ_NONE;
+	}
+
+	if (flags & RV3029_IRQ_FLAGS_AF) {
+		flags &=3D ~RV3029_IRQ_FLAGS_AF;
+		controls &=3D ~RV3029_IRQ_CTRL_AIE;
+		events |=3D RTC_AF;
+	}
+
+	if (events) {
+		rtc_update_irq(rv3029->rtc, 1, events);
+		rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+		rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	}
+	mutex_unlock(lock);
+
+	return IRQ_HANDLED;
+}
+
 static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
 	u8 buf[1];
@@ -376,7 +417,7 @@ static int rv3029_read_alarm(struct device *dev, struct=
 rtc_wkalrm *alarm)
 {
 	struct rtc_time *const tm =3D &alarm->time;
 	int ret;
-	u8 regs[8];
+	u8 regs[8], controls, flags;
=20
 	ret =3D rv3029_get_sr(dev, regs);
 	if (ret < 0) {
@@ -392,6 +433,17 @@ static int rv3029_read_alarm(struct device *dev, struc=
t rtc_wkalrm *alarm)
 		return ret;
 	}
=20
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret) {
+		dev_err(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+	if (ret < 0) {
+		dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
+		return ret;
+	}
+
 	tm->tm_sec =3D bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
 	tm->tm_min =3D bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
 	tm->tm_hour =3D bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f);
@@ -400,16 +452,30 @@ static int rv3029_read_alarm(struct device *dev, stru=
ct rtc_wkalrm *alarm)
 	tm->tm_year =3D bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100;
 	tm->tm_wday =3D bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1;
=20
+	alarm->enabled =3D !!(controls & RV3029_IRQ_CTRL_AIE);
+	alarm->pending =3D (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled;
+
 	return 0;
 }
=20
-static int rv3029_rtc_alarm_set_irq(struct device *dev, int enable)
+static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable=
)
 {
 	int ret;
+	u8 controls;
+
+	ret =3D rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+	if (ret < 0) {
+		dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
+		return ret;
+	}
=20
 	/* enable/disable AIE irq */
-	ret =3D rv3029_update_bits(dev, RV3029_IRQ_CTRL, RV3029_IRQ_CTRL_AIE,
-				 (enable ? RV3029_IRQ_CTRL_AIE : 0));
+	if (enable)
+		controls |=3D RV3029_IRQ_CTRL_AIE;
+	else
+		controls &=3D ~RV3029_IRQ_CTRL_AIE;
+
+	ret =3D rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
 	if (ret < 0) {
 		dev_err(dev, "can't update INT reg\n");
 		return ret;
@@ -459,26 +525,15 @@ static int rv3029_set_alarm(struct device *dev, struc=
t rtc_wkalrm *alarm)
 		return ret;
=20
 	if (alarm->enabled) {
-		/* clear AF flag */
-		ret =3D rv3029_update_bits(dev, RV3029_IRQ_FLAGS,
-					 RV3029_IRQ_FLAGS_AF, 0);
-		if (ret < 0) {
-			dev_err(dev, "can't clear alarm flag\n");
-			return ret;
-		}
 		/* enable AIE irq */
-		ret =3D rv3029_rtc_alarm_set_irq(dev, 1);
+		ret =3D rv3029_alarm_irq_enable(dev, 1);
 		if (ret)
 			return ret;
-
-		dev_dbg(dev, "alarm IRQ armed\n");
 	} else {
 		/* disable AIE irq */
-		ret =3D rv3029_rtc_alarm_set_irq(dev, 0);
+		ret =3D rv3029_alarm_irq_enable(dev, 0);
 		if (ret)
 			return ret;
-
-		dev_dbg(dev, "alarm IRQ disabled\n");
 	}
=20
 	return 0;
@@ -731,11 +786,9 @@ static void rv3029_hwmon_register(struct device *dev, =
const char *name)
=20
 #endif /* CONFIG_RTC_DRV_RV3029_HWMON */
=20
-static const struct rtc_class_ops rv3029_rtc_ops =3D {
+static struct rtc_class_ops rv3029_rtc_ops =3D {
 	.read_time	=3D rv3029_read_time,
 	.set_time	=3D rv3029_set_time,
-	.read_alarm	=3D rv3029_read_alarm,
-	.set_alarm	=3D rv3029_set_alarm,
 };
=20
 static struct i2c_device_id rv3029_id[] =3D {
@@ -772,8 +825,27 @@ static int rv3029_probe(struct device *dev, struct reg=
map *regmap, int irq,
=20
 	rv3029->rtc =3D devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
 					       THIS_MODULE);
+	if (IS_ERR(rv3029->rtc)) {
+		dev_err(dev, "unable to register the class device\n");
+		return PTR_ERR(rv3029->rtc);
+	}
=20
-	return PTR_ERR_OR_ZERO(rv3029->rtc);
+	if (rv3029->irq > 0) {
+		rc =3D devm_request_threaded_irq(dev, rv3029->irq,
+					       NULL, rv3029_handle_irq,
+					       IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					       "rv3029", dev);
+		if (rc) {
+			dev_warn(dev, "unable to request IRQ, alarms disabled\n");
+			rv3029->irq =3D 0;
+		} else {
+			rv3029_rtc_ops.read_alarm =3D rv3029_read_alarm;
+			rv3029_rtc_ops.set_alarm =3D rv3029_set_alarm;
+			rv3029_rtc_ops.alarm_irq_enable =3D rv3029_alarm_irq_enable;
+		}
+	}
+
+	return 0;
 }
=20
 #if IS_ENABLED(CONFIG_I2C)
--=20
2.8.0.rc3

--=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH V2 5/6] rtc: rv3029: fix alarm support
  2016-04-28 22:00   ` [rtc-linux] " Mylène Josserand
@ 2016-05-03  8:25     ` Alexandre Belloni
  -1 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-05-03  8:25 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

On 29/04/2016 at 00:00:36 +0200, Mylène Josserand wrote :
> The RTC RV3029 handles different types of alarms : seconds, minutes, ...
> These alarms can be enabled or disabled individually using an AE_x bit
> which is the last bit (BIT(7)) on each alarm registers.
> 
> To prepare the alarm IRQ support, the current code enables all the alarm
> types by setting each AE_x to 1.
> It also fixes others alarms issues :
>    - month and weekday errors : it was performing -1 instead of +1.
>    - wrong use of bit mask with bin2bcd
> 
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/rtc/rtc-rv3029c2.c | 25 +++++++++++++++++--------
>  1 file changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
> index cf8d465..916bbc2 100644
> --- a/drivers/rtc/rtc-rv3029c2.c
> +++ b/drivers/rtc/rtc-rv3029c2.c
> @@ -76,6 +76,7 @@
>  #define RV3029_A_DW			0x14
>  #define RV3029_A_MO			0x15
>  #define RV3029_A_YR			0x16
> +#define RV3029_A_AE_X			BIT(7)
>  #define RV3029_ALARM_SECTION_LEN	0x07
>  
>  /* timer section */
> @@ -436,14 +437,22 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
>  		dev_err(dev, "%s: reading SR failed\n", __func__);
>  		return -EIO;
>  	}
> -	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);
>  
> +	/* Activate all the alarms with AE_x bit */
> +	regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
> +	regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X;
> +	regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour) & 0x3f)
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday) & 0x3f)
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd(tm->tm_mon + 1) & 0x1f)
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd(tm->tm_wday + 1) & 0x7)
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd(tm->tm_year - 100))
> +		| RV3029_A_AE_X;
> +
> +	/* Write the alarm */
>  	ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
>  				RV3029_ALARM_SECTION_LEN);
>  	if (ret < 0)
> @@ -493,7 +502,7 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
>  	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_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;

This may go in a separate patch.

>  	regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
>  
>  	ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
> -- 
> 2.8.0.rc3
> 

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

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [rtc-linux] Re: [PATCH V2 5/6] rtc: rv3029: fix alarm support
@ 2016-05-03  8:25     ` Alexandre Belloni
  0 siblings, 0 replies; 38+ messages in thread
From: Alexandre Belloni @ 2016-05-03  8:25 UTC (permalink / raw)
  To: Mylène Josserand; +Cc: rtc-linux, Alessandro Zummo, linux-kernel

On 29/04/2016 at 00:00:36 +0200, Myl=C4=8Dne Josserand wrote :
> The RTC RV3029 handles different types of alarms : seconds, minutes, ...
> These alarms can be enabled or disabled individually using an AE_x bit
> which is the last bit (BIT(7)) on each alarm registers.
>=20
> To prepare the alarm IRQ support, the current code enables all the alarm
> types by setting each AE_x to 1.
> It also fixes others alarms issues :
>    - month and weekday errors : it was performing -1 instead of +1.
>    - wrong use of bit mask with bin2bcd
>=20
> Signed-off-by: Myl=C4=8Dne Josserand <mylene.josserand@free-electrons.com=
>
> ---
>  drivers/rtc/rtc-rv3029c2.c | 25 +++++++++++++++++--------
>  1 file changed, 17 insertions(+), 8 deletions(-)
>=20
> diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c
> index cf8d465..916bbc2 100644
> --- a/drivers/rtc/rtc-rv3029c2.c
> +++ b/drivers/rtc/rtc-rv3029c2.c
> @@ -76,6 +76,7 @@
>  #define RV3029_A_DW			0x14
>  #define RV3029_A_MO			0x15
>  #define RV3029_A_YR			0x16
> +#define RV3029_A_AE_X			BIT(7)
>  #define RV3029_ALARM_SECTION_LEN	0x07
> =20
>  /* timer section */
> @@ -436,14 +437,22 @@ static int rv3029_set_alarm(struct device *dev, str=
uct rtc_wkalrm *alarm)
>  		dev_err(dev, "%s: reading SR failed\n", __func__);
>  		return -EIO;
>  	}
> -	regs[RV3029_A_SC - RV3029_A_SC] =3D bin2bcd(tm->tm_sec & 0x7f);
> -	regs[RV3029_A_MN - RV3029_A_SC] =3D bin2bcd(tm->tm_min & 0x7f);
> -	regs[RV3029_A_HR - RV3029_A_SC] =3D bin2bcd(tm->tm_hour & 0x3f);
> -	regs[RV3029_A_DT - RV3029_A_SC] =3D bin2bcd(tm->tm_mday & 0x3f);
> -	regs[RV3029_A_MO - RV3029_A_SC] =3D bin2bcd((tm->tm_mon & 0x1f) - 1);
> -	regs[RV3029_A_DW - RV3029_A_SC] =3D bin2bcd((tm->tm_wday & 7) - 1);
> -	regs[RV3029_A_YR - RV3029_A_SC] =3D bin2bcd((tm->tm_year & 0x7f) - 100)=
;
> =20
> +	/* Activate all the alarms with AE_x bit */
> +	regs[RV3029_A_SC - RV3029_A_SC] =3D bin2bcd(tm->tm_sec) | RV3029_A_AE_X=
;
> +	regs[RV3029_A_MN - RV3029_A_SC] =3D bin2bcd(tm->tm_min) | RV3029_A_AE_X=
;
> +	regs[RV3029_A_HR - RV3029_A_SC] =3D (bin2bcd(tm->tm_hour) & 0x3f)
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_DT - RV3029_A_SC] =3D (bin2bcd(tm->tm_mday) & 0x3f)
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_MO - RV3029_A_SC] =3D (bin2bcd(tm->tm_mon + 1) & 0x1f)
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_DW - RV3029_A_SC] =3D (bin2bcd(tm->tm_wday + 1) & 0x7)
> +		| RV3029_A_AE_X;
> +	regs[RV3029_A_YR - RV3029_A_SC] =3D (bin2bcd(tm->tm_year - 100))
> +		| RV3029_A_AE_X;
> +
> +	/* Write the alarm */
>  	ret =3D rv3029_write_regs(dev, RV3029_A_SC, regs,
>  				RV3029_ALARM_SECTION_LEN);
>  	if (ret < 0)
> @@ -493,7 +502,7 @@ static int rv3029_set_time(struct device *dev, struct=
 rtc_time *tm)
>  	regs[RV3029_W_HOURS - RV3029_W_SEC] =3D bin2bcd(tm->tm_hour);
>  	regs[RV3029_W_DATE - RV3029_W_SEC] =3D bin2bcd(tm->tm_mday);
>  	regs[RV3029_W_MONTHS - RV3029_W_SEC] =3D bin2bcd(tm->tm_mon + 1);
> -	regs[RV3029_W_DAYS - RV3029_W_SEC] =3D bin2bcd((tm->tm_wday & 7) + 1);
> +	regs[RV3029_W_DAYS - RV3029_W_SEC] =3D bin2bcd(tm->tm_wday + 1) & 0x7;

This may go in a separate patch.

>  	regs[RV3029_W_YEARS - RV3029_W_SEC] =3D bin2bcd(tm->tm_year - 100);
> =20
>  	ret =3D rv3029_write_regs(dev, RV3029_W_SEC, regs,
> --=20
> 2.8.0.rc3
>=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 rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2016-05-03  8:25 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-21 18:24 [PATCH 0/6] add support for Microcrystal RV-3049 Mylène Josserand
2016-04-21 18:24 ` [rtc-linux] " Mylène Josserand
2016-04-21 18:24 ` [PATCH 1/6] rtc: rv3029: remove 'i2c' in functions names Mylène Josserand
2016-04-21 18:24   ` [rtc-linux] " Mylène Josserand
2016-04-21 18:24 ` [PATCH 2/6] rtc: rv3029: convert to use regmap Mylène Josserand
2016-04-21 18:24   ` [rtc-linux] " Mylène Josserand
2016-04-21 18:24 ` [PATCH 3/6] rtc: rv3029: Add support of RV3049 Mylène Josserand
2016-04-21 18:24   ` [rtc-linux] " Mylène Josserand
2016-04-21 18:24 ` [PATCH 4/6] rtc: rv3029: Removes some checks and warnings Mylène Josserand
2016-04-21 18:24   ` [rtc-linux] " Mylène Josserand
2016-04-22 23:29   ` Alexandre Belloni
2016-04-22 23:29     ` [rtc-linux] " Alexandre Belloni
2016-04-22 23:31     ` Alexandre Belloni
2016-04-22 23:31       ` [rtc-linux] " Alexandre Belloni
2016-04-21 18:24 ` [PATCH 5/6] rtc: rv3029: enable AE_x bits on set_alarm Mylène Josserand
2016-04-21 18:24   ` [rtc-linux] " Mylène Josserand
2016-04-22 23:37   ` Alexandre Belloni
2016-04-22 23:37     ` [rtc-linux] " Alexandre Belloni
2016-04-21 18:24 ` [PATCH 6/6] rtc: rv3029: add alarm IRQ Mylène Josserand
2016-04-21 18:24   ` [rtc-linux] " Mylène Josserand
2016-04-22 23:48   ` Alexandre Belloni
2016-04-22 23:48     ` [rtc-linux] " Alexandre Belloni
2016-04-28 22:00 ` [PATCH V2 0/6] add support for Microcrystal RV-3049 Mylène Josserand
2016-04-28 22:00   ` [rtc-linux] " Mylène Josserand
2016-04-28 22:00 ` [PATCH V2 1/6] rtc: rv3029: remove 'i2c' in functions names Mylène Josserand
2016-04-28 22:00   ` [rtc-linux] " Mylène Josserand
2016-04-28 22:00 ` [PATCH V2 2/6] rtc: rv3029: convert to use regmap Mylène Josserand
2016-04-28 22:00   ` [rtc-linux] " Mylène Josserand
2016-04-28 22:00 ` [PATCH V2 3/6] rtc: rv3029: Add support of RV3049 Mylène Josserand
2016-04-28 22:00   ` [rtc-linux] " Mylène Josserand
2016-04-28 22:00 ` [PATCH V2 4/6] rtc: rv3029: Removes some checks and warnings Mylène Josserand
2016-04-28 22:00   ` [rtc-linux] " Mylène Josserand
2016-04-28 22:00 ` [PATCH V2 5/6] rtc: rv3029: fix alarm support Mylène Josserand
2016-04-28 22:00   ` [rtc-linux] " Mylène Josserand
2016-05-03  8:25   ` Alexandre Belloni
2016-05-03  8:25     ` [rtc-linux] " Alexandre Belloni
2016-04-28 22:00 ` [PATCH V2 6/6] rtc: rv3029: add alarm IRQ Mylène Josserand
2016-04-28 22:00   ` [rtc-linux] " Mylène Josserand

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.