LEN; i++) + len += sprintf(page+len, "%02X", buf_id[i]); + len += sprintf(page+len, "\n"); + + len -= off; + if ( len < count ) { + *eof = 1; + if ( len <= 0 ) + return 0; + } else { + len = count; + } + + *start = page + off; + + return len; +} + + +static int +isl12024_probe(struct i2c_adapter *adapter, int addr, int kind) +{ + int rc = 0; + int err = 0; + unsigned char sr; + struct i2c_client *new_client = NULL; + struct rtc_device *rtc = NULL; + struct proc_dir_entry *proc_root; + struct proc_dir_entry *proc_entry; + + if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { + rc = -ENODEV; + goto failout; + } + + new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (new_client == NULL) { + rc = -ENOMEM; + goto failout; + } + + new_client->addr = addr; + new_client->adapter = adapter; + new_client->driver = &isl12024_driver; + new_client->flags = 0; + strcpy(new_client->name, DRV_NAME); + + if (kind < 0) { + rc = isl12024_i2c_validate_client(new_client); + if (rc < 0) + goto failout; + } + + rc = i2c_attach_client(new_client); + if (rc < 0) + goto failout; + + rtc = rtc_device_register(isl12024_driver.driver.name, + &new_client->dev, + &isl12024_rtc_ops, THIS_MODULE); + + if (IS_ERR(rtc)) { + printk(KERN_ERR DRV_NAME ": Error during rtc registration\n"); + rc = PTR_ERR(rtc); + goto failout; + } + + i2c_set_clientdata(new_client, rtc); + + /* Check for power failures and eventualy enable the osc */ + if ((err = isl12024_get_status(new_client, &sr)) == 0) { + if (sr & ISL12024_SR_RTCF) { + printk(KERN_INFO DRV_NAME ": Power failure detected, please set the clock\n"); + udelay(50); + isl12024_fix_osc(new_client); + } + } + else { + printk(KERN_ERR DRV_NAME ": Couldn't read status\n"); + } + + proc_root = proc_mkdir(DRV_NAME, 0); + proc_entry = create_proc_entry("id", S_IFREG | S_IRUGO, proc_root); + if (proc_entry == NULL) + return -1; + + proc_entry->owner = THIS_MODULE; + proc_entry->read_proc = read_proc; + + /* Read unique id from eeprom */ + isl12024_i2c_read_regs(new_client, ISL12024_REG_ID, buf_id, sizeof(buf_id)); + + return 0; + + failout: + kfree(new_client); + return rc; +} + + +static int +isl12024_attach_adapter (struct i2c_adapter *adapter) +{ + return i2c_probe(adapter, &addr_data, isl12024_probe); +} + + +static int +isl12024_detach_client(struct i2c_client *client) +{ + int rc; + struct rtc_device *const rtc = i2c_get_clientdata(client); + + if (rtc) + rtc_device_unregister(rtc); + + rc = i2c_detach_client(client); + if (rc) + return rc; + + kfree(client); + + return 0; +} + + +/* module init/exit */ + +static int __init isl12024_init(void) +{ + return i2c_add_driver(&isl12024_driver); +} + +static void __exit isl12024_exit(void) +{ + i2c_del_driver(&isl12024_driver); +} + +MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@cenosys.com>"); +MODULE_DESCRIPTION("Intersil ISL12024 driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +module_init(isl12024_init); +module_exit(isl12024_exit);