Browse Source

use regmap for nvram access since i2c_transfer was unreliable

Helmut Pozimski 5 years ago
parent
commit
d5ef1b1f3a
1 changed files with 16 additions and 13 deletions
  1. 16 13
      rtc-ds13307.c

+ 16 - 13
rtc-ds13307.c

@@ -13,6 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/bcd.h>
 #include <linux/slab.h>
+#include <linux/regmap.h>
 
 #define M_NAME "rtc-ds13307" /* Module name */
 
@@ -42,6 +43,11 @@ static int model_detected;
 static struct i2c_driver ds13307_driver;
 static struct nvmem_config ds1307_nvmem;
 
+static struct regmap_config regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+
 /* Reads a specified number of bytes via i2c, returns 0 on success */
 static int ds13307_read_bytes(struct i2c_client *client,
 		u8 *addr, u8 *bytes, int length) {
@@ -330,27 +336,20 @@ static int ds13307_detect_device(struct i2c_client *client) {
 }
 
 static int ds13307_nvram_read(void *priv, unsigned int offset, void *buf, size_t count) {
-	struct i2c_client *client = priv;
-	u8 addr = DS1307_NVRAM_BASE + offset;
-	if (!ds13307_read_bytes(client, &addr, buf, count)) {
-		return count;
-	}
-	return -EIO;
+	struct regmap *regmap = priv;
+	return regmap_bulk_read(regmap, DS1307_NVRAM_BASE + offset, buf, count);
 }
 
 static int ds13307_nvram_write(void *priv, unsigned int offset, void *buf, size_t count) {
-	struct i2c_client *client = priv;
-	u8 addr = DS1307_NVRAM_BASE + offset;
-	if (!ds13307_write_bytes(client, &addr, buf, count)) {
-		return count;
-	}
-	return -EIO;
+	struct regmap * regmap = priv;
+        return regmap_bulk_write(regmap, DS1307_NVRAM_BASE + offset, buf, count);
 }
 
 static int ds13307_probe(struct i2c_client *client,
 		const struct i2c_device_id *id) {
 	struct rtc_device *rtc;
 	int error;
+	struct regmap * regmap;
 	model_detected = ds13307_detect_device(client);
 	if ((model_detected != DEVICE_DS1307) && (model_detected != DEVICE_DS1337)) {
 		return -EIO;
@@ -359,6 +358,10 @@ static int ds13307_probe(struct i2c_client *client,
 	if (IS_ERR(rtc)) {
 		return PTR_ERR(rtc);
 	}
+	regmap = devm_regmap_init_i2c(client, &regmap_config);
+	if (IS_ERR(regmap)) {
+		return PTR_ERR(regmap);
+	}
 	rtc->uie_unsupported = 1;
 	device_set_wakeup_capable(&client->dev, 0);
 	client->irq = 0;
@@ -368,7 +371,7 @@ static int ds13307_probe(struct i2c_client *client,
 		ds1307_nvmem.size = 56;
 		ds1307_nvmem.reg_read = ds13307_nvram_read;
 		ds1307_nvmem.reg_write = ds13307_nvram_write;
-		ds1307_nvmem.priv = client;
+		ds1307_nvmem.priv = regmap;
 		rtc->nvmem_config = &ds1307_nvmem;
 	} else {
 		ds13307_rtc_ops.read_alarm = ds13307_read_alarm;