linux/drivers/rtc/rtc-em3027.c
<<
" " " o/spa> " ospa> class="lxr_search">" ="+search" method="post" onsubmit="return do_search(this);">" " " Search " ospa> class="lxr_prefs" " " o/spa> < ="ajax+*" method="post" onsubmit="return false;">" oinput typ="vhidden" nam="vajax_lookup" id"vajax_lookup" alue="v">" <
odiv id"vfile_contents"
< <1o/a>ospa> class="comment">/*o/spa>
 < <2o/a>ospa> class="comment"> * An rtc/i2c driver for the EM Microelectronic EM3027o/spa>
 < <3o/a>ospa> class="comment"> * Copyright 2011 CompuLab, Ltd.o/spa>
 < <4o/a>ospa> class="comment"> *o/spa>
 < <5o/a>ospa> class="comment"> * Author: Mike Rapoport <mike@compulab.co.il>o/spa>
 < <6o/a>ospa> class="comment"> *o/spa>
 < <7o/a>ospa> class="comment"> * Based on rtc-ds1672.c by Alessandro Zummo <a.zummo@towertech.it>o/spa>
 < <8o/a>ospa> class="comment"> *o/spa>
 < <9o/a>ospa> class="comment"> * This program is free software; you ca> redistribute it and/or modifyo/spa>
 < 1ospa> class="comment"> * it under the terms of the GNU General Public License verson v2 aso/spa>
 < 11o/a>ospa> class="comment"> * published by the Free Software Foundaion>.o/spa>
 < 12o/a>ospa> class="comment"> */o/spa>
 < 13o/a> < 14o/a>#include <linux/i2c.ho/a>> < 15o/a>#include <linux/rtc.ho/a>> < 16o/a>#include <linux/bcd.ho/a>> < 17o/a>#include <linux/module.ho/a>> < 18o/a> < 19o/a>ospa> class="comment">/* Registers */o/spa>
 < 2#defineEM3027_REG_ON_OFF_CTRL/oa>  0x00 < 21/oa>#defineEM3027_REG_IRQ_CTRL/oa>     0x01 < 22/oa>#defineEM3027_REG_IRQ_FLAGS/oa>    0x02 < 23/oa>#defineEM3027_REG_STATUS/oa>       0x03 < 24/oa>#defineEM3027_REG_RST_CTRL/oa>     0x04 < 25o/a> < 26/oa>#defineEM3027_REG_WATCH_SEC/oa>    0x08 < 27/oa>#defineEM3027_REG_WATCH_MIN/oa>    0x09 < 28/oa>#defineEM3027_REG_WATCH_HOUR/oa>   0x0a < 29/oa>#defineEM3027_REG_WATCH_DATE/oa>   0x0b < 3#defineEM3027_REG_WATCH_DAY/oa>    0x0c < 31/oa>#defineEM3027_REG_WATCH_MON/oa>    0x0d < 32/oa>#defineEM3027_REG_WATCH_YEAR/oa>   0x0e < 33o/a> < 34/oa>#defineEM3027_REG_ALARM_SEC/oa>    0x10 < 35/oa>#defineEM3027_REG_ALARM_MIN/oa>    0x11 < 36/oa>#defineEM3027_REG_ALARM_HOUR/oa>   0x12 < 37/oa>#defineEM3027_REG_ALARM_DATE/oa>   0x13 < 38/oa>#defineEM3027_REG_ALARM_DAY/oa>    0x14 < 39/oa>#defineEM3027_REG_ALARM_MON/oa>    0x15 < 4#defineEM3027_REG_ALARM_YEAR/oa>   0x16 < 41o/a> < 42/oa>static structi2c_driver/oa> oa href="+code=em3027_driver" class="sref">em3027_driver/oa>; < 43o/a> < 44/oa>static intem3027_get_time/oa>(structdevice/oa> *oa href="+code=dev" class="sref">dev/oa>, structrtc_time/oa> *oa href="+code=tm" class="sref">tm/oa>) < 45/oa>{ < 46/oa>        structi2c_client/oa> *oa href="+code=client" class="sref">client/oa> =to_i2c_client/oa>(oa href="+code=dev" class="sref">dev/oa>); < 47o/a> < 48/oa>        unsigned charaddr/oa> =EM3027_REG_WATCH_SEC/oa>; < 49/oa>        unsigned charbuf/oa>[7]; < 50o/a> < 51/oa>        structi2c_msg/oa> oa href="+code=msgs" class="sref">msgs/oa>[] =<{ < 52/oa>                {oa href="+code=client" class="sref">client/oa>->oa href="+code=addr" class="sref">addr/oa>, 0, 1, &oa href="+code=addr" class="sref">addr/oa>},            ospa> class="comment">/* setup read addr */o/spa>
 < 53/oa>                {oa href="+code=client" class="sref">client/oa>->oa href="+code=addr" class="sref">addr/oa>, oa href="+code=I2C_M_RD" class="sref">I2C_M_RD/oa>, 7, oa href="+code=buf" class="sref">buf/oa>},       ospa> class="comment">/* read time/date */o/spa>
 < 54/oa>        }; < 55o/a> < 56/oa>        ospa> class="comment">/* read time/date registers */o/spa>
 < 57/oa>        if ((oa href="+code=i2c_transfer" class="sref">i2c_transfer/oa>(oa href="+code=client" class="sref">client/oa>->oa href="+code=adapter" class="sref">adapter/oa>, &oa href="+code=msgs" class="sref">msgs/oa>[0], 2)) != 2)<{ < 58/oa>                oa href="+code=dev_err" class="sref">dev_err/oa>(&oa href="+code=client" class="sref">client/oa>->oa href="+code=dev" class="sref">dev/oa>, ospa> class="string">"%s: read error\n"o/spa>
, oa href="+code=__func__" class="sref">__func__/oa>); < 59/oa>                return -oa href="+code=EIO" class="sref">EIO/oa>; < 60/oa>        } < 61o/a> < 62/oa>        oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_sec" class="sref">tm_sec/oa>      =bcd2bin/oa>(oa href="+code=buf" class="sref">buf/oa>[0]); < 63/oa>        oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_min" class="sref">tm_min/oa>      =bcd2bin/oa>(oa href="+code=buf" class="sref">buf/oa>[1]); < 64/oa>        oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_hour" class="sref">tm_hour/oa>     =bcd2bin/oa>(oa href="+code=buf" class="sref">buf/oa>[2]); < 65/oa>        oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_mday" class="sref">tm_mday/oa>     =bcd2bin/oa>(oa href="+code=buf" class="sref">buf/oa>[3]); < 66/oa>        oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_wday" class="sref">tm_wday/oa>     =bcd2bin/oa>(oa href="+code=buf" class="sref">buf/oa>[4]); < 67/oa>        oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_mon" class="sref">tm_mon/oa>      =bcd2bin/oa>(oa href="+code=buf" class="sref">buf/oa>[5]); < 68/oa>        oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_year" class="sref">tm_year/oa>     =bcd2bin/oa>(oa href="+code=buf" class="sref">buf/oa>[6]) + 100; < 69o/a> < 70/oa>        return 0; < 71o/a>} < 72o/a> < 73/oa>static intem3027_set_time/oa>(structdevice/oa> *oa href="+code=dev" class="sref">dev/oa>, structrtc_time/oa> *oa href="+code=tm" class="sref">tm/oa>) < 74/oa>{ < 75/oa>        structi2c_client/oa> *oa href="+code=client" class="sref">client/oa> =to_i2c_client/oa>(oa href="+code=dev" class="sref">dev/oa>); < 76/oa>        unsigned charbuf/oa>[8]; < 77o/a> < 78/oa>        structi2c_msg/oa> oa href="+code=msg" class="sref">msg/oa> =<{ < 79/oa>                oa href="+code=client" class="sref">client/oa>->oa href="+code=addr" class="sref">addr/oa>, 0, 8, oa href="+code=buf" class="sref">buf/oa>,        ospa> class="comment">/* write time/date */o/spa>
 < 80/oa>        }; < 81o/a> < 82/oa>        oa href="+code=buf" class="sref">buf/oa>[0] =EM3027_REG_WATCH_SEC/oa>; < 83/oa>        oa href="+code=buf" class="sref">buf/oa>[1] =bin2bcd/oa>(oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_sec" class="sref">tm_sec/oa>); < 84/oa>        oa href="+code=buf" class="sref">buf/oa>[2] =bin2bcd/oa>(oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_min" class="sref">tm_min/oa>); < 85/oa>        oa href="+code=buf" class="sref">buf/oa>[3] =bin2bcd/oa>(oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_hour" class="sref">tm_hour/oa>); < 86/oa>        oa href="+code=buf" class="sref">buf/oa>[4] =bin2bcd/oa>(oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_mday" class="sref">tm_mday/oa>); < 87/oa>        oa href="+code=buf" class="sref">buf/oa>[5] =bin2bcd/oa>(oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_wday" class="sref">tm_wday/oa>); < 88/oa>        oa href="+code=buf" class="sref">buf/oa>[6] =bin2bcd/oa>(oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_mon" class="sref">tm_mon/oa>); < 89/oa>        oa href="+code=buf" class="sref">buf/oa>[7] =bin2bcd/oa>(oa href="+code=tm" class="sref">tm/oa>->oa href="+code=tm_year" class="sref">tm_year/oa> % 100); < 90o/a> < 91/oa>        ospa> class="comment">/* write time/date registers */o/spa>
 < 92/oa>        if ((oa href="+code=i2c_transfer" class="sref">i2c_transfer/oa>(oa href="+code=client" class="sref">client/oa>->oa href="+code=adapter" class="sref">adapter/oa>, &oa href="+code=msg" class="sref">msg/oa>, 1)) != 1)<{ < 93/oa>                oa href="+code=dev_err" class="sref">dev_err/oa>(&oa href="+code=client" class="sref">client/oa>->oa href="+code=dev" class="sref">dev/oa>, ospa> class="string">"%s: write error\n"o/spa>
, oa href="+code=__func__" class="sref">__func__/oa>); < 94/oa>                return -oa href="+code=EIO" class="sref">EIO/oa>; < 95/oa>        } < 96o/a> < 97/oa>        return 0; < 98o/a>} < 99o/a> <100/oa>static const structrtc_class_ops/oa> oa href="+code=em3027_rtc_ops" class="sref">em3027_rtc_ops/oa> =<{ <101/oa>        .oa href="+code=read_time" class="sref">read_time/oa> =em3027_get_time/oa>, <102/oa>        .oa href="+code=set_time" class="sref">set_time/oa> =em3027_set_time/oa>, <103/oa>}; <104o/a> <105/oa>static intem3027_probe/oa>(structi2c_client/oa> *oa href="+code=client" class="sref">client/oa>, <106/oa>                        const structi2c_device_id/oa> *oa href="+code=id" class="sref">id/oa>) <107/oa>{ <108/oa>        structrtc_device/oa> *oa href="+code=rtc" class="sref">rtc/oa>; <109o/a> <110/oa>        if (!oa href="+code=i2c_check_funcion>ality" class="sref">i2c_check_funcion>ality/oa>(oa href="+code=client" class="sref">client/oa>->oa href="+code=adapter" class="sref">adapter/oa>, oa href="+code=I2C_FUNC_I2C" class="sref">I2C_FUNC_I2C/oa>)) <111/oa>                return -oa href="+code=ENODEV" class="sref">ENODEV/oa>; <112o/a> <113/oa>        oa href="+code=rtc" class="sref">rtc/oa> =rtc_device_register/oa>(oa href="+code=em3027_driver" class="sref">em3027_driver/oa>.oa href="+code=driver" class="sref">driver/oa>.oa href="+code=nam=" class="sref">nam=/oa>, &oa href="+code=client" class="sref">client/oa>->oa href="+code=dev" class="sref">dev/oa>, <114/oa>                                  &oa href="+code=em3027_rtc_ops" class="sref">em3027_rtc_ops/oa>, oa href="+code=THIS_MODULE" class="sref">THIS_MODULE/oa>); <115/oa>        if (oa href="+code=IS_ERR" class="sref">IS_ERR/oa>(oa href="+code=rtc" class="sref">rtc/oa>)) <116/oa>                return oa href="+code=PTR_ERR" class="sref">PTR_ERR/oa>(oa href="+code=rtc" class="sref">rtc/oa>); <117o/a> <118/oa>        oa href="+code=i2c_set_clientdata" class="sref">i2c_set_clientdata/oa>(oa href="+code=client" class="sref">client/oa>, oa href="+code=rtc" class="sref">rtc/oa>); <119o/a> <120/oa>        return 0; <121o/a>} <122o/a> <123/oa>static intem3027_remove/oa>(structi2c_client/oa> *oa href="+code=client" class="sref">client/oa>) <124/oa>{ <125/oa>        structrtc_device/oa> *oa href="+code=rtc" class="sref">rtc/oa> =i2c_get_clientdata/oa>(oa href="+code=client" class="sref">client/oa>); <126o/a> <127/oa>        if (oa href="+code=rtc" class="sref">rtc/oa>) <128/oa>                oa href="+code=rtc_device_unregister" class="sref">rtc_device_unregister/oa>(oa href="+code=rtc" class="sref">rtc/oa>); <129o/a> <130/oa>        return 0; <131o/a>} <132o/a> <133/oa>static structi2c_device_id/oa> oa href="+code=em3027_id" class="sref">em3027_id/oa>[] =<{ <134/oa>        { ospa> class="string">"em3027"o/spa>
, 0 }, <135/oa>        { } <136/oa>}; <137o/a> <138/oa>static structi2c_driver/oa> oa href="+code=em3027_driver" class="sref">em3027_driver/oa> =<{ <139/oa>        .oa href="+code=driver" class="sref">driver/oa> =<{ <140/oa>                   .oa href="+code=nam=" class="sref">nam=/oa> = class="string">"rtc-em3027"o/spa>
, <141/oa>        }, <142/oa>        .oa href="+code=probe" class="sref">probe/oa> =<&oa href="+code=em3027_probe" class="sref">em3027_probe/oa>, <143/oa>        .oa href="+code=remove" class="sref">remove/oa> =<&oa href="+code=em3027_remove" class="sref">em3027_remove/oa>, <144/oa>        .oa href="+code=id_table" class="sref">id_table/oa> =em3027_id/oa>, <145/oa>}; <146o/a> <147o/a>oa href="+code=module_i2c_driver" class="sref">module_i2c_driver/oa>(oa href="+code=em3027_driver" class="sref">em3027_driver/oa>); <148o/a> <149/oa>oa href="+code=MODULE_AUTHOR" class="sref">MODULE_AUTHOR/oa>(ospa> class="string">"Mike Rapoport <mike@compulab.co.il>"o/spa>
); <150o/a>oa href="+code=MODULE_DESCRIPTION" class="sref">MODULE_DESCRIPTION/oa>(ospa> class="string">"EM Microelectronic EM3027 RTC driver"o/spa>
); <151/oa>oa href="+code=MODULE_LICENSE" class="sref">MODULE_LICENSE/oa>(ospa> class="string">"GPL"o/spa>
); <152/oa>
The original LXR software by the LXR community/oa>, this experimental verson vby lxr@linux.no/oa>. o/div odiv class="subfooter"> lxr.linux.no kindly hostedvby Redpill Linpro AS/oa>, provider of Linux consulting and operaion>s services since 1995. o/div o/body o/html