diff options
author | Vincent Donnefort <vdonnefort@gmail.com> | 2014-08-08 17:20:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-08 18:57:19 -0400 |
commit | 2784366c6797e6a3078abca2f303ebf7a36290be (patch) | |
tree | 152462695aaa0b61eb2f28c6aab742eecb86ee0c | |
parent | da167ad7638759adb811afa3c80ff4cb67608242 (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.c | 74 |
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 | /* | 72 | static 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 | */ | ||
76 | static 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 = ®, |
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 | |||
97 | static 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 | */ | ||
122 | static 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) | |||
144 | static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) | 175 | static 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 | } |