drivers/rtc/rtc-pcf8563.c: introduce read|write_block_data
authorVincent Donnefort <vdonnefort@gmail.com>
Fri, 8 Aug 2014 21:20:16 +0000 (14:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 8 Aug 2014 22:57:19 +0000 (15:57 -0700)
This functions allow to factorize I2C I/O operations.

Signed-off-by: Vincent Donnefort <vdonnefort@gmail.com>
Cc: Simon Guinot <simon.guinot@sequanux.org>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/rtc/rtc-pcf8563.c

index 63b558c..7cbbf50 100644 (file)
@@ -69,35 +69,66 @@ struct pcf8563 {
        int voltage_low; /* incicates if a low_voltage was detected */
 };
 
-/*
- * In the routines that deal directly with the pcf8563 hardware, we use
- * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
- */
-static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
+static int pcf8563_read_block_data(struct i2c_client *client, unsigned char reg,
+                                  unsigned char length, unsigned char *buf)
 {
-       struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
-       unsigned char buf[13] = { PCF8563_REG_ST1 };
-
        struct i2c_msg msgs[] = {
                {/* setup read ptr */
                        .addr = client->addr,
                        .len = 1,
-                       .buf = buf
+                       .buf = &reg,
                },
-               {/* read status + date */
+               {
                        .addr = client->addr,
                        .flags = I2C_M_RD,
-                       .len = 13,
+                       .len = length,
                        .buf = buf
                },
        };
 
-       /* read registers */
        if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
                dev_err(&client->dev, "%s: read error\n", __func__);
                return -EIO;
        }
 
+       return 0;
+}
+
+static int pcf8563_write_block_data(struct i2c_client *client,
+                                  unsigned char reg, unsigned char length,
+                                  unsigned char *buf)
+{
+       int i, err;
+
+       for (i = 0; i < length; i++) {
+               unsigned char data[2] = { reg + i, buf[i] };
+
+               err = i2c_master_send(client, data, sizeof(data));
+               if (err != sizeof(data)) {
+                       dev_err(&client->dev,
+                               "%s: err=%d addr=%02x, data=%02x\n",
+                               __func__, err, data[0], data[1]);
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * In the routines that deal directly with the pcf8563 hardware, we use
+ * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
+ */
+static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
+{
+       struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
+       unsigned char buf[9];
+       int err;
+
+       err = pcf8563_read_block_data(client, PCF8563_REG_ST1, 9, buf);
+       if (err)
+               return err;
+
        if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) {
                pcf8563->voltage_low = 1;
                dev_info(&client->dev,
@@ -144,7 +175,7 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
 static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 {
        struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
-       int i, err;
+       int err;
        unsigned char buf[9];
 
        dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
@@ -170,19 +201,10 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 
        buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
 
-       /* write register's data */
-       for (i = 0; i < 7; i++) {
-               unsigned char data[2] = { PCF8563_REG_SC + i,
-                                               buf[PCF8563_REG_SC + i] };
-
-               err = i2c_master_send(client, data, sizeof(data));
-               if (err != sizeof(data)) {
-                       dev_err(&client->dev,
-                               "%s: err=%d addr=%02x, data=%02x\n",
-                               __func__, err, data[0], data[1]);
-                       return -EIO;
-               }
-       }
+       err = pcf8563_write_block_data(client, PCF8563_REG_SC,
+                               9 - PCF8563_REG_SC, buf + PCF8563_REG_SC);
+       if (err)
+               return err;
 
        return 0;
 }