2006-06-25 16:48:17 +04:00
/*
* rtc - ds1307 . c - RTC driver for some mostly - compatible I2C chips .
*
* Copyright ( C ) 2005 James Chapman ( ds1337 core )
* Copyright ( C ) 2006 David Brownell
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/module.h>
# include <linux/init.h>
# include <linux/slab.h>
# include <linux/i2c.h>
# include <linux/string.h>
# include <linux/rtc.h>
# include <linux/bcd.h>
/* We can't determine type by probing, but if we expect pre-Linux code
* to have set the chip up as a clock ( turning on the oscillator and
* setting the date and time ) , Linux can ignore the non - clock features .
* That ' s a natural job for a factory or repair bench .
*
2007-07-17 15:04:55 +04:00
* This is currently a simple no - alarms driver . If your board has the
* alarm irq wired up on a ds1337 or ds1339 , and you want to use that ,
* then look at the rtc - rs5c372 driver for code to steal . . .
2006-06-25 16:48:17 +04:00
*/
enum ds_type {
2007-07-17 15:04:55 +04:00
ds_1307 ,
ds_1337 ,
ds_1338 ,
ds_1339 ,
ds_1340 ,
m41t00 ,
2006-06-25 16:48:17 +04:00
// rs5c372 too? different address...
} ;
/* RTC registers don't differ much, except for the century flag */
# define DS1307_REG_SECS 0x00 /* 00-59 */
# define DS1307_BIT_CH 0x80
2007-07-17 15:05:06 +04:00
# define DS1340_BIT_nEOSC 0x80
2006-06-25 16:48:17 +04:00
# define DS1307_REG_MIN 0x01 /* 00-59 */
# define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */
2007-07-17 15:05:10 +04:00
# define DS1307_BIT_12HR 0x40 /* in REG_HOUR */
# define DS1307_BIT_PM 0x20 /* in REG_HOUR */
2006-06-25 16:48:17 +04:00
# define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */
# define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */
# define DS1307_REG_WDAY 0x03 /* 01-07 */
# define DS1307_REG_MDAY 0x04 /* 01-31 */
# define DS1307_REG_MONTH 0x05 /* 01-12 */
# define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */
# define DS1307_REG_YEAR 0x06 /* 00-99 */
/* Other registers (control, status, alarms, trickle charge, NVRAM, etc)
2007-07-17 15:04:55 +04:00
* start at 7 , and they differ a LOT . Only control and status matter for
* basic RTC date and time functionality ; be careful using them .
2006-06-25 16:48:17 +04:00
*/
2007-07-17 15:04:55 +04:00
# define DS1307_REG_CONTROL 0x07 /* or ds1338 */
2006-06-25 16:48:17 +04:00
# define DS1307_BIT_OUT 0x80
2007-07-17 15:05:06 +04:00
# define DS1338_BIT_OSF 0x20
2006-06-25 16:48:17 +04:00
# define DS1307_BIT_SQWE 0x10
# define DS1307_BIT_RS1 0x02
# define DS1307_BIT_RS0 0x01
# define DS1337_REG_CONTROL 0x0e
# define DS1337_BIT_nEOSC 0x80
# define DS1337_BIT_RS2 0x10
# define DS1337_BIT_RS1 0x08
# define DS1337_BIT_INTCN 0x04
# define DS1337_BIT_A2IE 0x02
# define DS1337_BIT_A1IE 0x01
2007-07-17 15:04:55 +04:00
# define DS1340_REG_CONTROL 0x07
# define DS1340_BIT_OUT 0x80
# define DS1340_BIT_FT 0x40
# define DS1340_BIT_CALIB_SIGN 0x20
# define DS1340_M_CALIBRATION 0x1f
2007-07-17 15:05:06 +04:00
# define DS1340_REG_FLAG 0x09
# define DS1340_BIT_OSF 0x80
2006-06-25 16:48:17 +04:00
# define DS1337_REG_STATUS 0x0f
# define DS1337_BIT_OSF 0x80
# define DS1337_BIT_A2I 0x02
# define DS1337_BIT_A1I 0x01
# define DS1339_REG_TRICKLE 0x10
struct ds1307 {
u8 reg_addr ;
2007-11-15 03:58:32 +03:00
bool has_nvram ;
2006-06-25 16:48:17 +04:00
u8 regs [ 8 ] ;
enum ds_type type ;
struct i2c_msg msg [ 2 ] ;
2007-07-17 15:04:55 +04:00
struct i2c_client * client ;
struct i2c_client dev ;
2006-06-25 16:48:17 +04:00
struct rtc_device * rtc ;
} ;
2007-07-17 15:04:55 +04:00
struct chip_desc {
unsigned nvram56 : 1 ;
unsigned alarm : 1 ;
} ;
2008-04-30 01:11:40 +04:00
static const struct chip_desc chips [ ] = {
[ ds_1307 ] = {
2007-07-17 15:04:55 +04:00
. nvram56 = 1 ,
2008-04-30 01:11:40 +04:00
} ,
[ ds_1337 ] = {
2007-07-17 15:04:55 +04:00
. alarm = 1 ,
2008-04-30 01:11:40 +04:00
} ,
[ ds_1338 ] = {
2007-07-17 15:04:55 +04:00
. nvram56 = 1 ,
2008-04-30 01:11:40 +04:00
} ,
[ ds_1339 ] = {
2007-07-17 15:04:55 +04:00
. alarm = 1 ,
2008-04-30 01:11:40 +04:00
} ,
[ ds_1340 ] = {
} ,
[ m41t00 ] = {
2007-07-17 15:04:55 +04:00
} , } ;
2008-04-30 01:11:40 +04:00
static const struct i2c_device_id ds1307_id [ ] = {
{ " ds1307 " , ds_1307 } ,
{ " ds1337 " , ds_1337 } ,
{ " ds1338 " , ds_1338 } ,
{ " ds1339 " , ds_1339 } ,
{ " ds1340 " , ds_1340 } ,
{ " m41t00 " , m41t00 } ,
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , ds1307_id ) ;
2006-06-25 16:48:17 +04:00
static int ds1307_get_time ( struct device * dev , struct rtc_time * t )
{
struct ds1307 * ds1307 = dev_get_drvdata ( dev ) ;
int tmp ;
2007-07-17 15:04:55 +04:00
/* read the RTC date and time registers all at once */
2006-06-25 16:48:17 +04:00
ds1307 - > msg [ 1 ] . flags = I2C_M_RD ;
ds1307 - > msg [ 1 ] . len = 7 ;
2007-07-17 15:04:55 +04:00
tmp = i2c_transfer ( to_i2c_adapter ( ds1307 - > client - > dev . parent ) ,
ds1307 - > msg , 2 ) ;
2006-06-25 16:48:17 +04:00
if ( tmp ! = 2 ) {
dev_err ( dev , " %s error %d \n " , " read " , tmp ) ;
return - EIO ;
}
dev_dbg ( dev , " %s: %02x %02x %02x %02x %02x %02x %02x \n " ,
" read " ,
ds1307 - > regs [ 0 ] , ds1307 - > regs [ 1 ] ,
ds1307 - > regs [ 2 ] , ds1307 - > regs [ 3 ] ,
ds1307 - > regs [ 4 ] , ds1307 - > regs [ 5 ] ,
ds1307 - > regs [ 6 ] ) ;
t - > tm_sec = BCD2BIN ( ds1307 - > regs [ DS1307_REG_SECS ] & 0x7f ) ;
t - > tm_min = BCD2BIN ( ds1307 - > regs [ DS1307_REG_MIN ] & 0x7f ) ;
tmp = ds1307 - > regs [ DS1307_REG_HOUR ] & 0x3f ;
t - > tm_hour = BCD2BIN ( tmp ) ;
t - > tm_wday = BCD2BIN ( ds1307 - > regs [ DS1307_REG_WDAY ] & 0x07 ) - 1 ;
t - > tm_mday = BCD2BIN ( ds1307 - > regs [ DS1307_REG_MDAY ] & 0x3f ) ;
tmp = ds1307 - > regs [ DS1307_REG_MONTH ] & 0x1f ;
t - > tm_mon = BCD2BIN ( tmp ) - 1 ;
/* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */
t - > tm_year = BCD2BIN ( ds1307 - > regs [ DS1307_REG_YEAR ] ) + 100 ;
dev_dbg ( dev , " %s secs=%d, mins=%d, "
" hours=%d, mday=%d, mon=%d, year=%d, wday=%d \n " ,
" read " , t - > tm_sec , t - > tm_min ,
t - > tm_hour , t - > tm_mday ,
t - > tm_mon , t - > tm_year , t - > tm_wday ) ;
2007-07-17 15:04:55 +04:00
/* initial clock setting can be undefined */
return rtc_valid_tm ( t ) ;
2006-06-25 16:48:17 +04:00
}
static int ds1307_set_time ( struct device * dev , struct rtc_time * t )
{
struct ds1307 * ds1307 = dev_get_drvdata ( dev ) ;
int result ;
int tmp ;
u8 * buf = ds1307 - > regs ;
dev_dbg ( dev , " %s secs=%d, mins=%d, "
" hours=%d, mday=%d, mon=%d, year=%d, wday=%d \n " ,
2006-10-04 12:41:53 +04:00
" write " , t - > tm_sec , t - > tm_min ,
t - > tm_hour , t - > tm_mday ,
t - > tm_mon , t - > tm_year , t - > tm_wday ) ;
2006-06-25 16:48:17 +04:00
* buf + + = 0 ; /* first register addr */
buf [ DS1307_REG_SECS ] = BIN2BCD ( t - > tm_sec ) ;
buf [ DS1307_REG_MIN ] = BIN2BCD ( t - > tm_min ) ;
buf [ DS1307_REG_HOUR ] = BIN2BCD ( t - > tm_hour ) ;
buf [ DS1307_REG_WDAY ] = BIN2BCD ( t - > tm_wday + 1 ) ;
buf [ DS1307_REG_MDAY ] = BIN2BCD ( t - > tm_mday ) ;
buf [ DS1307_REG_MONTH ] = BIN2BCD ( t - > tm_mon + 1 ) ;
/* assume 20YY not 19YY */
tmp = t - > tm_year - 100 ;
buf [ DS1307_REG_YEAR ] = BIN2BCD ( tmp ) ;
2007-07-17 15:05:06 +04:00
switch ( ds1307 - > type ) {
case ds_1337 :
case ds_1339 :
2006-06-25 16:48:17 +04:00
buf [ DS1307_REG_MONTH ] | = DS1337_BIT_CENTURY ;
2007-07-17 15:05:06 +04:00
break ;
case ds_1340 :
2006-06-25 16:48:17 +04:00
buf [ DS1307_REG_HOUR ] | = DS1340_BIT_CENTURY_EN
| DS1340_BIT_CENTURY ;
2007-07-17 15:05:06 +04:00
break ;
default :
break ;
}
2006-06-25 16:48:17 +04:00
ds1307 - > msg [ 1 ] . flags = 0 ;
ds1307 - > msg [ 1 ] . len = 8 ;
dev_dbg ( dev , " %s: %02x %02x %02x %02x %02x %02x %02x \n " ,
" write " , buf [ 0 ] , buf [ 1 ] , buf [ 2 ] , buf [ 3 ] ,
buf [ 4 ] , buf [ 5 ] , buf [ 6 ] ) ;
2007-07-17 15:04:55 +04:00
result = i2c_transfer ( to_i2c_adapter ( ds1307 - > client - > dev . parent ) ,
& ds1307 - > msg [ 1 ] , 1 ) ;
2006-06-25 16:48:17 +04:00
if ( result ! = 1 ) {
dev_err ( dev , " %s error %d \n " , " write " , tmp ) ;
return - EIO ;
}
return 0 ;
}
2006-10-01 10:28:17 +04:00
static const struct rtc_class_ops ds13xx_rtc_ops = {
2006-06-25 16:48:17 +04:00
. read_time = ds1307_get_time ,
. set_time = ds1307_set_time ,
} ;
2007-11-15 03:58:32 +03:00
/*----------------------------------------------------------------------*/
# define NVRAM_SIZE 56
static ssize_t
ds1307_nvram_read ( struct kobject * kobj , struct bin_attribute * attr ,
char * buf , loff_t off , size_t count )
{
struct i2c_client * client ;
struct ds1307 * ds1307 ;
struct i2c_msg msg [ 2 ] ;
int result ;
2008-02-06 12:38:55 +03:00
client = kobj_to_i2c_client ( kobj ) ;
2007-11-15 03:58:32 +03:00
ds1307 = i2c_get_clientdata ( client ) ;
if ( unlikely ( off > = NVRAM_SIZE ) )
return 0 ;
if ( ( off + count ) > NVRAM_SIZE )
count = NVRAM_SIZE - off ;
if ( unlikely ( ! count ) )
return count ;
msg [ 0 ] . addr = client - > addr ;
msg [ 0 ] . flags = 0 ;
msg [ 0 ] . len = 1 ;
msg [ 0 ] . buf = buf ;
buf [ 0 ] = 8 + off ;
msg [ 1 ] . addr = client - > addr ;
msg [ 1 ] . flags = I2C_M_RD ;
msg [ 1 ] . len = count ;
msg [ 1 ] . buf = buf ;
result = i2c_transfer ( to_i2c_adapter ( client - > dev . parent ) , msg , 2 ) ;
if ( result ! = 2 ) {
dev_err ( & client - > dev , " %s error %d \n " , " nvram read " , result ) ;
return - EIO ;
}
return count ;
}
static ssize_t
ds1307_nvram_write ( struct kobject * kobj , struct bin_attribute * attr ,
char * buf , loff_t off , size_t count )
{
struct i2c_client * client ;
u8 buffer [ NVRAM_SIZE + 1 ] ;
int ret ;
2008-02-06 12:38:55 +03:00
client = kobj_to_i2c_client ( kobj ) ;
2007-11-15 03:58:32 +03:00
if ( unlikely ( off > = NVRAM_SIZE ) )
return - EFBIG ;
if ( ( off + count ) > NVRAM_SIZE )
count = NVRAM_SIZE - off ;
if ( unlikely ( ! count ) )
return count ;
buffer [ 0 ] = 8 + off ;
memcpy ( buffer + 1 , buf , count ) ;
ret = i2c_master_send ( client , buffer , count + 1 ) ;
return ( ret < 0 ) ? ret : ( ret - 1 ) ;
}
static struct bin_attribute nvram = {
. attr = {
. name = " nvram " ,
. mode = S_IRUGO | S_IWUSR ,
. owner = THIS_MODULE ,
} ,
. read = ds1307_nvram_read ,
. write = ds1307_nvram_write ,
. size = NVRAM_SIZE ,
} ;
/*----------------------------------------------------------------------*/
2006-06-25 16:48:17 +04:00
static struct i2c_driver ds1307_driver ;
2008-04-30 01:11:39 +04:00
static int __devinit ds1307_probe ( struct i2c_client * client ,
const struct i2c_device_id * id )
2006-06-25 16:48:17 +04:00
{
struct ds1307 * ds1307 ;
int err = - ENODEV ;
int tmp ;
2008-04-30 01:11:40 +04:00
const struct chip_desc * chip = & chips [ id - > driver_data ] ;
2007-07-17 15:05:10 +04:00
struct i2c_adapter * adapter = to_i2c_adapter ( client - > dev . parent ) ;
2006-06-25 16:48:17 +04:00
2007-07-17 15:05:10 +04:00
if ( ! i2c_check_functionality ( adapter ,
I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA ) )
return - EIO ;
if ( ! ( ds1307 = kzalloc ( sizeof ( struct ds1307 ) , GFP_KERNEL ) ) )
return - ENOMEM ;
2007-07-17 15:04:55 +04:00
ds1307 - > client = client ;
2006-06-25 16:48:17 +04:00
i2c_set_clientdata ( client , ds1307 ) ;
ds1307 - > msg [ 0 ] . addr = client - > addr ;
ds1307 - > msg [ 0 ] . flags = 0 ;
ds1307 - > msg [ 0 ] . len = 1 ;
ds1307 - > msg [ 0 ] . buf = & ds1307 - > reg_addr ;
ds1307 - > msg [ 1 ] . addr = client - > addr ;
ds1307 - > msg [ 1 ] . flags = I2C_M_RD ;
ds1307 - > msg [ 1 ] . len = sizeof ( ds1307 - > regs ) ;
ds1307 - > msg [ 1 ] . buf = ds1307 - > regs ;
2008-04-30 01:11:40 +04:00
ds1307 - > type = id - > driver_data ;
2007-07-17 15:04:55 +04:00
switch ( ds1307 - > type ) {
case ds_1337 :
case ds_1339 :
2006-06-25 16:48:17 +04:00
ds1307 - > reg_addr = DS1337_REG_CONTROL ;
ds1307 - > msg [ 1 ] . len = 2 ;
2007-07-17 15:05:06 +04:00
/* get registers that the "rtc" read below won't read... */
2007-07-17 15:04:55 +04:00
tmp = i2c_transfer ( adapter , ds1307 - > msg , 2 ) ;
2006-06-25 16:48:17 +04:00
if ( tmp ! = 2 ) {
pr_debug ( " read error %d \n " , tmp ) ;
err = - EIO ;
goto exit_free ;
}
ds1307 - > reg_addr = 0 ;
ds1307 - > msg [ 1 ] . len = sizeof ( ds1307 - > regs ) ;
2007-07-17 15:05:06 +04:00
/* oscillator off? turn it on, so clock can tick. */
if ( ds1307 - > regs [ 0 ] & DS1337_BIT_nEOSC )
i2c_smbus_write_byte_data ( client , DS1337_REG_CONTROL ,
ds1307 - > regs [ 0 ] & ~ DS1337_BIT_nEOSC ) ;
/* oscillator fault? clear flag, and warn */
if ( ds1307 - > regs [ 1 ] & DS1337_BIT_OSF ) {
i2c_smbus_write_byte_data ( client , DS1337_REG_STATUS ,
ds1307 - > regs [ 1 ] & ~ DS1337_BIT_OSF ) ;
dev_warn ( & client - > dev , " SET TIME! \n " ) ;
2006-06-25 16:48:17 +04:00
}
2007-07-17 15:04:55 +04:00
break ;
default :
break ;
}
2006-06-25 16:48:17 +04:00
read_rtc :
/* read RTC registers */
2007-07-17 15:04:55 +04:00
tmp = i2c_transfer ( adapter , ds1307 - > msg , 2 ) ;
2006-06-25 16:48:17 +04:00
if ( tmp ! = 2 ) {
pr_debug ( " read error %d \n " , tmp ) ;
err = - EIO ;
goto exit_free ;
}
/* minimal sanity checking; some chips (like DS1340) don't
* specify the extra bits as must - be - zero , but there are
* still a few values that are clearly out - of - range .
*/
tmp = ds1307 - > regs [ DS1307_REG_SECS ] ;
2007-07-17 15:04:55 +04:00
switch ( ds1307 - > type ) {
case ds_1307 :
case m41t00 :
2007-07-17 15:05:06 +04:00
/* clock halted? turn it on, so clock can tick. */
2007-07-17 15:04:55 +04:00
if ( tmp & DS1307_BIT_CH ) {
2007-07-17 15:05:06 +04:00
i2c_smbus_write_byte_data ( client , DS1307_REG_SECS , 0 ) ;
dev_warn ( & client - > dev , " SET TIME! \n " ) ;
2007-07-17 15:04:55 +04:00
goto read_rtc ;
2006-06-25 16:48:17 +04:00
}
2007-07-17 15:04:55 +04:00
break ;
2007-07-17 15:05:06 +04:00
case ds_1338 :
/* clock halted? turn it on, so clock can tick. */
2007-07-17 15:04:55 +04:00
if ( tmp & DS1307_BIT_CH )
2007-07-17 15:05:06 +04:00
i2c_smbus_write_byte_data ( client , DS1307_REG_SECS , 0 ) ;
/* oscillator fault? clear flag, and warn */
if ( ds1307 - > regs [ DS1307_REG_CONTROL ] & DS1338_BIT_OSF ) {
i2c_smbus_write_byte_data ( client , DS1307_REG_CONTROL ,
2007-07-26 21:41:00 +04:00
ds1307 - > regs [ DS1307_REG_CONTROL ]
2007-07-17 15:05:06 +04:00
& ~ DS1338_BIT_OSF ) ;
dev_warn ( & client - > dev , " SET TIME! \n " ) ;
goto read_rtc ;
}
2007-07-17 15:04:55 +04:00
break ;
2008-02-06 12:38:55 +03:00
case ds_1340 :
/* clock halted? turn it on, so clock can tick. */
if ( tmp & DS1340_BIT_nEOSC )
i2c_smbus_write_byte_data ( client , DS1307_REG_SECS , 0 ) ;
tmp = i2c_smbus_read_byte_data ( client , DS1340_REG_FLAG ) ;
if ( tmp < 0 ) {
pr_debug ( " read error %d \n " , tmp ) ;
err = - EIO ;
goto exit_free ;
}
/* oscillator fault? clear flag, and warn */
if ( tmp & DS1340_BIT_OSF ) {
i2c_smbus_write_byte_data ( client , DS1340_REG_FLAG , 0 ) ;
dev_warn ( & client - > dev , " SET TIME! \n " ) ;
}
break ;
2007-07-17 15:05:10 +04:00
case ds_1337 :
case ds_1339 :
2007-07-17 15:04:55 +04:00
break ;
2006-06-25 16:48:17 +04:00
}
2007-07-17 15:04:55 +04:00
tmp = ds1307 - > regs [ DS1307_REG_SECS ] ;
2006-06-25 16:48:17 +04:00
tmp = BCD2BIN ( tmp & 0x7f ) ;
if ( tmp > 60 )
2007-07-17 15:05:10 +04:00
goto exit_bad ;
2006-06-25 16:48:17 +04:00
tmp = BCD2BIN ( ds1307 - > regs [ DS1307_REG_MIN ] & 0x7f ) ;
if ( tmp > 60 )
2007-07-17 15:05:10 +04:00
goto exit_bad ;
2006-06-25 16:48:17 +04:00
tmp = BCD2BIN ( ds1307 - > regs [ DS1307_REG_MDAY ] & 0x3f ) ;
if ( tmp = = 0 | | tmp > 31 )
2007-07-17 15:05:10 +04:00
goto exit_bad ;
2006-06-25 16:48:17 +04:00
tmp = BCD2BIN ( ds1307 - > regs [ DS1307_REG_MONTH ] & 0x1f ) ;
if ( tmp = = 0 | | tmp > 12 )
2007-07-17 15:05:10 +04:00
goto exit_bad ;
2006-06-25 16:48:17 +04:00
tmp = ds1307 - > regs [ DS1307_REG_HOUR ] ;
2007-07-17 15:05:10 +04:00
switch ( ds1307 - > type ) {
case ds_1340 :
case m41t00 :
/* NOTE: ignores century bits; fix before deploying
* systems that will run through year 2100.
*/
break ;
default :
if ( ! ( tmp & DS1307_BIT_12HR ) )
break ;
/* Be sure we're in 24 hour mode. Multi-master systems
* take note . . .
*/
tmp = BCD2BIN ( tmp & 0x1f ) ;
if ( tmp = = 12 )
tmp = 0 ;
if ( ds1307 - > regs [ DS1307_REG_HOUR ] & DS1307_BIT_PM )
tmp + = 12 ;
2006-06-25 16:48:17 +04:00
i2c_smbus_write_byte_data ( client ,
DS1307_REG_HOUR ,
BIN2BCD ( tmp ) ) ;
}
ds1307 - > rtc = rtc_device_register ( client - > name , & client - > dev ,
& ds13xx_rtc_ops , THIS_MODULE ) ;
if ( IS_ERR ( ds1307 - > rtc ) ) {
err = PTR_ERR ( ds1307 - > rtc ) ;
dev_err ( & client - > dev ,
" unable to register the class device \n " ) ;
2007-07-17 15:05:10 +04:00
goto exit_free ;
2006-06-25 16:48:17 +04:00
}
2007-11-15 03:58:32 +03:00
if ( chip - > nvram56 ) {
err = sysfs_create_bin_file ( & client - > dev . kobj , & nvram ) ;
if ( err = = 0 ) {
ds1307 - > has_nvram = true ;
dev_info ( & client - > dev , " 56 bytes nvram \n " ) ;
}
}
2006-06-25 16:48:17 +04:00
return 0 ;
2007-07-17 15:05:10 +04:00
exit_bad :
dev_dbg ( & client - > dev , " %s: %02x %02x %02x %02x %02x %02x %02x \n " ,
" bogus register " ,
ds1307 - > regs [ 0 ] , ds1307 - > regs [ 1 ] ,
ds1307 - > regs [ 2 ] , ds1307 - > regs [ 3 ] ,
ds1307 - > regs [ 4 ] , ds1307 - > regs [ 5 ] ,
ds1307 - > regs [ 6 ] ) ;
2006-06-25 16:48:17 +04:00
exit_free :
kfree ( ds1307 ) ;
return err ;
}
2007-07-17 15:05:10 +04:00
static int __devexit ds1307_remove ( struct i2c_client * client )
2006-06-25 16:48:17 +04:00
{
struct ds1307 * ds1307 = i2c_get_clientdata ( client ) ;
2007-11-15 03:58:32 +03:00
if ( ds1307 - > has_nvram )
sysfs_remove_bin_file ( & client - > dev . kobj , & nvram ) ;
2006-06-25 16:48:17 +04:00
rtc_device_unregister ( ds1307 - > rtc ) ;
kfree ( ds1307 ) ;
return 0 ;
}
static struct i2c_driver ds1307_driver = {
. driver = {
2007-07-17 15:05:10 +04:00
. name = " rtc-ds1307 " ,
2006-06-25 16:48:17 +04:00
. owner = THIS_MODULE ,
} ,
2007-07-17 15:05:10 +04:00
. probe = ds1307_probe ,
. remove = __devexit_p ( ds1307_remove ) ,
2008-04-30 01:11:40 +04:00
. id_table = ds1307_id ,
2006-06-25 16:48:17 +04:00
} ;
static int __init ds1307_init ( void )
{
return i2c_add_driver ( & ds1307_driver ) ;
}
module_init ( ds1307_init ) ;
static void __exit ds1307_exit ( void )
{
i2c_del_driver ( & ds1307_driver ) ;
}
module_exit ( ds1307_exit ) ;
MODULE_DESCRIPTION ( " RTC driver for DS1307 and similar chips " ) ;
MODULE_LICENSE ( " GPL " ) ;