linux/drivers/rtc/rtc-max8998.c
<<
> opt/spa opt/form opta > op href="../linux+v3.9.6/drivers/rtc/rtc-max8998.c"> > optimg src="../.static/gfx/right.png" alt=">>"> >t/spa >tspa class="lxr_search"> > ="+search" method="post" onsubmit="return do_search(this);"> > optinput typv2.hidden" namv2.navtarget" ue="v2."> > optinput typv2.text" namv2.search" id2.search"> > optbuttvaltypv2.submit">Searchtspa class="lxr_prefs" opta href="+prefs?return=drivers/rtc/rtc-max8998.c" > op onclick="return ajax_prefs();"> > opPrefs opt/a> >t/spa op pt/div op ptform acn> ="ajax+*" method="post" onsubmit="return false;"> >tinput typv2.hidden" namv2.ajax_lookup" id2.ajax_lookup" ue="v2."> op pt/form op ptdiv class="headingbottvm">
tdiv id2.file_contents"
p p1t/a>tspa  class="comment">/*t/spa  
p p2t/a>tspa  class="comment"> * RTC driver for Maxim MAX8998t/spa  
p p3t/a>tspa  class="comment"> *t/spa  
p p4t/a>tspa  class="comment"> * Copyright (C) 2010 Samsung Electronics Co.Ltdt/spa  
p p5t/a>tspa  class="comment"> * Author: Minkyu Kang <mk7.kang@samsung.com>t/spa  
p p6t/a>tspa  class="comment"> * Author: Joonyoung Shim <jy0922.shim@samsung.com>t/spa  
p p7t/a>tspa  class="comment"> *t/spa  
p p8t/a>tspa  class="comment"> *  This program is free software; you ca  redistribute  it and/or modify itt/spa  
p p9t/a>tspa  class="comment"> *  under  the terms of  the GNU GeneralopPublic License as published by thet/spa  
p 3"
	a>tspa  class="comment"> *  Free Software Foundan>
 ;  either vers val2 of the  License, or (at yourt/spa  
p 11t/a>tspa  class="comment"> *  ion>
 ) any later vers va.t/spa  
p 12t/a>tspa  class="comment"> *t/spa  
p 13t/a>tspa  class="comment"> */t/spa  
p 14t/a>
p 15t/a>#include <linux/module.ht/a>>
p 16t/a>#include <linux/i2c.ht/a>>
p 17t/a>#include <linux/slab.ht/a>>
p 18t/a>#include <linux/bcd.ht/a>>
p 19t/a>#include <linux/rtc.ht/a>>
p 20t/a>#include <linux/platform_device.ht/a>>
p 21t/a>#include <linux/mfd/max8998.ht/a>>
p 22t/a>#include <linux/mfd/max8998-private.ht/a>>
p 23t/a>#include <linux/delay.ht/a>>
p 24t/a>
p 25t/a>#definepta href="+code=MAX8998_RTC_SEC" class="sref">MAX8998_RTC_SECt/a>                 0x00
p 26t/a>#definepta href="+code=MAX8998_RTC_MIN" class="sref">MAX8998_RTC_MINt/a>                 0x01
p 27t/a>#definepta href="+code=MAX8998_RTC_HOUR" class="sref">MAX8998_RTC_HOURt/a>                0x02
p 28t/a>#definepta href="+code=MAX8998_RTC_WEEKDAY" class="sref">MAX8998_RTC_WEEKDAYt/a>             0x03
p 29t/a>#definepta href="+code=MAX8998_RTC_DATE" class="sref">MAX8998_RTC_DATEt/a>                0x04
p 30t/a>#definepta href="+code=MAX8998_RTC_MONTH" class="sref">MAX8998_RTC_MONTHt/a>               0x05
p 31t/a>#definepta href="+code=MAX8998_RTC_YEAR1" class="sref">MAX8998_RTC_YEAR1t/a>               0x06
p 32t/a>#definepta href="+code=MAX8998_RTC_YEAR2" class="sref">MAX8998_RTC_YEAR2t/a>               0x07
p 33t/a>#definepta href="+code=MAX8998_ALARM0_SEC" class="sref">MAX8998_ALARM0_SECt/a>              0x08
p 34t/a>#definepta href="+code=MAX8998_ALARM0_MIN" class="sref">MAX8998_ALARM0_MINt/a>              0x09
p 35t/a>#definepta href="+code=MAX8998_ALARM0_HOUR" class="sref">MAX8998_ALARM0_HOURt/a>             0x0a
p 36t/a>#definepta href="+code=MAX8998_ALARM0_WEEKDAY" class="sref">MAX8998_ALARM0_WEEKDAYt/a>          0x0b
p 37t/a>#definepta href="+code=MAX8998_ALARM0_DATE" class="sref">MAX8998_ALARM0_DATEt/a>             0x0c
p 38t/a>#definepta href="+code=MAX8998_ALARM0_MONTH" class="sref">MAX8998_ALARM0_MONTHt/a>            0x0d
p 39t/a>#definepta href="+code=MAX8998_ALARM0_YEAR1" class="sref">MAX8998_ALARM0_YEAR1t/a>            0x0e
p 40t/a>#definepta href="+code=MAX8998_ALARM0_YEAR2" class="sref">MAX8998_ALARM0_YEAR2t/a>            0x0f
p 41t/a>#definepta href="+code=MAX8998_ALARM1_SEC" class="sref">MAX8998_ALARM1_SECt/a>              0x10
p 42t/a>#definepta href="+code=MAX8998_ALARM1_MIN" class="sref">MAX8998_ALARM1_MINt/a>              0x11
p 43t/a>#definepta href="+code=MAX8998_ALARM1_HOUR" class="sref">MAX8998_ALARM1_HOURt/a>             0x12
p 44t/a>#definepta href="+code=MAX8998_ALARM1_WEEKDAY" class="sref">MAX8998_ALARM1_WEEKDAYt/a>          0x13
p 45t/a>#definepta href="+code=MAX8998_ALARM1_DATE" class="sref">MAX8998_ALARM1_DATEt/a>             0x14
p 46t/a>#definepta href="+code=MAX8998_ALARM1_MONTH" class="sref">MAX8998_ALARM1_MONTHt/a>            0x15
p 47t/a>#definepta href="+code=MAX8998_ALARM1_YEAR1" class="sref">MAX8998_ALARM1_YEAR1t/a>            0x16
p 48t/a>#definepta href="+code=MAX8998_ALARM1_YEAR2" class="sref">MAX8998_ALARM1_YEAR2t/a>            0x17
p 49t/a>#definepta href="+code=MAX8998_ALARM0_CONF" class="sref">MAX8998_ALARM0_CONFt/a>             0x18
p 50t/a>#definepta href="+code=MAX8998_ALARM1_CONF" class="sref">MAX8998_ALARM1_CONFt/a>             0x19
p 51t/a>#definepta href="+code=MAX8998_RTC_STATUS" class="sref">MAX8998_RTC_STATUSt/a>              0x1a
p 52t/a>#definepta href="+code=MAX8998_WTSR_SMPL_CNTL" class="sref">MAX8998_WTSR_SMPL_CNTLt/a>          0x1b
p 53t/a>#definepta href="+code=MAX8998_TEST" class="sref">MAX8998_TESTt/a>                    0x1f
p 54t/a>
p 55t/a>#definepta href="+code=HOUR_12" class="sref">HOUR_12t/a>                         (1 << 7)
p 56t/a>#definepta href="+code=HOUR_PM" class="sref">HOUR_PMt/a>                         (1 << 5)
p 57t/a>#definepta href="+code=ALARM0_STATUS" class="sref">ALARM0_STATUSt/a>                   (1 << 1)
p 58t/a>#definepta href="+code=ALARM1_STATUS" class="sref">ALARM1_STATUSt/a>                   (1 << 2)
p 59t/a>
p 60t/a>enum {
p 61t/a>        ta href="+code=RTC_SEC" class="sref">RTC_SECt/a> = 0,
p 62t/a>        ta href="+code=RTC_MIN" class="sref">RTC_MINt/a>,
p 63t/a>        ta href="+code=RTC_HOUR" class="sref">RTC_HOURt/a>,
p 64t/a>        ta href="+code=RTC_WEEKDAY" class="sref">RTC_WEEKDAYt/a>,
p 65t/a>        ta href="+code=RTC_DATE" class="sref">RTC_DATEt/a>,
p 66t/a>        ta href="+code=RTC_MONTH" class="sref">RTC_MONTHt/a>,
p 67t/a>        ta href="+code=RTC_YEAR1" class="sref">RTC_YEAR1t/a>,
p 68t/a>        ta href="+code=RTC_YEAR2" class="sref">RTC_YEAR2t/a>,
p 69t/a>};
p 70t/a>
p 71t/a>struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> {
p 72t/a>        struct ta href="+code=device" class="sref">devicet/a>           *ta href="+code=dev" class="sref">devt/a>;
p 73t/a>        struct ta href="+code=max8998_dev" class="sref">max8998_devt/a>      *ta href="+code=max8998" class="sref">max8998t/a>;
p 74t/a>        struct ta href="+code=i2c_client" class="sref">i2c_clientt/a>       *ta href="+code=rtc" class="sref">rtct/a>;
p 75t/a>        struct ta href="+code=rtc_device" class="sref">rtc_devicet/a>       *ta href="+code=rtc_dev" class="sref">rtc_devt/a>;
p 76t/a>        int ta href="+code=irq" class="sref">irqt/a>;
p 77t/a>        ta href="+code=bool" class="sref">boolt/a> ta href="+code=lp3974_bug_workaround" class="sref">lp3974_bug_workaroundt/a>;
p 78t/a>};
p 79t/a>
p 80t/a>static void ta href="+code=max8998_data_to_tm" class="sref">max8998_data_to_tmt/a>(ta href="+code=u8" class="sref">u8t/a> *ta href="+code=data" class="sref">datat/a>, struct ta href="+code=rtc_time" class="sref">rtc_timet/a> *ta href="+code=tm" class="sref">tmt/a>)
p 81t/a>{
p 82t/a>        ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_sec" class="sref">tm_sect/a> = ta href="+code=bcd2bin" class="sref">bcd2bint/a>(ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_SEC" class="sref">RTC_SECt/a>]);
p 83t/a>        ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_min" class="sref">tm_mint/a> = ta href="+code=bcd2bin" class="sref">bcd2bint/a>(ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_MIN" class="sref">RTC_MINt/a>]);
p 84t/a>        if (ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_HOUR" class="sref">RTC_HOURt/a>] &pta href="+code=HOUR_12" class="sref">HOUR_12t/a>) {
p 85t/a>                ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_hour" class="sref">tm_hourt/a> = ta href="+code=bcd2bin" class="sref">bcd2bint/a>(ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_HOUR" class="sref">RTC_HOURt/a>] &p0x1f);
p 86t/a>                if (ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_HOUR" class="sref">RTC_HOURt/a>] &pta href="+code=HOUR_PM" class="sref">HOUR_PMt/a>)
p 87t/a>                        ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_hour" class="sref">tm_hourt/a> += 12;
p 88t/a>        } else
p 89t/a>                ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_hour" class="sref">tm_hourt/a> = ta href="+code=bcd2bin" class="sref">bcd2bint/a>(ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_HOUR" class="sref">RTC_HOURt/a>] &p0x3f);
p 90t/a>
p 91t/a>        ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_wday" class="sref">tm_wdayt/a> = ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_WEEKDAY" class="sref">RTC_WEEKDAYt/a>] &p0x07;
p 92t/a>        ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_mday" class="sref">tm_mdayt/a> = ta href="+code=bcd2bin" class="sref">bcd2bint/a>(ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_DATE" class="sref">RTC_DATEt/a>]);
p 93t/a>        ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_mon" class="sref">tm_mont/a> = ta href="+code=bcd2bin" class="sref">bcd2bint/a>(ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_MONTH" class="sref">RTC_MONTHt/a>]);
p 94t/a>        ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_year" class="sref">tm_yeart/a> = ta href="+code=bcd2bin" class="sref">bcd2bint/a>(ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_YEAR1" class="sref">RTC_YEAR1t/a>]) + ta href="+code=bcd2bin" class="sref">bcd2bint/a>(ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_YEAR2" class="sref">RTC_YEAR2t/a>]) * 100;
p 95t/a>        ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_year" class="sref">tm_yeart/a> -= 1900;
p 96t/a>}
p 97t/a>
p 98t/a>static void ta href="+code=max8998_tm_to_data" class="sref">max8998_tm_to_datat/a>(struct ta href="+code=rtc_time" class="sref">rtc_timet/a> *ta href="+code=tm" class="sref">tmt/a>, ta href="+code=u8" class="sref">u8t/a> *ta href="+code=data" class="sref">datat/a>)
p 99t/a>{
p100t/a>        ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_SEC" class="sref">RTC_SECt/a>] = ta href="+code=bin2bcd" class="sref">bin2bcdt/a>(ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_sec" class="sref">tm_sect/a>);
p101t/a>        ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_MIN" class="sref">RTC_MINt/a>] = ta href="+code=bin2bcd" class="sref">bin2bcdt/a>(ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_min" class="sref">tm_mint/a>);
p102t/a>        ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_HOUR" class="sref">RTC_HOURt/a>] = ta href="+code=bin2bcd" class="sref">bin2bcdt/a>(ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_hour" class="sref">tm_hourt/a>);
p103t/a>        ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_WEEKDAY" class="sref">RTC_WEEKDAYt/a>] = ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_wday" class="sref">tm_wdayt/a>;
p104t/a>        ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_DATE" class="sref">RTC_DATEt/a>] = ta href="+code=bin2bcd" class="sref">bin2bcdt/a>(ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_mday" class="sref">tm_mdayt/a>);
p105t/a>        ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_MONTH" class="sref">RTC_MONTHt/a>] = ta href="+code=bin2bcd" class="sref">bin2bcdt/a>(ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_mon" class="sref">tm_mont/a>);
p106t/a>        ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_YEAR1" class="sref">RTC_YEAR1t/a>] = ta href="+code=bin2bcd" class="sref">bin2bcdt/a>(ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_year" class="sref">tm_yeart/a> %p100);
p107t/a>        ta href="+code=data" class="sref">datat/a>[ta href="+code=RTC_YEAR2" class="sref">RTC_YEAR2t/a>] = ta href="+code=bin2bcd" class="sref">bin2bcdt/a>((ta href="+code=tm" class="sref">tmt/a>->ta href="+code=tm_year" class="sref">tm_yeart/a> + 1900) /p100);
p108t/a>}
p109t/a>
p110t/a>static int ta href="+code=max8998_rtc_read_time" class="sref">max8998_rtc_read_timet/a>(struct ta href="+code=device" class="sref">devicet/a> *ta href="+code=dev" class="sref">devt/a>, struct ta href="+code=rtc_time" class="sref">rtc_timet/a> *ta href="+code=tm" class="sref">tmt/a>)
p111t/a>{
p112t/a>        struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a> = ta href="+code=dev_get_drvdata" class="sref">dev_get_drvdatat/a>(ta href="+code=dev" class="sref">devt/a>);
p113t/a>        ta href="+code=u8" class="sref">u8t/a> ta href="+code=data" class="sref">datat/a>[8];
p114t/a>        int ta href="+code=ret" class="sref">rett/a>;
p115t/a>
p116t/a>        ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_bulk_read" class="sref">max8998_bulk_readt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc" class="sref">rtct/a>, ta href="+code=MAX8998_RTC_SEC" class="sref">MAX8998_RTC_SECt/a>, 8, ta href="+code=data" class="sref">datat/a>);
p117t/a>        if (ta href="+code=ret" class="sref">rett/a> < 0)
p118t/a>                return ta href="+code=ret" class="sref">rett/a>;
p119t/a>
p120t/a>        ta href="+code=max8998_data_to_tm" class="sref">max8998_data_to_tmt/a>(ta href="+code=data" class="sref">datat/a>, ta href="+code=tm" class="sref">tmt/a>);
p121t/a>
p122t/a>        return ta href="+code=rtc_valid_tm" class="sref">rtc_valid_tmt/a>(ta href="+code=tm" class="sref">tmt/a>);
p123t/a>}
p124t/a>
p125t/a>static int ta href="+code=max8998_rtc_set_time" class="sref">max8998_rtc_set_timet/a>(struct ta href="+code=device" class="sref">devicet/a> *ta href="+code=dev" class="sref">devt/a>, struct ta href="+code=rtc_time" class="sref">rtc_timet/a> *ta href="+code=tm" class="sref">tmt/a>)
p126t/a>{
p127t/a>        struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a> = ta href="+code=dev_get_drvdata" class="sref">dev_get_drvdatat/a>(ta href="+code=dev" class="sref">devt/a>);
p128t/a>        ta href="+code=u8" class="sref">u8t/a> ta href="+code=data" class="sref">datat/a>[8];
p129t/a>        int ta href="+code=ret" class="sref">rett/a>;
p130t/a>
p131t/a>        ta href="+code=max8998_tm_to_data" class="sref">max8998_tm_to_datat/a>(ta href="+code=tm" class="sref">tmt/a>, ta href="+code=data" class="sref">datat/a>);
p132t/a>
p133t/a>        ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_bulk_write" class="sref">max8998_bulk_writet/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc" class="sref">rtct/a>, ta href="+code=MAX8998_RTC_SEC" class="sref">MAX8998_RTC_SECt/a>, 8, ta href="+code=data" class="sref">datat/a>);
p134t/a>
p135t/a>        if (ta href="+code=info" class="sref">infot/a>->ta href="+code=lp3974_bug_workaround" class="sref">lp3974_bug_workaroundt/a>)
p136t/a>                ta href="+code=msleep" class="sref">msleept/a>(2000);
p137t/a>
p138t/a>        return ta href="+code=ret" class="sref">rett/a>;
p139t/a>}
p140t/a>
p141t/a>static int ta href="+code=max8998_rtc_read_alarm" class="sref">max8998_rtc_read_alarmt/a>(struct ta href="+code=device" class="sref">devicet/a> *ta href="+code=dev" class="sref">devt/a>, struct ta href="+code=rtc_wkalrm" class="sref">rtc_wkalrmt/a> *ta href="+code=alrm" class="sref">alrmt/a>)
p142t/a>{
p143t/a>        struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a> = ta href="+code=dev_get_drvdata" class="sref">dev_get_drvdatat/a>(ta href="+code=dev" class="sref">devt/a>);
p144t/a>        ta href="+code=u8" class="sref">u8t/a> ta href="+code=data" class="sref">datat/a>[8];
p145t/a>        ta href="+code=u8" class="sref">u8t/a> ta href="+code=val" class="sref">valt/a>;
p146t/a>        int ta href="+code=ret" class="sref">rett/a>;
p147t/a>
p148t/a>        ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_bulk_read" class="sref">max8998_bulk_readt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc" class="sref">rtct/a>, ta href="+code=MAX8998_ALARM0_SEC" class="sref">MAX8998_ALARM0_SECt/a>, 8, ta href="+code=data" class="sref">datat/a>);
p149t/a>        if (ta href="+code=ret" class="sref">rett/a> < 0)
p150t/a>                return ta href="+code=ret" class="sref">rett/a>;
p151t/a>
p152t/a>        ta href="+code=max8998_data_to_tm" class="sref">max8998_data_to_tmt/a>(ta href="+code=data" class="sref">datat/a>, &ta href="+code=alrm" class="sref">alrmt/a>->ta href="+code=time" class="sref">timet/a>);
p153t/a>
p154t/a>        ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_read_reg" class="sref">max8998_read_regt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc" class="sref">rtct/a>, ta href="+code=MAX8998_ALARM0_CONF" class="sref">MAX8998_ALARM0_CONFt/a>, &ta href="+code=val" class="sref">valt/a>);
p155t/a>        if (ta href="+code=ret" class="sref">rett/a> < 0)
p156t/a>                return ta href="+code=ret" class="sref">rett/a>;
p157t/a>
p158t/a>        ta href="+code=alrm" class="sref">alrmt/a>->ta href="+code=enabled" class="sref">enabledt/a> = !!ta href="+code=val" class="sref">valt/a>;
p159t/a>
p160t/a>        ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_read_reg" class="sref">max8998_read_regt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc" class="sref">rtct/a>, ta href="+code=MAX8998_RTC_STATUS" class="sref">MAX8998_RTC_STATUSt/a>, &ta href="+code=val" class="sref">valt/a>);
p161t/a>        if (ta href="+code=ret" class="sref">rett/a> < 0)
p162t/a>                return ta href="+code=ret" class="sref">rett/a>;
p163t/a>
p164t/a>        if (ta href="+code=val" class="sref">valt/a> &pta href="+code=ALARM0_STATUS" class="sref">ALARM0_STATUSt/a>)
p165t/a>                ta href="+code=alrm" class="sref">alrmt/a>->ta href="+code=pending" class="sref">pendingt/a> = 1;
p166t/a>        else
p167t/a>                ta href="+code=alrm" class="sref">alrmt/a>->ta href="+code=pending" class="sref">pendingt/a> = 0;
p168t/a>
p169t/a>        return 0;
p170t/a>}
p171t/a>
p172t/a>static int ta href="+code=max8998_rtc_stop_alarm" class="sref">max8998_rtc_stop_alarmt/a>(struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a>)
p173t/a>{
p174t/a>        int ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_write_reg" class="sref">max8998_write_regt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc" class="sref">rtct/a>, ta href="+code=MAX8998_ALARM0_CONF" class="sref">MAX8998_ALARM0_CONFt/a>, 0);
p175t/a>
p176t/a>        if (ta href="+code=info" class="sref">infot/a>->ta href="+code=lp3974_bug_workaround" class="sref">lp3974_bug_workaroundt/a>)
p177t/a>                ta href="+code=msleep" class="sref">msleept/a>(2000);
p178t/a>
p179t/a>        return ta href="+code=ret" class="sref">rett/a>;
p180t/a>}
p181t/a>
p182t/a>static int ta href="+code=max8998_rtc_start_alarm" class="sref">max8998_rtc_start_alarmt/a>(struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a>)
p183t/a>{
p184t/a>        int ta href="+code=ret" class="sref">rett/a>;
p185t/a>        ta href="+code=u8" class="sref">u8t/a> ta href="+code=alarm0_conf" class="sref">alarm0_conft/a> = 0x77;
p186t/a>
p187t/a>        tspa  class="comment">/* LP3974 with delay bug chips has rtc alarm bugs with "MONTH" field */t/spa  
p188t/a>        if (ta href="+code=info" class="sref">infot/a>->ta href="+code=lp3974_bug_workaround" class="sref">lp3974_bug_workaroundt/a>)
p189t/a>                ta href="+code=alarm0_conf" class="sref">alarm0_conft/a> = 0x57;
p190t/a>
p191t/a>        ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_write_reg" class="sref">max8998_write_regt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc" class="sref">rtct/a>, ta href="+code=MAX8998_ALARM0_CONF" class="sref">MAX8998_ALARM0_CONFt/a>, ta href="+code=alarm0_conf" class="sref">alarm0_conft/a>);
p192t/a>
p193t/a>        if (ta href="+code=info" class="sref">infot/a>->ta href="+code=lp3974_bug_workaround" class="sref">lp3974_bug_workaroundt/a>)
p194t/a>                ta href="+code=msleep" class="sref">msleept/a>(2000);
p195t/a>
p196t/a>        return ta href="+code=ret" class="sref">rett/a>;
p197t/a>}
p198t/a>
p199t/a>static int ta href="+code=max8998_rtc_set_alarm" class="sref">max8998_rtc_set_alarmt/a>(struct ta href="+code=device" class="sref">devicet/a> *ta href="+code=dev" class="sref">devt/a>, struct ta href="+code=rtc_wkalrm" class="sref">rtc_wkalrmt/a> *ta href="+code=alrm" class="sref">alrmt/a>)
p200t/a>{
p201t/a>        struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a> = ta href="+code=dev_get_drvdata" class="sref">dev_get_drvdatat/a>(ta href="+code=dev" class="sref">devt/a>);
p202t/a>        ta href="+code=u8" class="sref">u8t/a> ta href="+code=data" class="sref">datat/a>[8];
p203t/a>        int ta href="+code=ret" class="sref">rett/a>;
p204t/a>
p205t/a>        ta href="+code=max8998_tm_to_data" class="sref">max8998_tm_to_datat/a>(&ta href="+code=alrm" class="sref">alrmt/a>->ta href="+code=time" class="sref">timet/a>, ta href="+code=data" class="sref">datat/a>);
p206t/a>
p207t/a>        ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_rtc_stop_alarm" class="sref">max8998_rtc_stop_alarmt/a>(ta href="+code=info" class="sref">infot/a>);
p208t/a>        if (ta href="+code=ret" class="sref">rett/a> < 0)
p209t/a>                return ta href="+code=ret" class="sref">rett/a>;
p210t/a>
p211t/a>        ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_bulk_write" class="sref">max8998_bulk_writet/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc" class="sref">rtct/a>, ta href="+code=MAX8998_ALARM0_SEC" class="sref">MAX8998_ALARM0_SECt/a>, 8, ta href="+code=data" class="sref">datat/a>);
p212t/a>        if (ta href="+code=ret" class="sref">rett/a> < 0)
p213t/a>                return ta href="+code=ret" class="sref">rett/a>;
p214t/a>
p215t/a>        if (ta href="+code=info" class="sref">infot/a>->ta href="+code=lp3974_bug_workaround" class="sref">lp3974_bug_workaroundt/a>)
p216t/a>                ta href="+code=msleep" class="sref">msleept/a>(2000);
p217t/a>
p218t/a>        if (ta href="+code=alrm" class="sref">alrmt/a>->ta href="+code=enabled" class="sref">enabledt/a>)
p219t/a>                ta href="+code=ret" class="sref">rett/a> = ta href="+code=max8998_rtc_start_alarm" class="sref">max8998_rtc_start_alarmt/a>(ta href="+code=info" class="sref">infot/a>);
p220t/a>
p221t/a>        return ta href="+code=ret" class="sref">rett/a>;
p222t/a>}
p223t/a>
p224t/a>static int ta href="+code=max8998_rtc_alarm_irq_enable" class="sref">max8998_rtc_alarm_irq_enablet/a>(struct ta href="+code=device" class="sref">devicet/a> *ta href="+code=dev" class="sref">devt/a>,
p225t/a>                                        unsigned int ta href="+code=enabled" class="sref">enabledt/a>)
p226t/a>{
p227t/a>        struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a> = ta href="+code=dev_get_drvdata" class="sref">dev_get_drvdatat/a>(ta href="+code=dev" class="sref">devt/a>);
p228t/a>
p229t/a>        if (ta href="+code=enabled" class="sref">enabledt/a>)
p230t/a>                return ta href="+code=max8998_rtc_start_alarm" class="sref">max8998_rtc_start_alarmt/a>(ta href="+code=info" class="sref">infot/a>);
p231t/a>        else
p232t/a>                return ta href="+code=max8998_rtc_stop_alarm" class="sref">max8998_rtc_stop_alarmt/a>(ta href="+code=info" class="sref">infot/a>);
p233t/a>}
p234t/a>
p235t/a>static ta href="+code=irqreturn_t" class="sref">irqreturn_tt/a> ta href="+code=max8998_rtc_alarm_irq" class="sref">max8998_rtc_alarm_irqt/a>(int ta href="+code=irq" class="sref">irqt/a>, void *ta href="+code=data" class="sref">datat/a>)
p236t/a>{
p237t/a>        struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a> = ta href="+code=data" class="sref">datat/a>;
p238t/a>
p239t/a>        ta href="+code=rtc_update_irq" class="sref">rtc_update_irqt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc_dev" class="sref">rtc_devt/a>, 1, ta href="+code=RTC_IRQF" class="sref">RTC_IRQFt/a> | ta href="+code=RTC_AF" class="sref">RTC_AFt/a>);
p240t/a>
p241t/a>        return ta href="+code=IRQ_HANDLED" class="sref">IRQ_HANDLEDt/a>;
p242t/a>}
p243t/a>
p244t/a>static const struct ta href="+code=rtc_class_ops" class="sref">rtc_class_opst/a> ta href="+code=max8998_rtc_ops" class="sref">max8998_rtc_opst/a> = {
p245t/a>        .ta href="+code=read_time" class="sref">read_timet/a> = ta href="+code=max8998_rtc_read_time" class="sref">max8998_rtc_read_timet/a>,
p246t/a>        .ta href="+code=set_time" class="sref">set_timet/a> = ta href="+code=max8998_rtc_set_time" class="sref">max8998_rtc_set_timet/a>,
p247t/a>        .ta href="+code=read_alarm" class="sref">read_alarmt/a> = ta href="+code=max8998_rtc_read_alarm" class="sref">max8998_rtc_read_alarmt/a>,
p248t/a>        .ta href="+code=set_alarm" class="sref">set_alarmt/a> = ta href="+code=max8998_rtc_set_alarm" class="sref">max8998_rtc_set_alarmt/a>,
p249t/a>        .ta href="+code=alarm_irq_enable" class="sref">alarm_irq_enablet/a> = ta href="+code=max8998_rtc_alarm_irq_enable" class="sref">max8998_rtc_alarm_irq_enablet/a>,
p250t/a>};
p251t/a>
p252t/a>static int ta href="+code=max8998_rtc_probe" class="sref">max8998_rtc_probet/a>(struct ta href="+code=platform_device" class="sref">platform_devicet/a> *ta href="+code=pdev" class="sref">pdevt/a>)
p253t/a>{
p254t/a>        struct ta href="+code=max8998_dev" class="sref">max8998_devt/a> *ta href="+code=max8998" class="sref">max8998t/a> = ta href="+code=dev_get_drvdata" class="sref">dev_get_drvdatat/a>(ta href="+code=pdev" class="sref">pdevt/a>->ta href="+code=dev" class="sref">devt/a>.ta href="+code=parent" class="sref">parentt/a>);
p255t/a>        struct ta href="+code=max8998_platform_data" class="sref">max8998_platform_datat/a> *ta href="+code=pdata" class="sref">pdatat/a> = ta href="+code=dev_get_platdata" class="sref">dev_get_platdatat/a>(ta href="+code=max8998" class="sref">max8998t/a>->ta href="+code=dev" class="sref">devt/a>);
p256t/a>        struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a>;
p257t/a>        int ta href="+code=ret" class="sref">rett/a>;
p258t/a>
p259t/a>        ta href="+code=info" class="sref">infot/a> = ta href="+code=kzalloc" class="sref">kzalloct/a>(sizeof(struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a>), ta href="+code=GFP_KERNEL" class="sref">GFP_KERNELt/a>);
p260t/a>        if (!ta href="+code=info" class="sref">infot/a>)
p261t/a>                return -ta href="+code=ENOMEM" class="sref">ENOMEMt/a>;
p262t/a>
p263t/a>        ta href="+code=info" class="sref">infot/a>->ta href="+code=dev" class="sref">devt/a> = &ta href="+code=pdev" class="sref">pdevt/a>->ta href="+code=dev" class="sref">devt/a>;
p264t/a>        ta href="+code=info" class="sref">infot/a>->ta href="+code=max8998" class="sref">max8998t/a> = ta href="+code=max8998" class="sref">max8998t/a>;
p265t/a>        ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc" class="sref">rtct/a> = ta href="+code=max8998" class="sref">max8998t/a>->ta href="+code=rtc" class="sref">rtct/a>;
p266t/a>        ta href="+code=info" class="sref">infot/a>->ta href="+code=irq" class="sref">irqt/a> = ta href="+code=max8998" class="sref">max8998t/a>->ta href="+code=irq_base" class="sref">irq_baset/a> + ta href="+code=MAX8998_IRQ_ALARM0" class="sref">MAX8998_IRQ_ALARM0t/a>;
p267t/a>
p268t/a>        ta href="+code=platform_set_drvdata" class="sref">platform_set_drvdatat/a>(ta href="+code=pdev" class="sref">pdevt/a>, ta href="+code=info" class="sref">infot/a>);
p269t/a>
p270t/a>        ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc_dev" class="sref">rtc_devt/a> = ta href="+code=rtc_device_register" class="sref">rtc_device_registert/a>(tspa  class="string">"max8998-rtc"t/spa  , &ta href="+code=pdev" class="sref">pdevt/a>->ta href="+code=dev" class="sref">devt/a>,
p271t/a>                        &ta href="+code=max8998_rtc_ops" class="sref">max8998_rtc_opst/a>, ta href="+code=THIS_MODULE" class="sref">THIS_MODULEt/a>);
p272t/a>
p273t/a>        if (ta href="+code=IS_ERR" class="sref">IS_ERRt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc_dev" class="sref">rtc_devt/a>)) {
p274t/a>                ta href="+code=ret" class="sref">rett/a> = ta href="+code=PTR_ERR" class="sref">PTR_ERRt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc_dev" class="sref">rtc_devt/a>);
p275t/a>                ta href="+code=dev_err" class="sref">dev_errt/a>(&ta href="+code=pdev" class="sref">pdevt/a>->ta href="+code=dev" class="sref">devt/a>, tspa  class="string">"Failed to register RTC device: %d\n"t/spa  , ta href="+code=ret" class="sref">rett/a>);
p276t/a>                goto ta href="+code=out_rtc" class="sref">out_rtct/a>;
p277t/a>        }
p278t/a>
p279t/a>        ta href="+code=ret" class="sref">rett/a> = ta href="+code=request_threaded_irq" class="sref">request_threaded_irqt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=irq" class="sref">irqt/a>, ta href="+code=NULL" class="sref">NULLt/a>, ta href="+code=max8998_rtc_alarm_irq" class="sref">max8998_rtc_alarm_irqt/a>, 0,
p280t/a>                        tspa  class="string">"rtc-alarm0"t/spa  , ta href="+code=info" class="sref">infot/a>);
p281t/a>
p282t/a>        if (ta href="+code=ret" class="sref">rett/a> < 0)
p283t/a>                ta href="+code=dev_err" class="sref">dev_errt/a>(&ta href="+code=pdev" class="sref">pdevt/a>->ta href="+code=dev" class="sref">devt/a>, tspa  class="string">"Failed to request alarm IRQ: %d: %d\n"t/spa  ,
p284t/a>                        ta href="+code=info" class="sref">infot/a>->ta href="+code=irq" class="sref">irqt/a>, ta href="+code=ret" class="sref">rett/a>);
p285t/a>
p286t/a>        ta href="+code=dev_info" class="sref">dev_infot/a>(&ta href="+code=pdev" class="sref">pdevt/a>->ta href="+code=dev" class="sref">devt/a>, tspa  class="string">"RTC CHIP NAME: %s\n"t/spa  , ta href="+code=pdev" class="sref">pdevt/a>->ta href="+code=id_entry" class="sref">id_entryt/a>->ta href="+code=namv" class="sref">namvt/a>);
p287t/a>        if (ta href="+code=pdata" class="sref">pdatat/a>->ta href="+code=rtc_delay" class="sref">rtc_delayt/a>) {
p288t/a>                ta href="+code=info" class="sref">infot/a>->ta href="+code=lp3974_bug_workaround" class="sref">lp3974_bug_workaroundt/a> = ta href="+code=true" class="sref">truet/a>;
p289t/a>                ta href="+code=dev_warn" class="sref">dev_warnt/a>(&ta href="+code=pdev" class="sref">pdevt/a>->ta href="+code=dev" class="sref">devt/a>, tspa  class="string">"LP3974 with RTC REGERR option."t/spa  
p290t/a>                                tspa  class="string">" RTC updates will be extremely slow.\n"t/spa  );
p291t/a>        }
p292t/a>
p293t/a>        return 0;
p294t/a>
p295t/a>ta href="+code=out_rtc" class="sref">out_rtct/a>:
p296t/a>        ta href="+code=platform_set_drvdata" class="sref">platform_set_drvdatat/a>(ta href="+code=pdev" class="sref">pdevt/a>, ta href="+code=NULL" class="sref">NULLt/a>);
p297t/a>        ta href="+code=kfree" class="sref">kfreet/a>(ta href="+code=info" class="sref">infot/a>);
p298t/a>        return ta href="+code=ret" class="sref">rett/a>;
p299t/a>}
p300t/a>
p301t/a>static int ta href="+code=max8998_rtc_remove" class="sref">max8998_rtc_removet/a>(struct ta href="+code=platform_device" class="sref">platform_devicet/a> *ta href="+code=pdev" class="sref">pdevt/a>)
p302t/a>{
p303t/a>        struct ta href="+code=max8998_rtc_info" class="sref">max8998_rtc_infot/a> *ta href="+code=info" class="sref">infot/a> = ta href="+code=platform_get_drvdata" class="sref">platform_get_drvdatat/a>(ta href="+code=pdev" class="sref">pdevt/a>);
p304t/a>
p305t/a>        if (ta href="+code=info" class="sref">infot/a>) {
p306t/a>                ta href="+code=free_irq" class="sref">free_irqt/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=irq" class="sref">irqt/a>, ta href="+code=info" class="sref">infot/a>);
p307t/a>                ta href="+code=rtc_device_unregister" class="sref">rtc_device_unregistert/a>(ta href="+code=info" class="sref">infot/a>->ta href="+code=rtc_dev" class="sref">rtc_devt/a>);
p308t/a>                ta href="+code=kfree" class="sref">kfreet/a>(ta href="+code=info" class="sref">infot/a>);
p309t/a>        }
p310t/a>
p311t/a>        return 0;
p312t/a>}
p313t/a>
p314t/a>static const struct ta href="+code=platform_device_id" class="sref">platform_device_idt/a> ta href="+code=max8998_rtc_id" class="sref">max8998_rtc_idt/a>[] = {
p315t/a>        { tspa  class="string">"max8998-rtc"t/spa  , ta href="+code=TYPE_MAX8998" class="sref">TYPE_MAX8998t/a> },
p316t/a>        { tspa  class="string">"lp3974-rtc"t/spa  , ta href="+code=TYPE_LP3974" class="sref">TYPE_LP3974t/a> },
p317t/a>        { }
p318t/a>};
p319t/a>
p320t/a>static struct ta href="+code=platform_driver" class="sref">platform_drivert/a> ta href="+code=max8998_rtc_driver" class="sref">max8998_rtc_drivert/a> = {
p321t/a>        .ta href="+code=driver" class="sref">drivert/a>         = {
p322t/a>                .ta href="+code=namv" class="sref">namvt/a>   = tspa  class="string">"max8998-rtc"t/spa  ,
p323t/a>                .ta href="+code=owner" class="sref">ownert/a>  = ta href="+code=THIS_MODULE" class="sref">THIS_MODULEt/a>,
p324t/a>        },
p325t/a>        .ta href="+code=probe" class="sref">probet/a>          = ta href="+code=max8998_rtc_probe" class="sref">max8998_rtc_probet/a>,
p326t/a>        .ta href="+code=remove" class="sref">removet/a>         = ta href="+code=max8998_rtc_remove" class="sref">max8998_rtc_removet/a>,
p327t/a>        .ta href="+code=id_table" class="sref">id_tablet/a>       = ta href="+code=max8998_rtc_id" class="sref">max8998_rtc_idt/a>,
p328t/a>};
p329t/a>
p330t/a>ta href="+code=module_platform_driver" class="sref">module_platform_drivert/a>(ta href="+code=max8998_rtc_driver" class="sref">max8998_rtc_drivert/a>);
p331t/a>
p332t/a>ta href="+code=MODULE_AUTHOR" class="sref">MODULE_AUTHORt/a>(tspa  class="string">"Minkyu Kang <mk7.kang@samsung.com>"t/spa  );
p333t/a>ta href="+code=MODULE_AUTHOR" class="sref">MODULE_AUTHORt/a>(tspa  class="string">"Joonyoung Shim <jy0922.shim@samsung.com>"t/spa  );
p334t/a>ta href="+code=MODULE_DESCRIPTION" class="sref">MODULE_DESCRIPTIONt/a>(tspa  class="string">"Maxim MAX8998 RTC driver"t/spa  );
p335t/a>ta href="+code=MODULE_LICENSE" class="sref">MODULE_LICENSEt/a>(tspa  class="string">"GPL"t/spa  );
p336t/a>
lxr.linux.no kindly hosted by Redpill Linpro ASt/a>, provider of Linux consulting and operations services sincep1995.