aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Donnefort <vdonnefort@gmail.com>2014-08-08 17:20:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 18:57:19 -0400
commit2784366c6797e6a3078abca2f303ebf7a36290be (patch)
tree152462695aaa0b61eb2f28c6aab742eecb86ee0c
parentda167ad7638759adb811afa3c80ff4cb67608242 (diff)
drivers/rtc/rtc-pcf8563.c: introduce read|write_block_data
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>
-rw-r--r--drivers/rtc/rtc-pcf8563.c74
1 files changed, 48 insertions, 26 deletions
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 63b558c48196..7cbbf50cd895 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -69,35 +69,66 @@ struct pcf8563 {
69 int voltage_low; /* incicates if a low_voltage was detected */ 69 int voltage_low; /* incicates if a low_voltage was detected */
70}; 70};
71 71
72/* 72static int pcf8563_read_block_data(struct i2c_client *client, unsigned char reg,
73 * In the routines that deal directly with the pcf8563 hardware, we use 73 unsigned char length, unsigned char *buf)
74 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
75 */
76static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
77{ 74{
78 struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
79 unsigned char buf[13] = { PCF8563_REG_ST1 };
80
81 struct i2c_msg msgs[] = { 75 struct i2c_msg msgs[] = {
82 {/* setup read ptr */ 76 {/* setup read ptr */
83 .addr = client->addr, 77 .addr = client->addr,
84 .len = 1, 78 .len = 1,
85 .buf = buf 79 .buf = &reg,
86 }, 80 },
87 {/* read status + date */ 81 {
88 .addr = client->addr, 82 .addr = client->addr,
89 .flags = I2C_M_RD, 83 .flags = I2C_M_RD,
90 .len = 13, 84 .len = length,
91 .buf = buf 85 .buf = buf
92 }, 86 },
93 }; 87 };
94 88
95 /* read registers */
96 if ((i2c_transfer(client->adapter, msgs, 2)) != 2) { 89 if ((i2c_transfer(client->adapter, msgs, 2)) != 2) {
97 dev_err(&client->dev, "%s: read error\n", __func__); 90 dev_err(&client->dev, "%s: read error\n", __func__);
98 return -EIO; 91 return -EIO;
99 } 92 }
100 93
94 return 0;
95}
96
97static int pcf8563_write_block_data(struct i2c_client *client,
98 unsigned char reg, unsigned char length,
99 unsigned char *buf)
100{
101 int i, err;
102
103 for (i = 0; i < length; i++) {
104 unsigned char data[2] = { reg + i, buf[i] };
105
106 err = i2c_master_send(client, data, sizeof(data));
107 if (err != sizeof(data)) {
108 dev_err(&client->dev,
109 "%s: err=%d addr=%02x, data=%02x\n",
110 __func__, err, data[0], data[1]);
111 return -EIO;
112 }
113 }
114
115 return 0;
116}
117
118/*
119 * In the routines that deal directly with the pcf8563 hardware, we use
120 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
121 */
122static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
123{
124 struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
125 unsigned char buf[9];
126 int err;
127
128 err = pcf8563_read_block_data(client, PCF8563_REG_ST1, 9, buf);
129 if (err)
130 return err;
131
101 if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) { 132 if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) {
102 pcf8563->voltage_low = 1; 133 pcf8563->voltage_low = 1;
103 dev_info(&client->dev, 134 dev_info(&client->dev,
@@ -144,7 +175,7 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
144static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) 175static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
145{ 176{
146 struct pcf8563 *pcf8563 = i2c_get_clientdata(client); 177 struct pcf8563 *pcf8563 = i2c_get_clientdata(client);
147 int i, err; 178 int err;
148 unsigned char buf[9]; 179 unsigned char buf[9];
149 180
150 dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " 181 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)
170 201
171 buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; 202 buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
172 203
173 /* write register's data */ 204 err = pcf8563_write_block_data(client, PCF8563_REG_SC,
174 for (i = 0; i < 7; i++) { 205 9 - PCF8563_REG_SC, buf + PCF8563_REG_SC);
175 unsigned char data[2] = { PCF8563_REG_SC + i, 206 if (err)
176 buf[PCF8563_REG_SC + i] }; 207 return err;
177
178 err = i2c_master_send(client, data, sizeof(data));
179 if (err != sizeof(data)) {
180 dev_err(&client->dev,
181 "%s: err=%d addr=%02x, data=%02x\n",
182 __func__, err, data[0], data[1]);
183 return -EIO;
184 }
185 }
186 208
187 return 0; 209 return 0;
188} 210}