Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] Update the rtc-rs5c372 driver

Bugfixes:
- Handle RTCs which are configured to use 12-hour mode.
- Never report bogus/un-initialized times.
- Displaying "raw trim" requires not masking it first!
- Fix the sysfs and procfs display of crystal and trim data.

Features:
- Handle other RTCs in this family, notably rv5c386/rv5c387.
- Declare the other registers.
- Provide alarm get/set functionality.
- Handle AIE and UIE; but no IRQ handling yet.

Cleanup:
- Shrink object by not including needless sysfs or procfs support
- We don't need no steenkin' forward declarations. (Except one.)

Until the I2C framework merges "new style" driver support, matching
the driver model better, using rv5c chips or alarm IRQs requires a
separate board-specific patch. (And an IRQ handler, handing off labor
through a work_struct...)

This uses the "method 3" register reads, but notes that it's done
to work around an evident i2c adapter driver bug.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

David Brownell and committed by
Linus Torvalds
cb26b572 b6a60451

+465 -66
+465 -66
drivers/rtc/rtc-rs5c372.c
··· 1 1 /* 2 - * An I2C driver for the Ricoh RS5C372 RTC 2 + * An I2C driver for Ricoh RS5C372 and RV5C38[67] RTCs 3 3 * 4 4 * Copyright (C) 2005 Pavel Mironchik <pmironchik@optifacio.net> 5 5 * Copyright (C) 2006 Tower Technologies ··· 13 13 #include <linux/rtc.h> 14 14 #include <linux/bcd.h> 15 15 16 - #define DRV_VERSION "0.3" 16 + #define DRV_VERSION "0.4" 17 17 18 18 /* Addresses to scan */ 19 19 static unsigned short normal_i2c[] = { /* 0x32,*/ I2C_CLIENT_END }; ··· 21 21 /* Insmod parameters */ 22 22 I2C_CLIENT_INSMOD; 23 23 24 + 25 + /* 26 + * Ricoh has a family of I2C based RTCs, which differ only slightly from 27 + * each other. Differences center on pinout (e.g. how many interrupts, 28 + * output clock, etc) and how the control registers are used. The '372 29 + * is significant only because that's the one this driver first supported. 30 + */ 24 31 #define RS5C372_REG_SECS 0 25 32 #define RS5C372_REG_MINS 1 26 33 #define RS5C372_REG_HOURS 2 ··· 36 29 #define RS5C372_REG_MONTH 5 37 30 #define RS5C372_REG_YEAR 6 38 31 #define RS5C372_REG_TRIM 7 32 + # define RS5C372_TRIM_XSL 0x80 33 + # define RS5C372_TRIM_MASK 0x7F 39 34 40 - #define RS5C372_TRIM_XSL 0x80 41 - #define RS5C372_TRIM_MASK 0x7F 35 + #define RS5C_REG_ALARM_A_MIN 8 /* or ALARM_W */ 36 + #define RS5C_REG_ALARM_A_HOURS 9 37 + #define RS5C_REG_ALARM_A_WDAY 10 42 38 43 - #define RS5C372_REG_BASE 0 39 + #define RS5C_REG_ALARM_B_MIN 11 /* or ALARM_D */ 40 + #define RS5C_REG_ALARM_B_HOURS 12 41 + #define RS5C_REG_ALARM_B_WDAY 13 /* (ALARM_B only) */ 44 42 45 - static int rs5c372_attach(struct i2c_adapter *adapter); 46 - static int rs5c372_detach(struct i2c_client *client); 47 - static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind); 43 + #define RS5C_REG_CTRL1 14 44 + # define RS5C_CTRL1_AALE (1 << 7) /* or WALE */ 45 + # define RS5C_CTRL1_BALE (1 << 6) /* or DALE */ 46 + # define RV5C387_CTRL1_24 (1 << 5) 47 + # define RS5C372A_CTRL1_SL1 (1 << 5) 48 + # define RS5C_CTRL1_CT_MASK (7 << 0) 49 + # define RS5C_CTRL1_CT0 (0 << 0) /* no periodic irq */ 50 + # define RS5C_CTRL1_CT4 (4 << 0) /* 1 Hz level irq */ 51 + #define RS5C_REG_CTRL2 15 52 + # define RS5C372_CTRL2_24 (1 << 5) 53 + # define RS5C_CTRL2_XSTP (1 << 4) 54 + # define RS5C_CTRL2_CTFG (1 << 2) 55 + # define RS5C_CTRL2_AAFG (1 << 1) /* or WAFG */ 56 + # define RS5C_CTRL2_BAFG (1 << 0) /* or DAFG */ 48 57 58 + 59 + /* to read (style 1) or write registers starting at R */ 60 + #define RS5C_ADDR(R) (((R) << 4) | 0) 61 + 62 + 63 + enum rtc_type { 64 + rtc_undef = 0, 65 + rtc_rs5c372a, 66 + rtc_rs5c372b, 67 + rtc_rv5c386, 68 + rtc_rv5c387a, 69 + }; 70 + 71 + /* REVISIT: this assumes that: 72 + * - we're in the 21st century, so it's safe to ignore the century 73 + * bit for rv5c38[67] (REG_MONTH bit 7); 74 + * - we should use ALARM_A not ALARM_B (may be wrong on some boards) 75 + */ 49 76 struct rs5c372 { 50 - u8 reg_addr; 51 - u8 regs[17]; 52 - struct i2c_msg msg[1]; 53 - struct i2c_client client; 54 - struct rtc_device *rtc; 77 + struct i2c_client *client; 78 + struct rtc_device *rtc; 79 + enum rtc_type type; 80 + unsigned time24:1; 81 + unsigned has_irq:1; 82 + char buf[17]; 83 + char *regs; 84 + 85 + /* on conversion to a "new style" i2c driver, this vanishes */ 86 + struct i2c_client dev; 55 87 }; 56 88 57 - static struct i2c_driver rs5c372_driver = { 58 - .driver = { 59 - .name = "rs5c372", 60 - }, 61 - .attach_adapter = &rs5c372_attach, 62 - .detach_client = &rs5c372_detach, 63 - }; 64 - 65 - static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) 89 + static int rs5c_get_regs(struct rs5c372 *rs5c) 66 90 { 91 + struct i2c_client *client = rs5c->client; 92 + struct i2c_msg msgs[] = { 93 + { client->addr, I2C_M_RD, sizeof rs5c->buf, rs5c->buf }, 94 + }; 67 95 68 - struct rs5c372 *rs5c372 = i2c_get_clientdata(client); 69 - u8 *buf = &(rs5c372->regs[1]); 70 - 71 - /* this implements the 3rd reading method, according 72 - * to the datasheet. rs5c372 defaults to internal 73 - * address 0xF, so 0x0 is in regs[1] 96 + /* This implements the third reading method from the datasheet, using 97 + * an internal address that's reset after each transaction (by STOP) 98 + * to 0x0f ... so we read extra registers, and skip the first one. 99 + * 100 + * The first method doesn't work with the iop3xx adapter driver, on at 101 + * least 80219 chips; this works around that bug. 74 102 */ 75 - 76 - if ((i2c_transfer(client->adapter, rs5c372->msg, 1)) != 1) { 77 - dev_err(&client->dev, "%s: read error\n", __FUNCTION__); 103 + if ((i2c_transfer(client->adapter, msgs, 1)) != 1) { 104 + pr_debug("%s: can't read registers\n", rs5c->rtc->name); 78 105 return -EIO; 79 106 } 80 107 81 - tm->tm_sec = BCD2BIN(buf[RS5C372_REG_SECS] & 0x7f); 82 - tm->tm_min = BCD2BIN(buf[RS5C372_REG_MINS] & 0x7f); 83 - tm->tm_hour = BCD2BIN(buf[RS5C372_REG_HOURS] & 0x3f); 84 - tm->tm_wday = BCD2BIN(buf[RS5C372_REG_WDAY] & 0x07); 85 - tm->tm_mday = BCD2BIN(buf[RS5C372_REG_DAY] & 0x3f); 108 + dev_dbg(&client->dev, 109 + "%02x %02x %02x (%02x) %02x %02x %02x (%02x), " 110 + "%02x %02x %02x, %02x %02x %02x; %02x %02x\n", 111 + rs5c->regs[0], rs5c->regs[1], rs5c->regs[2], rs5c->regs[3], 112 + rs5c->regs[4], rs5c->regs[5], rs5c->regs[6], rs5c->regs[7], 113 + rs5c->regs[8], rs5c->regs[9], rs5c->regs[10], rs5c->regs[11], 114 + rs5c->regs[12], rs5c->regs[13], rs5c->regs[14], rs5c->regs[15]); 115 + 116 + return 0; 117 + } 118 + 119 + static unsigned rs5c_reg2hr(struct rs5c372 *rs5c, unsigned reg) 120 + { 121 + unsigned hour; 122 + 123 + if (rs5c->time24) 124 + return BCD2BIN(reg & 0x3f); 125 + 126 + hour = BCD2BIN(reg & 0x1f); 127 + if (hour == 12) 128 + hour = 0; 129 + if (reg & 0x20) 130 + hour += 12; 131 + return hour; 132 + } 133 + 134 + static unsigned rs5c_hr2reg(struct rs5c372 *rs5c, unsigned hour) 135 + { 136 + if (rs5c->time24) 137 + return BIN2BCD(hour); 138 + 139 + if (hour > 12) 140 + return 0x20 | BIN2BCD(hour - 12); 141 + if (hour == 12) 142 + return 0x20 | BIN2BCD(12); 143 + if (hour == 0) 144 + return BIN2BCD(12); 145 + return BIN2BCD(hour); 146 + } 147 + 148 + static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) 149 + { 150 + struct rs5c372 *rs5c = i2c_get_clientdata(client); 151 + int status = rs5c_get_regs(rs5c); 152 + 153 + if (status < 0) 154 + return status; 155 + 156 + tm->tm_sec = BCD2BIN(rs5c->regs[RS5C372_REG_SECS] & 0x7f); 157 + tm->tm_min = BCD2BIN(rs5c->regs[RS5C372_REG_MINS] & 0x7f); 158 + tm->tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C372_REG_HOURS]); 159 + 160 + tm->tm_wday = BCD2BIN(rs5c->regs[RS5C372_REG_WDAY] & 0x07); 161 + tm->tm_mday = BCD2BIN(rs5c->regs[RS5C372_REG_DAY] & 0x3f); 86 162 87 163 /* tm->tm_mon is zero-based */ 88 - tm->tm_mon = BCD2BIN(buf[RS5C372_REG_MONTH] & 0x1f) - 1; 164 + tm->tm_mon = BCD2BIN(rs5c->regs[RS5C372_REG_MONTH] & 0x1f) - 1; 89 165 90 166 /* year is 1900 + tm->tm_year */ 91 - tm->tm_year = BCD2BIN(buf[RS5C372_REG_YEAR]) + 100; 167 + tm->tm_year = BCD2BIN(rs5c->regs[RS5C372_REG_YEAR]) + 100; 92 168 93 169 dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " 94 170 "mday=%d, mon=%d, year=%d, wday=%d\n", ··· 179 89 tm->tm_sec, tm->tm_min, tm->tm_hour, 180 90 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); 181 91 182 - return 0; 92 + /* rtc might need initialization */ 93 + return rtc_valid_tm(tm); 183 94 } 184 95 185 96 static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) 186 97 { 187 - unsigned char buf[8] = { RS5C372_REG_BASE }; 98 + struct rs5c372 *rs5c = i2c_get_clientdata(client); 99 + unsigned char buf[8]; 188 100 189 - dev_dbg(&client->dev, 190 - "%s: secs=%d, mins=%d, hours=%d " 101 + dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " 191 102 "mday=%d, mon=%d, year=%d, wday=%d\n", 192 - __FUNCTION__, tm->tm_sec, tm->tm_min, tm->tm_hour, 103 + __FUNCTION__, 104 + tm->tm_sec, tm->tm_min, tm->tm_hour, 193 105 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); 194 106 107 + buf[0] = RS5C_ADDR(RS5C372_REG_SECS); 195 108 buf[1] = BIN2BCD(tm->tm_sec); 196 109 buf[2] = BIN2BCD(tm->tm_min); 197 - buf[3] = BIN2BCD(tm->tm_hour); 110 + buf[3] = rs5c_hr2reg(rs5c, tm->tm_hour); 198 111 buf[4] = BIN2BCD(tm->tm_wday); 199 112 buf[5] = BIN2BCD(tm->tm_mday); 200 113 buf[6] = BIN2BCD(tm->tm_mon + 1); ··· 211 118 return 0; 212 119 } 213 120 121 + #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) 122 + #define NEED_TRIM 123 + #endif 124 + 125 + #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) 126 + #define NEED_TRIM 127 + #endif 128 + 129 + #ifdef NEED_TRIM 214 130 static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim) 215 131 { 216 132 struct rs5c372 *rs5c372 = i2c_get_clientdata(client); 217 - u8 tmp = rs5c372->regs[RS5C372_REG_TRIM + 1]; 133 + u8 tmp = rs5c372->regs[RS5C372_REG_TRIM]; 218 134 219 135 if (osc) 220 136 *osc = (tmp & RS5C372_TRIM_XSL) ? 32000 : 32768; 221 137 222 138 if (trim) { 223 - *trim = tmp & RS5C372_TRIM_MASK; 224 - dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, *trim); 139 + dev_dbg(&client->dev, "%s: raw trim=%x\n", __FUNCTION__, tmp); 140 + tmp &= RS5C372_TRIM_MASK; 141 + if (tmp & 0x3e) { 142 + int t = tmp & 0x3f; 143 + 144 + if (tmp & 0x40) 145 + t = (~t | (s8)0xc0) + 1; 146 + else 147 + t = t - 1; 148 + 149 + tmp = t * 2; 150 + } else 151 + tmp = 0; 152 + *trim = tmp; 225 153 } 226 154 227 155 return 0; 228 156 } 157 + #endif 229 158 230 159 static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm) 231 160 { ··· 259 144 return rs5c372_set_datetime(to_i2c_client(dev), tm); 260 145 } 261 146 147 + #if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) 148 + 149 + static int 150 + rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 151 + { 152 + struct i2c_client *client = to_i2c_client(dev); 153 + struct rs5c372 *rs5c = i2c_get_clientdata(client); 154 + unsigned char buf[2]; 155 + int status; 156 + 157 + buf[1] = rs5c->regs[RS5C_REG_CTRL1]; 158 + switch (cmd) { 159 + case RTC_UIE_OFF: 160 + case RTC_UIE_ON: 161 + /* some 327a modes use a different IRQ pin for 1Hz irqs */ 162 + if (rs5c->type == rtc_rs5c372a 163 + && (buf[1] & RS5C372A_CTRL1_SL1)) 164 + return -ENOIOCTLCMD; 165 + case RTC_AIE_OFF: 166 + case RTC_AIE_ON: 167 + /* these irq management calls only make sense for chips 168 + * which are wired up to an IRQ. 169 + */ 170 + if (!rs5c->has_irq) 171 + return -ENOIOCTLCMD; 172 + break; 173 + default: 174 + return -ENOIOCTLCMD; 175 + } 176 + 177 + status = rs5c_get_regs(rs5c); 178 + if (status < 0) 179 + return status; 180 + 181 + buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); 182 + switch (cmd) { 183 + case RTC_AIE_OFF: /* alarm off */ 184 + buf[1] &= ~RS5C_CTRL1_AALE; 185 + break; 186 + case RTC_AIE_ON: /* alarm on */ 187 + buf[1] |= RS5C_CTRL1_AALE; 188 + break; 189 + case RTC_UIE_OFF: /* update off */ 190 + buf[1] &= ~RS5C_CTRL1_CT_MASK; 191 + break; 192 + case RTC_UIE_ON: /* update on */ 193 + buf[1] &= ~RS5C_CTRL1_CT_MASK; 194 + buf[1] |= RS5C_CTRL1_CT4; 195 + break; 196 + } 197 + if ((i2c_master_send(client, buf, 2)) != 2) { 198 + printk(KERN_WARNING "%s: can't update alarm\n", 199 + rs5c->rtc->name); 200 + status = -EIO; 201 + } else 202 + rs5c->regs[RS5C_REG_CTRL1] = buf[1]; 203 + return status; 204 + } 205 + 206 + #else 207 + #define rs5c_rtc_ioctl NULL 208 + #endif 209 + 210 + 211 + /* NOTE: Since RTC_WKALM_{RD,SET} were originally defined for EFI, 212 + * which only exposes a polled programming interface; and since 213 + * these calls map directly to those EFI requests; we don't demand 214 + * we have an IRQ for this chip when we go through this API. 215 + * 216 + * The older x86_pc derived RTC_ALM_{READ,SET} calls require irqs 217 + * though, managed through RTC_AIE_{ON,OFF} requests. 218 + */ 219 + 220 + static int rs5c_read_alarm(struct device *dev, struct rtc_wkalrm *t) 221 + { 222 + struct i2c_client *client = to_i2c_client(dev); 223 + struct rs5c372 *rs5c = i2c_get_clientdata(client); 224 + int status; 225 + 226 + status = rs5c_get_regs(rs5c); 227 + if (status < 0) 228 + return status; 229 + 230 + /* report alarm time */ 231 + t->time.tm_sec = 0; 232 + t->time.tm_min = BCD2BIN(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); 233 + t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); 234 + t->time.tm_mday = -1; 235 + t->time.tm_mon = -1; 236 + t->time.tm_year = -1; 237 + t->time.tm_wday = -1; 238 + t->time.tm_yday = -1; 239 + t->time.tm_isdst = -1; 240 + 241 + /* ... and status */ 242 + t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); 243 + t->pending = !!(rs5c->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_AAFG); 244 + 245 + return 0; 246 + } 247 + 248 + static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) 249 + { 250 + struct i2c_client *client = to_i2c_client(dev); 251 + struct rs5c372 *rs5c = i2c_get_clientdata(client); 252 + int status; 253 + unsigned char buf[4]; 254 + 255 + /* only handle up to 24 hours in the future, like RTC_ALM_SET */ 256 + if (t->time.tm_mday != -1 257 + || t->time.tm_mon != -1 258 + || t->time.tm_year != -1) 259 + return -EINVAL; 260 + 261 + /* REVISIT: round up tm_sec */ 262 + 263 + /* if needed, disable irq (clears pending status) */ 264 + status = rs5c_get_regs(rs5c); 265 + if (status < 0) 266 + return status; 267 + if (rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE) { 268 + buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); 269 + buf[1] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE; 270 + if (i2c_master_send(client, buf, 2) != 2) { 271 + pr_debug("%s: can't disable alarm\n", rs5c->rtc->name); 272 + return -EIO; 273 + } 274 + rs5c->regs[RS5C_REG_CTRL1] = buf[1]; 275 + } 276 + 277 + /* set alarm */ 278 + buf[0] = RS5C_ADDR(RS5C_REG_ALARM_A_MIN); 279 + buf[1] = BIN2BCD(t->time.tm_min); 280 + buf[2] = rs5c_hr2reg(rs5c, t->time.tm_hour); 281 + buf[3] = 0x7f; /* any/all days */ 282 + if ((i2c_master_send(client, buf, 4)) != 4) { 283 + pr_debug("%s: can't set alarm time\n", rs5c->rtc->name); 284 + return -EIO; 285 + } 286 + 287 + /* ... and maybe enable its irq */ 288 + if (t->enabled) { 289 + buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); 290 + buf[1] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE; 291 + if ((i2c_master_send(client, buf, 2)) != 2) 292 + printk(KERN_WARNING "%s: can't enable alarm\n", 293 + rs5c->rtc->name); 294 + rs5c->regs[RS5C_REG_CTRL1] = buf[1]; 295 + } 296 + 297 + return 0; 298 + } 299 + 300 + #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) 301 + 262 302 static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq) 263 303 { 264 304 int err, osc, trim; 265 305 266 306 err = rs5c372_get_trim(to_i2c_client(dev), &osc, &trim); 267 307 if (err == 0) { 268 - seq_printf(seq, "%d.%03d KHz\n", osc / 1000, osc % 1000); 269 - seq_printf(seq, "trim\t: %d\n", trim); 308 + seq_printf(seq, "crystal\t\t: %d.%03d KHz\n", 309 + osc / 1000, osc % 1000); 310 + seq_printf(seq, "trim\t\t: %d\n", trim); 270 311 } 271 312 272 313 return 0; 273 314 } 274 315 316 + #else 317 + #define rs5c372_rtc_proc NULL 318 + #endif 319 + 275 320 static const struct rtc_class_ops rs5c372_rtc_ops = { 276 321 .proc = rs5c372_rtc_proc, 322 + .ioctl = rs5c_rtc_ioctl, 277 323 .read_time = rs5c372_rtc_read_time, 278 324 .set_time = rs5c372_rtc_set_time, 325 + .read_alarm = rs5c_read_alarm, 326 + .set_alarm = rs5c_set_alarm, 279 327 }; 328 + 329 + #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) 280 330 281 331 static ssize_t rs5c372_sysfs_show_trim(struct device *dev, 282 332 struct device_attribute *attr, char *buf) ··· 452 172 if (err) 453 173 return err; 454 174 455 - return sprintf(buf, "0x%2x\n", trim); 175 + return sprintf(buf, "%d\n", trim); 456 176 } 457 177 static DEVICE_ATTR(trim, S_IRUGO, rs5c372_sysfs_show_trim, NULL); 458 178 ··· 469 189 } 470 190 static DEVICE_ATTR(osc, S_IRUGO, rs5c372_sysfs_show_osc, NULL); 471 191 472 - static int rs5c372_attach(struct i2c_adapter *adapter) 192 + static int rs5c_sysfs_register(struct device *dev) 473 193 { 474 - return i2c_probe(adapter, &addr_data, rs5c372_probe); 194 + int err; 195 + 196 + err = device_create_file(dev, &dev_attr_trim); 197 + if (err) 198 + return err; 199 + err = device_create_file(dev, &dev_attr_osc); 200 + if (err) 201 + device_remove_file(dev, &dev_attr_trim); 202 + 203 + return err; 475 204 } 205 + 206 + #else 207 + static int rs5c_sysfs_register(struct device *dev) 208 + { 209 + return 0; 210 + } 211 + #endif /* SYSFS */ 212 + 213 + static struct i2c_driver rs5c372_driver; 476 214 477 215 static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind) 478 216 { 479 217 int err = 0; 480 218 struct i2c_client *client; 481 219 struct rs5c372 *rs5c372; 220 + struct rtc_time tm; 482 221 483 222 dev_dbg(adapter->class_dev.dev, "%s\n", __FUNCTION__); 484 223 ··· 510 211 err = -ENOMEM; 511 212 goto exit; 512 213 } 513 - client = &rs5c372->client; 214 + 215 + /* we read registers 0x0f then 0x00-0x0f; skip the first one */ 216 + rs5c372->regs=&rs5c372->buf[1]; 217 + 218 + /* On conversion to a "new style" i2c driver, we'll be handed 219 + * the i2c_client (we won't create it) 220 + */ 221 + client = &rs5c372->dev; 222 + rs5c372->client = client; 514 223 515 224 /* I2C client */ 516 225 client->addr = address; ··· 529 222 530 223 i2c_set_clientdata(client, rs5c372); 531 224 532 - rs5c372->msg[0].addr = address; 533 - rs5c372->msg[0].flags = I2C_M_RD; 534 - rs5c372->msg[0].len = sizeof(rs5c372->regs); 535 - rs5c372->msg[0].buf = rs5c372->regs; 536 - 537 225 /* Inform the i2c layer */ 538 226 if ((err = i2c_attach_client(client))) 539 227 goto exit_kfree; 540 228 541 - dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); 229 + err = rs5c_get_regs(rs5c372); 230 + if (err < 0) 231 + goto exit_detach; 232 + 233 + /* For "new style" drivers, irq is in i2c_client and chip type 234 + * info comes from i2c_client.dev.platform_data. Meanwhile: 235 + * 236 + * STICK BOARD-SPECIFIC SETUP CODE RIGHT HERE 237 + */ 238 + if (rs5c372->type == rtc_undef) { 239 + rs5c372->type = rtc_rs5c372b; 240 + dev_warn(&client->dev, "assuming rs5c372b\n"); 241 + } 242 + 243 + /* clock may be set for am/pm or 24 hr time */ 244 + switch (rs5c372->type) { 245 + case rtc_rs5c372a: 246 + case rtc_rs5c372b: 247 + /* alarm uses ALARM_A; and nINTRA on 372a, nINTR on 372b. 248 + * so does periodic irq, except some 327a modes. 249 + */ 250 + if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C372_CTRL2_24) 251 + rs5c372->time24 = 1; 252 + break; 253 + case rtc_rv5c386: 254 + case rtc_rv5c387a: 255 + if (rs5c372->regs[RS5C_REG_CTRL1] & RV5C387_CTRL1_24) 256 + rs5c372->time24 = 1; 257 + /* alarm uses ALARM_W; and nINTRB for alarm and periodic 258 + * irq, on both 386 and 387 259 + */ 260 + break; 261 + default: 262 + dev_err(&client->dev, "unknown RTC type\n"); 263 + goto exit_detach; 264 + } 265 + 266 + /* if the oscillator lost power and no other software (like 267 + * the bootloader) set it up, do it here. 268 + */ 269 + if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP) { 270 + unsigned char buf[3]; 271 + 272 + rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP; 273 + 274 + buf[0] = RS5C_ADDR(RS5C_REG_CTRL1); 275 + buf[1] = rs5c372->regs[RS5C_REG_CTRL1]; 276 + buf[2] = rs5c372->regs[RS5C_REG_CTRL2]; 277 + 278 + /* use 24hr mode */ 279 + switch (rs5c372->type) { 280 + case rtc_rs5c372a: 281 + case rtc_rs5c372b: 282 + buf[2] |= RS5C372_CTRL2_24; 283 + rs5c372->time24 = 1; 284 + break; 285 + case rtc_rv5c386: 286 + case rtc_rv5c387a: 287 + buf[1] |= RV5C387_CTRL1_24; 288 + rs5c372->time24 = 1; 289 + break; 290 + default: 291 + /* impossible */ 292 + break; 293 + } 294 + 295 + if ((i2c_master_send(client, buf, 3)) != 3) { 296 + dev_err(&client->dev, "setup error\n"); 297 + goto exit_detach; 298 + } 299 + rs5c372->regs[RS5C_REG_CTRL1] = buf[1]; 300 + rs5c372->regs[RS5C_REG_CTRL2] = buf[2]; 301 + } 302 + 303 + if (rs5c372_get_datetime(client, &tm) < 0) 304 + dev_warn(&client->dev, "clock needs to be set\n"); 305 + 306 + dev_info(&client->dev, "%s found, %s, driver version " DRV_VERSION "\n", 307 + ({ char *s; switch (rs5c372->type) { 308 + case rtc_rs5c372a: s = "rs5c372a"; break; 309 + case rtc_rs5c372b: s = "rs5c372b"; break; 310 + case rtc_rv5c386: s = "rv5c386"; break; 311 + case rtc_rv5c387a: s = "rv5c387a"; break; 312 + default: s = "chip"; break; 313 + }; s;}), 314 + rs5c372->time24 ? "24hr" : "am/pm" 315 + ); 316 + 317 + /* FIXME when client->irq exists, use it to register alarm irq */ 542 318 543 319 rs5c372->rtc = rtc_device_register(rs5c372_driver.driver.name, 544 320 &client->dev, &rs5c372_rtc_ops, THIS_MODULE); ··· 631 241 goto exit_detach; 632 242 } 633 243 634 - err = device_create_file(&client->dev, &dev_attr_trim); 244 + err = rs5c_sysfs_register(&client->dev); 635 245 if (err) 636 246 goto exit_devreg; 637 - err = device_create_file(&client->dev, &dev_attr_osc); 638 - if (err) 639 - goto exit_trim; 640 247 641 248 return 0; 642 - 643 - exit_trim: 644 - device_remove_file(&client->dev, &dev_attr_trim); 645 249 646 250 exit_devreg: 647 251 rtc_device_unregister(rs5c372->rtc); ··· 650 266 return err; 651 267 } 652 268 269 + static int rs5c372_attach(struct i2c_adapter *adapter) 270 + { 271 + return i2c_probe(adapter, &addr_data, rs5c372_probe); 272 + } 273 + 653 274 static int rs5c372_detach(struct i2c_client *client) 654 275 { 655 276 int err; ··· 663 274 if (rs5c372->rtc) 664 275 rtc_device_unregister(rs5c372->rtc); 665 276 277 + /* REVISIT properly destroy the sysfs files ... */ 278 + 666 279 if ((err = i2c_detach_client(client))) 667 280 return err; 668 281 669 282 kfree(rs5c372); 670 283 return 0; 671 284 } 285 + 286 + static struct i2c_driver rs5c372_driver = { 287 + .driver = { 288 + .name = "rtc-rs5c372", 289 + }, 290 + .attach_adapter = &rs5c372_attach, 291 + .detach_client = &rs5c372_detach, 292 + }; 672 293 673 294 static __init int rs5c372_init(void) 674 295 {