Browse Source

switch from i2c-functions to regmap for read and write access

Helmut Pozimski 5 years ago
parent
commit
57c64dd2e8
1 changed files with 41 additions and 66 deletions
  1. 41 66
      rtc-ds13307.c

+ 41 - 66
rtc-ds13307.c

@@ -49,24 +49,11 @@ static struct regmap_config regmap_config = {
 };
 
 /* Reads a specified number of bytes via i2c, returns 0 on success */
-static int ds13307_read_bytes(struct i2c_client *client,
+static int ds13307_read_bytes(struct regmap *regmap,
 		u8 *addr, u8 *bytes, int length) {
 	int r;
-	struct i2c_msg msgs[] = {
-		{
-			.addr = client->addr,
-			.len = 1,
-			.buf = addr
-		},
-		{
-			.addr = client->addr,
-			.flags = I2C_M_RD,
-			.len = length,
-			.buf = bytes
-		}
-	};
-	r = i2c_transfer(client->adapter, msgs, 2);
-	if (r == 2) {
+	r = regmap_bulk_read(regmap, (*addr), bytes, length);
+	if (r == length) {
 		return 0;
 	} else {
 		return r;
@@ -74,24 +61,11 @@ static int ds13307_read_bytes(struct i2c_client *client,
 }
 
 /* Writes a specified number of bytes via 2ic, returns 0 on success */
-static int ds13307_write_bytes(struct i2c_client *client,
+static int ds13307_write_bytes(struct regmap *regmap,
 	u8 *addr, u8 *bytes, int length) {
 	int r;
-	u8 *buf;
-	struct i2c_msg msg;
-	buf = (u8*) kmalloc(length +1, GFP_KERNEL);
-	if (buf == NULL) {
-		printk(KERN_ERR "%s: Could not allocate memory for buffer\n", M_NAME);
-		return -EIO;
-	}
-	buf[0] = (*addr);
-	memmove(buf + 1, bytes, length);
-	msg.addr = client->addr;
-	msg.len = length + 1;
-	msg.buf = buf;
-	r = i2c_transfer(client->adapter, &msg, 1);
-	kfree(buf);
-	if (r == 1) {
+	r = regmap_bulk_write(regmap, (*addr), bytes, length);
+	if (r == length) {
 		return 0;
 	} else {
 		return r;
@@ -101,7 +75,7 @@ static int ds13307_write_bytes(struct i2c_client *client,
 /* The oscillator is stopped for both chips when power is first applied,
  * therefore this function checks its status and clears the stop bit.
  */
-static int ds13307_start_oscillator(struct i2c_client *client) {
+static int ds13307_start_oscillator(struct regmap *regmap) {
 	u8 data, addr, buf;
 	int r, v = 0;
 	if (model_detected == DEVICE_DS1307) {
@@ -109,10 +83,10 @@ static int ds13307_start_oscillator(struct i2c_client *client) {
 	} else {
 		addr = DS1337_STAT;
 	}
-	r = ds13307_read_bytes(client, &addr, &data, 1);
+	r = ds13307_read_bytes(regmap, &addr, &data, 1);
 	if (data & COMMON_HIGH_BIT) {
 		buf = data ^ COMMON_HIGH_BIT;
-		v = ds13307_write_bytes(client, &addr, &buf, 1);
+		v = ds13307_write_bytes(regmap, &addr, &buf, 1);
 		if (!v) {
 			printk(KERN_DEBUG "%s: oscillator stop bit successfully cleared\n", M_NAME);
 		}
@@ -138,15 +112,15 @@ static int ds13307_check_12h_am_pm(u8 *byte) {
 }
 
 static int ds13307_read_time(struct device *dev, struct rtc_time *time) {
-	struct i2c_client *client;
+	struct regmap *regmap;
 	int r, century = 1, h12 = 0;
 	u8 buf[7], stopbit;
 	u8 addr = COMMON_SEC;
-	client = to_i2c_client(dev);
-	r = ds13307_read_bytes(client, &addr, buf, 7);
+	regmap = dev_get_drvdata(dev);
+	r = ds13307_read_bytes(regmap, &addr, buf, 7);
 	if (model_detected == DEVICE_DS1337) {
 		addr = DS1337_STAT;
-		r = ds13307_read_bytes(client, &addr, &stopbit, 1);
+		r = ds13307_read_bytes(regmap, &addr, &stopbit, 1);
 		stopbit = stopbit & COMMON_HIGH_BIT;
 	} else {
 		stopbit = buf[COMMON_SEC] & COMMON_HIGH_BIT;
@@ -182,10 +156,10 @@ static int ds13307_read_time(struct device *dev, struct rtc_time *time) {
 }
 
 static int ds13307_set_time(struct device *dev, struct rtc_time *time) {
-	struct i2c_client *client;
+	struct regmap *regmap;
 	u8 buf[7], addr;
-	client = to_i2c_client(dev);
-	if (ds13307_start_oscillator(client)) {
+	regmap = dev_get_drvdata(dev);
+	if (ds13307_start_oscillator(regmap)) {
 		printk(KERN_ERR "%s: failed to initialize the oscillator\n", M_NAME);
 		return -EIO;
 	}
@@ -204,7 +178,7 @@ static int ds13307_set_time(struct device *dev, struct rtc_time *time) {
 		buf[5] = bin2bcd(time->tm_mon + 1);
 	}
 	buf[6] = bin2bcd(time->tm_year % 100);
-	if(ds13307_write_bytes(client, &addr, buf, 7)) {
+	if(ds13307_write_bytes(regmap, &addr, buf, 7)) {
 		return -EIO;
 	}
 	return 0;
@@ -212,11 +186,11 @@ static int ds13307_set_time(struct device *dev, struct rtc_time *time) {
 }
 
 static int ds13307_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
-	struct i2c_client *client;
+	struct regmap *regmap;
 	u8 buf[9], addr = DS1337_ALRM1;
 	int h12;
-	client = to_i2c_client(dev);
-	if (!ds13307_read_bytes(client, &addr, buf, 9)) {
+	regmap = dev_get_drvdata(dev);
+	if (!ds13307_read_bytes(regmap, &addr, buf, 9)) {
 		// select for A1IE bit
 		alarm->enabled = buf[7] & 0x01;
 		// select for A1F bit
@@ -243,10 +217,10 @@ static int ds13307_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
 
 /* Sets the alarm to the values passed to the function */
 static int ds13307_write_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
-	struct i2c_client *client;
+	struct regmap *regmap;
 	u8 buf[9], addr = DS1337_ALRM1;
-	client = to_i2c_client(dev);
-	if(!ds13307_read_bytes(client, &addr, buf, 9)) {
+	regmap = dev_get_drvdata(dev);
+	if(!ds13307_read_bytes(regmap, &addr, buf, 9)) {
 		// enable or disable the alarm as requested
 		if ((alarm->enabled && (!(buf[7] & 0x01))) || ((!alarm->enabled && (buf[7] & 0x01)))) {
 			buf[7] ^= 0x01;
@@ -263,7 +237,7 @@ static int ds13307_write_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
 		buf[1] = bin2bcd(alarm->time.tm_min);
 		buf[2] = bin2bcd(alarm->time.tm_hour);
 		buf[3] = bin2bcd(alarm->time.tm_mday);
-		if(!ds13307_write_bytes(client, &addr, buf, 9)) {
+		if(!ds13307_write_bytes(regmap, &addr, buf, 9)) {
 			return 0;
 		}
 	}
@@ -271,16 +245,16 @@ static int ds13307_write_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
 }
 
 static int ds13307_alarm_irq_enable(struct device *dev, unsigned int enabled) {
-	struct i2c_client *client;
+	struct regmap *regmap;
 	u8 buf, addr = DS1337_CTL;
-	client = to_i2c_client(dev);
-	if (ds13307_read_bytes(client, &addr, &buf, 1)) {
+	regmap = dev_get_drvdata(dev);
+	if (ds13307_read_bytes(regmap, &addr, &buf, 1)) {
 		return -EIO;
 	}
 	if ((!enabled && (buf & 0x01)) || (enabled & (!(buf & 0x01)))) {
 		buf ^= 0x01;
 	}
-	if(!ds13307_write_bytes(client, &addr, &buf, 1)) {
+	if(!ds13307_write_bytes(regmap, &addr, &buf, 1)) {
 		return 0;
 	}
 	return -EIO;
@@ -288,13 +262,13 @@ static int ds13307_alarm_irq_enable(struct device *dev, unsigned int enabled) {
 
 /* Reads the alarm bit and copies it to userspace */
 static int ds13307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) {
-	struct i2c_client *client;
+	struct regmap *regmap;
 	u8 addr, buf;
 	switch(cmd) {
 	case IOCTL_DS13307_ALRM:
 		addr = DS1337_STAT;
-		client = to_i2c_client(dev);
-		if (ds13307_read_bytes(client, &addr, &buf, 1)) {
+		regmap = dev_get_drvdata(dev);
+		if (ds13307_read_bytes(regmap, &addr, &buf, 1)) {
 			return -EIO;
 		}
 		buf &= 0x01;
@@ -316,22 +290,22 @@ static struct rtc_class_ops ds13307_rtc_ops = {
  * DS1307 and DS1337 chips. Returns the defined device ID or
  * -1 on failure
  */
-static int ds13307_detect_device(struct i2c_client *client) {
+static int ds13307_detect_device(struct regmap *regmap) {
 	u8 data, addr = DS1307_MAX_ADDR;
 	int result;
-	result = ds13307_read_bytes(client, &addr, &data, 1);
+	result = ds13307_read_bytes(regmap, &addr, &data, 1);
 	if (!result) {
 		printk(KERN_INFO "%s: Detected device DS1307\n", M_NAME);
 		return DEVICE_DS1307;
 	}
         addr = DS1337_CTL;
-	result = ds13307_read_bytes(client, &addr, &data, 1);
+	result = ds13307_read_bytes(regmap, &addr, &data, 1);
 	if (!result) {	
 		printk(KERN_INFO "%s: Detected device DS1337\n", M_NAME);
  		return DEVICE_DS1337;
 	}
 	printk(KERN_ERR "%s: Could not talk to I2C device at addr %x, is it connected?\n",
-			M_NAME, client->addr);
+			M_NAME, 0x68);
 	return -1;
 }
 
@@ -350,7 +324,11 @@ static int ds13307_probe(struct i2c_client *client,
 	struct rtc_device *rtc;
 	int error;
 	struct regmap * regmap;
-	model_detected = ds13307_detect_device(client);
+	regmap = devm_regmap_init_i2c(client, &regmap_config);
+	if (IS_ERR(regmap)) {
+		return PTR_ERR(regmap);
+	}
+	model_detected = ds13307_detect_device(regmap);
 	if ((model_detected != DEVICE_DS1307) && (model_detected != DEVICE_DS1337)) {
 		return -EIO;
 	}
@@ -358,10 +336,6 @@ 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;
@@ -381,6 +355,7 @@ static int ds13307_probe(struct i2c_client *client,
 	}
 	rtc->ops = &ds13307_rtc_ops;
 	i2c_set_clientdata(client,rtc);
+	dev_set_drvdata(&client->dev, regmap);	
 	error = rtc_register_device(rtc);
 	return error ? error: 0;
 }