aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorAlessandro Zummo <a.zummo@towertech.it>2008-04-28 05:11:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-28 11:58:16 -0400
commit9edae7bcdcbac2dbf037b751ce1809eb2758cd8e (patch)
tree800704222a5db8a1373d789e2d940b253b61c3df /drivers/rtc
parentc750090085f260503d8beec1c73c4d2e4fe93628 (diff)
rtc-isl1208: new style conversion and minor bug fixes
[akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Cc: Herbert Valerio Riedel <hvr@gnu.org> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-isl1208.c357
1 files changed, 170 insertions, 187 deletions
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index 725b0c73c333..fb15e3fb4ce2 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -15,16 +15,15 @@
15#include <linux/bcd.h> 15#include <linux/bcd.h>
16#include <linux/rtc.h> 16#include <linux/rtc.h>
17 17
18#define DRV_NAME "isl1208" 18#define DRV_VERSION "0.3"
19#define DRV_VERSION "0.2"
20 19
21/* Register map */ 20/* Register map */
22/* rtc section */ 21/* rtc section */
23#define ISL1208_REG_SC 0x00 22#define ISL1208_REG_SC 0x00
24#define ISL1208_REG_MN 0x01 23#define ISL1208_REG_MN 0x01
25#define ISL1208_REG_HR 0x02 24#define ISL1208_REG_HR 0x02
26#define ISL1208_REG_HR_MIL (1<<7) /* 24h/12h mode */ 25#define ISL1208_REG_HR_MIL (1<<7) /* 24h/12h mode */
27#define ISL1208_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */ 26#define ISL1208_REG_HR_PM (1<<5) /* PM/AM bit in 12h mode */
28#define ISL1208_REG_DT 0x03 27#define ISL1208_REG_DT 0x03
29#define ISL1208_REG_MO 0x04 28#define ISL1208_REG_MO 0x04
30#define ISL1208_REG_YR 0x05 29#define ISL1208_REG_YR 0x05
@@ -33,14 +32,14 @@
33 32
34/* control/status section */ 33/* control/status section */
35#define ISL1208_REG_SR 0x07 34#define ISL1208_REG_SR 0x07
36#define ISL1208_REG_SR_ARST (1<<7) /* auto reset */ 35#define ISL1208_REG_SR_ARST (1<<7) /* auto reset */
37#define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */ 36#define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */
38#define ISL1208_REG_SR_WRTC (1<<4) /* write rtc */ 37#define ISL1208_REG_SR_WRTC (1<<4) /* write rtc */
39#define ISL1208_REG_SR_ALM (1<<2) /* alarm */ 38#define ISL1208_REG_SR_ALM (1<<2) /* alarm */
40#define ISL1208_REG_SR_BAT (1<<1) /* battery */ 39#define ISL1208_REG_SR_BAT (1<<1) /* battery */
41#define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */ 40#define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */
42#define ISL1208_REG_INT 0x08 41#define ISL1208_REG_INT 0x08
43#define ISL1208_REG_09 0x09 /* reserved */ 42#define ISL1208_REG_09 0x09 /* reserved */
44#define ISL1208_REG_ATR 0x0a 43#define ISL1208_REG_ATR 0x0a
45#define ISL1208_REG_DTR 0x0b 44#define ISL1208_REG_DTR 0x0b
46 45
@@ -58,39 +57,21 @@
58#define ISL1208_REG_USR2 0x13 57#define ISL1208_REG_USR2 0x13
59#define ISL1208_USR_SECTION_LEN 2 58#define ISL1208_USR_SECTION_LEN 2
60 59
61/* i2c configuration */ 60static struct i2c_driver isl1208_driver;
62#define ISL1208_I2C_ADDR 0xde
63
64static const unsigned short normal_i2c[] = {
65 ISL1208_I2C_ADDR>>1, I2C_CLIENT_END
66};
67I2C_CLIENT_INSMOD; /* defines addr_data */
68
69static int isl1208_attach_adapter(struct i2c_adapter *adapter);
70static int isl1208_detach_client(struct i2c_client *client);
71
72static struct i2c_driver isl1208_driver = {
73 .driver = {
74 .name = DRV_NAME,
75 },
76 .id = I2C_DRIVERID_ISL1208,
77 .attach_adapter = &isl1208_attach_adapter,
78 .detach_client = &isl1208_detach_client,
79};
80 61
81/* block read */ 62/* block read */
82static int 63static int
83isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], 64isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
84 unsigned len) 65 unsigned len)
85{ 66{
86 u8 reg_addr[1] = { reg }; 67 u8 reg_addr[1] = { reg };
87 struct i2c_msg msgs[2] = { 68 struct i2c_msg msgs[2] = {
88 { client->addr, client->flags, sizeof(reg_addr), reg_addr }, 69 {client->addr, 0, sizeof(reg_addr), reg_addr}
89 { client->addr, client->flags | I2C_M_RD, len, buf } 70 ,
71 {client->addr, I2C_M_RD, len, buf}
90 }; 72 };
91 int ret; 73 int ret;
92 74
93 BUG_ON(len == 0);
94 BUG_ON(reg > ISL1208_REG_USR2); 75 BUG_ON(reg > ISL1208_REG_USR2);
95 BUG_ON(reg + len > ISL1208_REG_USR2 + 1); 76 BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
96 77
@@ -103,15 +84,14 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
103/* block write */ 84/* block write */
104static int 85static int
105isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], 86isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
106 unsigned len) 87 unsigned len)
107{ 88{
108 u8 i2c_buf[ISL1208_REG_USR2 + 2]; 89 u8 i2c_buf[ISL1208_REG_USR2 + 2];
109 struct i2c_msg msgs[1] = { 90 struct i2c_msg msgs[1] = {
110 { client->addr, client->flags, len + 1, i2c_buf } 91 {client->addr, 0, len + 1, i2c_buf}
111 }; 92 };
112 int ret; 93 int ret;
113 94
114 BUG_ON(len == 0);
115 BUG_ON(reg > ISL1208_REG_USR2); 95 BUG_ON(reg > ISL1208_REG_USR2);
116 BUG_ON(reg + len > ISL1208_REG_USR2 + 1); 96 BUG_ON(reg + len > ISL1208_REG_USR2 + 1);
117 97
@@ -125,7 +105,8 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
125} 105}
126 106
127/* simple check to see wether we have a isl1208 */ 107/* simple check to see wether we have a isl1208 */
128static int isl1208_i2c_validate_client(struct i2c_client *client) 108static int
109isl1208_i2c_validate_client(struct i2c_client *client)
129{ 110{
130 u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; 111 u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
131 u8 zero_mask[ISL1208_RTC_SECTION_LEN] = { 112 u8 zero_mask[ISL1208_RTC_SECTION_LEN] = {
@@ -139,24 +120,29 @@ static int isl1208_i2c_validate_client(struct i2c_client *client)
139 return ret; 120 return ret;
140 121
141 for (i = 0; i < ISL1208_RTC_SECTION_LEN; ++i) { 122 for (i = 0; i < ISL1208_RTC_SECTION_LEN; ++i) {
142 if (regs[i] & zero_mask[i]) /* check if bits are cleared */ 123 if (regs[i] & zero_mask[i]) /* check if bits are cleared */
143 return -ENODEV; 124 return -ENODEV;
144 } 125 }
145 126
146 return 0; 127 return 0;
147} 128}
148 129
149static int isl1208_i2c_get_sr(struct i2c_client *client) 130static int
131isl1208_i2c_get_sr(struct i2c_client *client)
150{ 132{
151 return i2c_smbus_read_byte_data(client, ISL1208_REG_SR) == -1 ? -EIO:0; 133 int sr = i2c_smbus_read_byte_data(client, ISL1208_REG_SR);
134 if (sr < 0)
135 return -EIO;
136
137 return sr;
152} 138}
153 139
154static int isl1208_i2c_get_atr(struct i2c_client *client) 140static int
141isl1208_i2c_get_atr(struct i2c_client *client)
155{ 142{
156 int atr = i2c_smbus_read_byte_data(client, ISL1208_REG_ATR); 143 int atr = i2c_smbus_read_byte_data(client, ISL1208_REG_ATR);
157
158 if (atr < 0) 144 if (atr < 0)
159 return -EIO; 145 return atr;
160 146
161 /* The 6bit value in the ATR register controls the load 147 /* The 6bit value in the ATR register controls the load
162 * capacitance C_load * in steps of 0.25pF 148 * capacitance C_load * in steps of 0.25pF
@@ -169,51 +155,54 @@ static int isl1208_i2c_get_atr(struct i2c_client *client)
169 * 155 *
170 */ 156 */
171 157
172 atr &= 0x3f; /* mask out lsb */ 158 atr &= 0x3f; /* mask out lsb */
173 atr ^= 1<<5; /* invert 6th bit */ 159 atr ^= 1 << 5; /* invert 6th bit */
174 atr += 2*9; /* add offset of 4.5pF; unit[atr] = 0.25pF */ 160 atr += 2 * 9; /* add offset of 4.5pF; unit[atr] = 0.25pF */
175 161
176 return atr; 162 return atr;
177} 163}
178 164
179static int isl1208_i2c_get_dtr(struct i2c_client *client) 165static int
166isl1208_i2c_get_dtr(struct i2c_client *client)
180{ 167{
181 int dtr = i2c_smbus_read_byte_data(client, ISL1208_REG_DTR); 168 int dtr = i2c_smbus_read_byte_data(client, ISL1208_REG_DTR);
182
183 if (dtr < 0) 169 if (dtr < 0)
184 return -EIO; 170 return -EIO;
185 171
186 /* dtr encodes adjustments of {-60,-40,-20,0,20,40,60} ppm */ 172 /* dtr encodes adjustments of {-60,-40,-20,0,20,40,60} ppm */
187 dtr = ((dtr & 0x3) * 20) * (dtr & (1<<2) ? -1 : 1); 173 dtr = ((dtr & 0x3) * 20) * (dtr & (1 << 2) ? -1 : 1);
188 174
189 return dtr; 175 return dtr;
190} 176}
191 177
192static int isl1208_i2c_get_usr(struct i2c_client *client) 178static int
179isl1208_i2c_get_usr(struct i2c_client *client)
193{ 180{
194 u8 buf[ISL1208_USR_SECTION_LEN] = { 0, }; 181 u8 buf[ISL1208_USR_SECTION_LEN] = { 0, };
195 int ret; 182 int ret;
196 183
197 ret = isl1208_i2c_read_regs (client, ISL1208_REG_USR1, buf, 184 ret = isl1208_i2c_read_regs(client, ISL1208_REG_USR1, buf,
198 ISL1208_USR_SECTION_LEN); 185 ISL1208_USR_SECTION_LEN);
199 if (ret < 0) 186 if (ret < 0)
200 return ret; 187 return ret;
201 188
202 return (buf[1] << 8) | buf[0]; 189 return (buf[1] << 8) | buf[0];
203} 190}
204 191
205static int isl1208_i2c_set_usr(struct i2c_client *client, u16 usr) 192static int
193isl1208_i2c_set_usr(struct i2c_client *client, u16 usr)
206{ 194{
207 u8 buf[ISL1208_USR_SECTION_LEN]; 195 u8 buf[ISL1208_USR_SECTION_LEN];
208 196
209 buf[0] = usr & 0xff; 197 buf[0] = usr & 0xff;
210 buf[1] = (usr >> 8) & 0xff; 198 buf[1] = (usr >> 8) & 0xff;
211 199
212 return isl1208_i2c_set_regs (client, ISL1208_REG_USR1, buf, 200 return isl1208_i2c_set_regs(client, ISL1208_REG_USR1, buf,
213 ISL1208_USR_SECTION_LEN); 201 ISL1208_USR_SECTION_LEN);
214} 202}
215 203
216static int isl1208_rtc_proc(struct device *dev, struct seq_file *seq) 204static int
205isl1208_rtc_proc(struct device *dev, struct seq_file *seq)
217{ 206{
218 struct i2c_client *const client = to_i2c_client(dev); 207 struct i2c_client *const client = to_i2c_client(dev);
219 int sr, dtr, atr, usr; 208 int sr, dtr, atr, usr;
@@ -230,20 +219,19 @@ static int isl1208_rtc_proc(struct device *dev, struct seq_file *seq)
230 (sr & ISL1208_REG_SR_ALM) ? " ALM" : "", 219 (sr & ISL1208_REG_SR_ALM) ? " ALM" : "",
231 (sr & ISL1208_REG_SR_WRTC) ? " WRTC" : "", 220 (sr & ISL1208_REG_SR_WRTC) ? " WRTC" : "",
232 (sr & ISL1208_REG_SR_XTOSCB) ? " XTOSCB" : "", 221 (sr & ISL1208_REG_SR_XTOSCB) ? " XTOSCB" : "",
233 (sr & ISL1208_REG_SR_ARST) ? " ARST" : "", 222 (sr & ISL1208_REG_SR_ARST) ? " ARST" : "", sr);
234 sr);
235 223
236 seq_printf(seq, "batt_status\t: %s\n", 224 seq_printf(seq, "batt_status\t: %s\n",
237 (sr & ISL1208_REG_SR_RTCF) ? "bad" : "okay"); 225 (sr & ISL1208_REG_SR_RTCF) ? "bad" : "okay");
238 226
239 dtr = isl1208_i2c_get_dtr(client); 227 dtr = isl1208_i2c_get_dtr(client);
240 if (dtr >= 0 -1) 228 if (dtr >= 0 - 1)
241 seq_printf(seq, "digital_trim\t: %d ppm\n", dtr); 229 seq_printf(seq, "digital_trim\t: %d ppm\n", dtr);
242 230
243 atr = isl1208_i2c_get_atr(client); 231 atr = isl1208_i2c_get_atr(client);
244 if (atr >= 0) 232 if (atr >= 0)
245 seq_printf(seq, "analog_trim\t: %d.%.2d pF\n", 233 seq_printf(seq, "analog_trim\t: %d.%.2d pF\n",
246 atr>>2, (atr&0x3)*25); 234 atr >> 2, (atr & 0x3) * 25);
247 235
248 usr = isl1208_i2c_get_usr(client); 236 usr = isl1208_i2c_get_usr(client);
249 if (usr >= 0) 237 if (usr >= 0)
@@ -252,9 +240,8 @@ static int isl1208_rtc_proc(struct device *dev, struct seq_file *seq)
252 return 0; 240 return 0;
253} 241}
254 242
255 243static int
256static int isl1208_i2c_read_time(struct i2c_client *client, 244isl1208_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
257 struct rtc_time *tm)
258{ 245{
259 int sr; 246 int sr;
260 u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; 247 u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
@@ -274,27 +261,30 @@ static int isl1208_i2c_read_time(struct i2c_client *client,
274 261
275 tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SC]); 262 tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SC]);
276 tm->tm_min = BCD2BIN(regs[ISL1208_REG_MN]); 263 tm->tm_min = BCD2BIN(regs[ISL1208_REG_MN]);
277 { /* HR field has a more complex interpretation */ 264
265 /* HR field has a more complex interpretation */
266 {
278 const u8 _hr = regs[ISL1208_REG_HR]; 267 const u8 _hr = regs[ISL1208_REG_HR];
279 if (_hr & ISL1208_REG_HR_MIL) /* 24h format */ 268 if (_hr & ISL1208_REG_HR_MIL) /* 24h format */
280 tm->tm_hour = BCD2BIN(_hr & 0x3f); 269 tm->tm_hour = BCD2BIN(_hr & 0x3f);
281 else { // 12h format 270 else {
271 /* 12h format */
282 tm->tm_hour = BCD2BIN(_hr & 0x1f); 272 tm->tm_hour = BCD2BIN(_hr & 0x1f);
283 if (_hr & ISL1208_REG_HR_PM) /* PM flag set */ 273 if (_hr & ISL1208_REG_HR_PM) /* PM flag set */
284 tm->tm_hour += 12; 274 tm->tm_hour += 12;
285 } 275 }
286 } 276 }
287 277
288 tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DT]); 278 tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DT]);
289 tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */ 279 tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */
290 tm->tm_year = BCD2BIN(regs[ISL1208_REG_YR]) + 100; 280 tm->tm_year = BCD2BIN(regs[ISL1208_REG_YR]) + 100;
291 tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DW]); 281 tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DW]);
292 282
293 return 0; 283 return 0;
294} 284}
295 285
296static int isl1208_i2c_read_alarm(struct i2c_client *client, 286static int
297 struct rtc_wkalrm *alarm) 287isl1208_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
298{ 288{
299 struct rtc_time *const tm = &alarm->time; 289 struct rtc_time *const tm = &alarm->time;
300 u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, }; 290 u8 regs[ISL1208_ALARM_SECTION_LEN] = { 0, };
@@ -307,7 +297,7 @@ static int isl1208_i2c_read_alarm(struct i2c_client *client,
307 } 297 }
308 298
309 sr = isl1208_i2c_read_regs(client, ISL1208_REG_SCA, regs, 299 sr = isl1208_i2c_read_regs(client, ISL1208_REG_SCA, regs,
310 ISL1208_ALARM_SECTION_LEN); 300 ISL1208_ALARM_SECTION_LEN);
311 if (sr < 0) { 301 if (sr < 0) {
312 dev_err(&client->dev, "%s: reading alarm section failed\n", 302 dev_err(&client->dev, "%s: reading alarm section failed\n",
313 __func__); 303 __func__);
@@ -315,23 +305,25 @@ static int isl1208_i2c_read_alarm(struct i2c_client *client,
315 } 305 }
316 306
317 /* MSB of each alarm register is an enable bit */ 307 /* MSB of each alarm register is an enable bit */
318 tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SCA-ISL1208_REG_SCA] & 0x7f); 308 tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SCA - ISL1208_REG_SCA] & 0x7f);
319 tm->tm_min = BCD2BIN(regs[ISL1208_REG_MNA-ISL1208_REG_SCA] & 0x7f); 309 tm->tm_min = BCD2BIN(regs[ISL1208_REG_MNA - ISL1208_REG_SCA] & 0x7f);
320 tm->tm_hour = BCD2BIN(regs[ISL1208_REG_HRA-ISL1208_REG_SCA] & 0x3f); 310 tm->tm_hour = BCD2BIN(regs[ISL1208_REG_HRA - ISL1208_REG_SCA] & 0x3f);
321 tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DTA-ISL1208_REG_SCA] & 0x3f); 311 tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DTA - ISL1208_REG_SCA] & 0x3f);
322 tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MOA-ISL1208_REG_SCA] & 0x1f)-1; 312 tm->tm_mon =
323 tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DWA-ISL1208_REG_SCA] & 0x03); 313 BCD2BIN(regs[ISL1208_REG_MOA - ISL1208_REG_SCA] & 0x1f) - 1;
314 tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DWA - ISL1208_REG_SCA] & 0x03);
324 315
325 return 0; 316 return 0;
326} 317}
327 318
328static int isl1208_rtc_read_time(struct device *dev, struct rtc_time *tm) 319static int
320isl1208_rtc_read_time(struct device *dev, struct rtc_time *tm)
329{ 321{
330 return isl1208_i2c_read_time(to_i2c_client(dev), tm); 322 return isl1208_i2c_read_time(to_i2c_client(dev), tm);
331} 323}
332 324
333static int isl1208_i2c_set_time(struct i2c_client *client, 325static int
334 struct rtc_time const *tm) 326isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
335{ 327{
336 int sr; 328 int sr;
337 u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; 329 u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
@@ -353,7 +345,7 @@ static int isl1208_i2c_set_time(struct i2c_client *client,
353 } 345 }
354 346
355 /* set WRTC */ 347 /* set WRTC */
356 sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR, 348 sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR,
357 sr | ISL1208_REG_SR_WRTC); 349 sr | ISL1208_REG_SR_WRTC);
358 if (sr < 0) { 350 if (sr < 0) {
359 dev_err(&client->dev, "%s: writing SR failed\n", __func__); 351 dev_err(&client->dev, "%s: writing SR failed\n", __func__);
@@ -369,7 +361,7 @@ static int isl1208_i2c_set_time(struct i2c_client *client,
369 } 361 }
370 362
371 /* clear WRTC again */ 363 /* clear WRTC again */
372 sr = i2c_smbus_write_byte_data (client, ISL1208_REG_SR, 364 sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR,
373 sr & ~ISL1208_REG_SR_WRTC); 365 sr & ~ISL1208_REG_SR_WRTC);
374 if (sr < 0) { 366 if (sr < 0) {
375 dev_err(&client->dev, "%s: writing SR failed\n", __func__); 367 dev_err(&client->dev, "%s: writing SR failed\n", __func__);
@@ -380,70 +372,69 @@ static int isl1208_i2c_set_time(struct i2c_client *client,
380} 372}
381 373
382 374
383static int isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm) 375static int
376isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm)
384{ 377{
385 return isl1208_i2c_set_time(to_i2c_client(dev), tm); 378 return isl1208_i2c_set_time(to_i2c_client(dev), tm);
386} 379}
387 380
388static int isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 381static int
382isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
389{ 383{
390 return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm); 384 return isl1208_i2c_read_alarm(to_i2c_client(dev), alarm);
391} 385}
392 386
393static const struct rtc_class_ops isl1208_rtc_ops = { 387static const struct rtc_class_ops isl1208_rtc_ops = {
394 .proc = isl1208_rtc_proc, 388 .proc = isl1208_rtc_proc,
395 .read_time = isl1208_rtc_read_time, 389 .read_time = isl1208_rtc_read_time,
396 .set_time = isl1208_rtc_set_time, 390 .set_time = isl1208_rtc_set_time,
397 .read_alarm = isl1208_rtc_read_alarm, 391 .read_alarm = isl1208_rtc_read_alarm,
398 //.set_alarm = isl1208_rtc_set_alarm, 392 /*.set_alarm = isl1208_rtc_set_alarm, */
399}; 393};
400 394
401/* sysfs interface */ 395/* sysfs interface */
402 396
403static ssize_t isl1208_sysfs_show_atrim(struct device *dev, 397static ssize_t
404 struct device_attribute *attr, 398isl1208_sysfs_show_atrim(struct device *dev,
405 char *buf) 399 struct device_attribute *attr, char *buf)
406{ 400{
407 int atr; 401 int atr = isl1208_i2c_get_atr(to_i2c_client(dev));
408
409 atr = isl1208_i2c_get_atr(to_i2c_client(dev));
410 if (atr < 0) 402 if (atr < 0)
411 return atr; 403 return atr;
412 404
413 return sprintf(buf, "%d.%.2d pF\n", atr>>2, (atr&0x3)*25); 405 return sprintf(buf, "%d.%.2d pF\n", atr >> 2, (atr & 0x3) * 25);
414} 406}
407
415static DEVICE_ATTR(atrim, S_IRUGO, isl1208_sysfs_show_atrim, NULL); 408static DEVICE_ATTR(atrim, S_IRUGO, isl1208_sysfs_show_atrim, NULL);
416 409
417static ssize_t isl1208_sysfs_show_dtrim(struct device *dev, 410static ssize_t
418 struct device_attribute *attr, 411isl1208_sysfs_show_dtrim(struct device *dev,
419 char *buf) 412 struct device_attribute *attr, char *buf)
420{ 413{
421 int dtr; 414 int dtr = isl1208_i2c_get_dtr(to_i2c_client(dev));
422
423 dtr = isl1208_i2c_get_dtr(to_i2c_client(dev));
424 if (dtr < 0) 415 if (dtr < 0)
425 return dtr; 416 return dtr;
426 417
427 return sprintf(buf, "%d ppm\n", dtr); 418 return sprintf(buf, "%d ppm\n", dtr);
428} 419}
420
429static DEVICE_ATTR(dtrim, S_IRUGO, isl1208_sysfs_show_dtrim, NULL); 421static DEVICE_ATTR(dtrim, S_IRUGO, isl1208_sysfs_show_dtrim, NULL);
430 422
431static ssize_t isl1208_sysfs_show_usr(struct device *dev, 423static ssize_t
432 struct device_attribute *attr, 424isl1208_sysfs_show_usr(struct device *dev,
433 char *buf) 425 struct device_attribute *attr, char *buf)
434{ 426{
435 int usr; 427 int usr = isl1208_i2c_get_usr(to_i2c_client(dev));
436
437 usr = isl1208_i2c_get_usr(to_i2c_client(dev));
438 if (usr < 0) 428 if (usr < 0)
439 return usr; 429 return usr;
440 430
441 return sprintf(buf, "0x%.4x\n", usr); 431 return sprintf(buf, "0x%.4x\n", usr);
442} 432}
443 433
444static ssize_t isl1208_sysfs_store_usr(struct device *dev, 434static ssize_t
445 struct device_attribute *attr, 435isl1208_sysfs_store_usr(struct device *dev,
446 const char *buf, size_t count) 436 struct device_attribute *attr,
437 const char *buf, size_t count)
447{ 438{
448 int usr = -1; 439 int usr = -1;
449 440
@@ -460,124 +451,116 @@ static ssize_t isl1208_sysfs_store_usr(struct device *dev,
460 451
461 return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count; 452 return isl1208_i2c_set_usr(to_i2c_client(dev), usr) ? -EIO : count;
462} 453}
454
463static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr, 455static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr,
464 isl1208_sysfs_store_usr); 456 isl1208_sysfs_store_usr);
465 457
466static int 458static int
467isl1208_probe(struct i2c_adapter *adapter, int addr, int kind) 459isl1208_sysfs_register(struct device *dev)
468{ 460{
469 int rc = 0; 461 int err;
470 struct i2c_client *new_client = NULL; 462
471 struct rtc_device *rtc = NULL; 463 err = device_create_file(dev, &dev_attr_atrim);
464 if (err)
465 return err;
472 466
473 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { 467 err = device_create_file(dev, &dev_attr_dtrim);
474 rc = -ENODEV; 468 if (err) {
475 goto failout; 469 device_remove_file(dev, &dev_attr_atrim);
470 return err;
476 } 471 }
477 472
478 new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 473 err = device_create_file(dev, &dev_attr_usr);
479 if (new_client == NULL) { 474 if (err) {
480 rc = -ENOMEM; 475 device_remove_file(dev, &dev_attr_atrim);
481 goto failout; 476 device_remove_file(dev, &dev_attr_dtrim);
482 } 477 }
483 478
484 new_client->addr = addr; 479 return 0;
485 new_client->adapter = adapter; 480}
486 new_client->driver = &isl1208_driver;
487 new_client->flags = 0;
488 strcpy(new_client->name, DRV_NAME);
489 481
490 if (kind < 0) { 482static int
491 rc = isl1208_i2c_validate_client(new_client); 483isl1208_sysfs_unregister(struct device *dev)
492 if (rc < 0) 484{
493 goto failout; 485 device_remove_file(dev, &dev_attr_atrim);
494 } 486 device_remove_file(dev, &dev_attr_atrim);
487 device_remove_file(dev, &dev_attr_usr);
488
489 return 0;
490}
491
492static int
493isl1208_probe(struct i2c_client *client)
494{
495 int rc = 0;
496 struct rtc_device *rtc;
495 497
496 rc = i2c_attach_client(new_client); 498 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
497 if (rc < 0) 499 return -ENODEV;
498 goto failout;
499 500
500 dev_info(&new_client->dev, 501 if (isl1208_i2c_validate_client(client) < 0)
502 return -ENODEV;
503
504 dev_info(&client->dev,
501 "chip found, driver version " DRV_VERSION "\n"); 505 "chip found, driver version " DRV_VERSION "\n");
502 506
503 rtc = rtc_device_register(isl1208_driver.driver.name, 507 rtc = rtc_device_register(isl1208_driver.driver.name,
504 &new_client->dev, 508 &client->dev, &isl1208_rtc_ops,
505 &isl1208_rtc_ops, THIS_MODULE); 509 THIS_MODULE);
506 510 if (IS_ERR(rtc))
507 if (IS_ERR(rtc)) { 511 return PTR_ERR(rtc);
508 rc = PTR_ERR(rtc);
509 goto failout_detach;
510 }
511 512
512 i2c_set_clientdata(new_client, rtc); 513 i2c_set_clientdata(client, rtc);
513 514
514 rc = isl1208_i2c_get_sr(new_client); 515 rc = isl1208_i2c_get_sr(client);
515 if (rc < 0) { 516 if (rc < 0) {
516 dev_err(&new_client->dev, "reading status failed\n"); 517 dev_err(&client->dev, "reading status failed\n");
517 goto failout_unregister; 518 goto exit_unregister;
518 } 519 }
519 520
520 if (rc & ISL1208_REG_SR_RTCF) 521 if (rc & ISL1208_REG_SR_RTCF)
521 dev_warn(&new_client->dev, "rtc power failure detected, " 522 dev_warn(&client->dev, "rtc power failure detected, "
522 "please set clock.\n"); 523 "please set clock.\n");
523 524
524 rc = device_create_file(&new_client->dev, &dev_attr_atrim); 525 rc = isl1208_sysfs_register(&client->dev);
525 if (rc < 0) 526 if (rc)
526 goto failout_unregister; 527 goto exit_unregister;
527 rc = device_create_file(&new_client->dev, &dev_attr_dtrim);
528 if (rc < 0)
529 goto failout_atrim;
530 rc = device_create_file(&new_client->dev, &dev_attr_usr);
531 if (rc < 0)
532 goto failout_dtrim;
533 528
534 return 0; 529 return 0;
535 530
536 failout_dtrim: 531exit_unregister:
537 device_remove_file(&new_client->dev, &dev_attr_dtrim);
538 failout_atrim:
539 device_remove_file(&new_client->dev, &dev_attr_atrim);
540 failout_unregister:
541 rtc_device_unregister(rtc); 532 rtc_device_unregister(rtc);
542 failout_detach:
543 i2c_detach_client(new_client);
544 failout:
545 kfree(new_client);
546 return rc;
547}
548 533
549static int 534 return rc;
550isl1208_attach_adapter (struct i2c_adapter *adapter)
551{
552 return i2c_probe(adapter, &addr_data, isl1208_probe);
553} 535}
554 536
555static int 537static int
556isl1208_detach_client(struct i2c_client *client) 538isl1208_remove(struct i2c_client *client)
557{ 539{
558 int rc; 540 struct rtc_device *rtc = i2c_get_clientdata(client);
559 struct rtc_device *const rtc = i2c_get_clientdata(client);
560
561 if (rtc)
562 rtc_device_unregister(rtc); /* do we need to kfree? */
563
564 rc = i2c_detach_client(client);
565 if (rc)
566 return rc;
567 541
568 kfree(client); 542 isl1208_sysfs_unregister(&client->dev);
543 rtc_device_unregister(rtc);
569 544
570 return 0; 545 return 0;
571} 546}
572 547
573/* module management */ 548static struct i2c_driver isl1208_driver = {
549 .driver = {
550 .name = "rtc-isl1208",
551 },
552 .probe = isl1208_probe,
553 .remove = isl1208_remove,
554};
574 555
575static int __init isl1208_init(void) 556static int __init
557isl1208_init(void)
576{ 558{
577 return i2c_add_driver(&isl1208_driver); 559 return i2c_add_driver(&isl1208_driver);
578} 560}
579 561
580static void __exit isl1208_exit(void) 562static void __exit
563isl1208_exit(void)
581{ 564{
582 i2c_del_driver(&isl1208_driver); 565 i2c_del_driver(&isl1208_driver);
583} 566}