コード例 #1
0
ファイル: rtc.c プロジェクト: drthth/busware
void rtc_write_ticks( uint8_t ch, uint32_t val ) {
     rtc_write( RTC_RAM_START + (ch*4) + 0, val & 0xff );
     rtc_write( RTC_RAM_START + (ch*4) + 1, (val>>8) & 0xff );
     rtc_write( RTC_RAM_START + (ch*4) + 2, (val>>16) & 0xff );
     rtc_write( RTC_RAM_START + (ch*4) + 3, (val>>24) & 0xff );
}
コード例 #2
0
ファイル: ds1337.c プロジェクト: 8devices/Caraboot
/*
 * Reset the RTC.  We also enable the oscillator output on the
 * SQW/INTB* pin and program it for 32,768 Hz output. Note that
 * according to the datasheet, turning on the square wave output
 * increases the current drain on the backup battery from about
 * 600 nA to 2uA.
 */
void rtc_reset (void)
{
	rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
}
コード例 #3
0
ファイル: pcf8563.c プロジェクト: Antonio-Zhou/Linux-2.6.11
/*
 * ioctl calls for this driver. Why return -ENOTTY upon error? Because
 * POSIX says so!
 */
int
pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
	/* Some sanity checks. */
	if (_IOC_TYPE(cmd) != RTC_MAGIC)
		return -ENOTTY;

	if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
		return -ENOTTY;

	switch (cmd) {
		case RTC_RD_TIME:
			{
				struct rtc_time tm;

				get_rtc_time(&tm);

				if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
					return -EFAULT;
				}

				return 0;
			}
			break;
		case RTC_SET_TIME:
			{
#ifdef CONFIG_ETRAX_RTC_READONLY
				return -EPERM;
#else
				int leap;
				int century;
				struct rtc_time tm;

				memset(&tm, 0, sizeof (struct rtc_time));
				if (!capable(CAP_SYS_TIME))
					return -EPERM;

				if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
					return -EFAULT;

				/* Convert from struct tm to struct rtc_time. */
				tm.tm_year += 1900;
				tm.tm_mon += 1;
				
				leap = ((tm.tm_mon == 2) && ((tm.tm_year % 4) == 0)) ? 1 : 0;

				/* Perform some sanity checks. */
				if ((tm.tm_year < 1970) ||
				    (tm.tm_mon > 12) ||
				    (tm.tm_mday == 0) ||
				    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
				    (tm.tm_hour >= 24) ||
				    (tm.tm_min >= 60) ||
				    (tm.tm_sec >= 60))
					return -EINVAL;

				century = (tm.tm_year >= 2000) ? 0x80 : 0;
				tm.tm_year = tm.tm_year % 100;

				BIN_TO_BCD(tm.tm_year);
				BIN_TO_BCD(tm.tm_mday);
				BIN_TO_BCD(tm.tm_hour);
				BIN_TO_BCD(tm.tm_min);
				BIN_TO_BCD(tm.tm_sec);
				tm.tm_mon |= century;
				
				rtc_write(RTC_YEAR, tm.tm_year);
				rtc_write(RTC_MONTH, tm.tm_mon);
				rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
				rtc_write(RTC_HOURS, tm.tm_hour);
				rtc_write(RTC_MINUTES, tm.tm_min);
				rtc_write(RTC_SECONDS, tm.tm_sec);

				return 0;
#endif /* !CONFIG_ETRAX_RTC_READONLY */
			}

		case RTC_VLOW_RD:
		{
			int vl_bit = 0;

			if (rtc_read(RTC_SECONDS) & 0x80) {
				vl_bit = 1;
				printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
				       "date/time information is no longer guaranteed!\n",
				       PCF8563_NAME);
			}
			if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
				return -EFAULT;

			return 0;
		}

		case RTC_VLOW_SET:
		{
			/* Clear the VL bit in the seconds register */
			int ret = rtc_read(RTC_SECONDS);

			rtc_write(RTC_SECONDS, (ret & 0x7F));

			return 0;
		}

		default:
				return -ENOTTY;
	}

	return 0;
}
コード例 #4
0
int rtc_get( struct rtc_time *tmp)
{
	if (phantom_flag < 0)
		phantom_flag = get_phantom_flag();

	if (phantom_flag)
	{
		unsigned char rtc[8];

		phantom_rtc_read(RTC_BASE, rtc);

		tmp->tm_sec	= bcd2bin(rtc[1] & 0x7f);
		tmp->tm_min	= bcd2bin(rtc[2] & 0x7f);
		tmp->tm_hour	= bcd2bin(rtc[3] & 0x1f);
		tmp->tm_wday	= bcd2bin(rtc[4] & 0x7);
		tmp->tm_mday	= bcd2bin(rtc[5] & 0x3f);
		tmp->tm_mon	= bcd2bin(rtc[6] & 0x1f);
		tmp->tm_year	= bcd2bin(rtc[7]) + 1900;
		tmp->tm_yday = 0;
		tmp->tm_isdst = 0;

		if( (rtc[3] & 0x80)  && (rtc[3] & 0x40) ) tmp->tm_hour += 12;
		if (tmp->tm_year < 1970) tmp->tm_year += 100;
	} else {
		uchar sec, min, hour;
		uchar mday, wday, mon, year;

		int century;

		uchar reg_a;

		if (century_flag < 0)
			century_flag = get_century_flag();

		reg_a = rtc_read( RTC_CONTROLA );
		/* lock clock registers for read */
		rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));

		sec     = rtc_read( RTC_SECONDS );
		min     = rtc_read( RTC_MINUTES );
		hour    = rtc_read( RTC_HOURS );
		mday    = rtc_read( RTC_DAY_OF_MONTH );
		wday    = rtc_read( RTC_DAY_OF_WEEK );
		mon     = rtc_read( RTC_MONTH );
		year    = rtc_read( RTC_YEAR );
		century = rtc_read( RTC_CENTURY );

		/* unlock clock registers after read */
		rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));

		tmp->tm_sec  = bcd2bin( sec  & 0x7F );
		tmp->tm_min  = bcd2bin( min  & 0x7F );
		tmp->tm_hour = bcd2bin( hour & 0x3F );
		tmp->tm_mday = bcd2bin( mday & 0x3F );
		tmp->tm_mon  = bcd2bin( mon & 0x1F );
		tmp->tm_wday = bcd2bin( wday & 0x07 );

		if (century_flag) {
			tmp->tm_year = bcd2bin( year ) +
				( bcd2bin( century & 0x3F ) * 100 );
		} else {
			tmp->tm_year = bcd2bin( year ) + 1900;
			if (tmp->tm_year < 1970) tmp->tm_year += 100;
		}

		tmp->tm_yday = 0;
		tmp->tm_isdst= 0;
	}

	return 0;
}
コード例 #5
0
void
pcf8563_writereg(int reg, unsigned char val)
{
    rtc_write(reg, val);
}
コード例 #6
0
ファイル: rtc-ds1511.c プロジェクト: Cool-Joe/imx23-audio
static void
rtc_enable_update(void)
{
	rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD);
}
コード例 #7
0
ファイル: rtc.c プロジェクト: canistation/coreboot
/* write powerkeys to enable rtc functions */
static int rtc_powerkey_init(void)
{
	rtc_write(RTC_POWERKEY1, RTC_POWERKEY1_KEY);
	rtc_write(RTC_POWERKEY2, RTC_POWERKEY2_KEY);
	return rtc_write_trigger();
}
コード例 #8
0
ファイル: rtc-ds1511.c プロジェクト: mesosexy/linux-2.6
/*
 * set the rtc chip's idea of the time.
 * stupidly, some callers call with year unmolested;
 * and some call with  year = year - 1900.  thanks.
 */
static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
{
	u8 mon, day, dow, hrs, min, sec, yrs, cen;
	unsigned long flags;

	/*
	 * won't have to change this for a while
	 */
	if (rtc_tm->tm_year < 1900) {
		rtc_tm->tm_year += 1900;
	}

	if (rtc_tm->tm_year < 1970) {
		return -EINVAL;
	}
	yrs = rtc_tm->tm_year % 100;
	cen = rtc_tm->tm_year / 100;
	mon = rtc_tm->tm_mon + 1;   /* tm_mon starts at zero */
	day = rtc_tm->tm_mday;
	dow = rtc_tm->tm_wday & 0x7; /* automatic BCD */
	hrs = rtc_tm->tm_hour;
	min = rtc_tm->tm_min;
	sec = rtc_tm->tm_sec;

	if ((mon > 12) || (day == 0)) {
		return -EINVAL;
	}

	if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year)) {
		return -EINVAL;
	}

	if ((hrs >= 24) || (min >= 60) || (sec >= 60)) {
		return -EINVAL;
	}

	/*
	 * each register is a different number of valid bits
	 */
	sec = bin2bcd(sec) & 0x7f;
	min = bin2bcd(min) & 0x7f;
	hrs = bin2bcd(hrs) & 0x3f;
	day = bin2bcd(day) & 0x3f;
	mon = bin2bcd(mon) & 0x1f;
	yrs = bin2bcd(yrs) & 0xff;
	cen = bin2bcd(cen) & 0xff;

	spin_lock_irqsave(&ds1511_lock, flags);
	rtc_disable_update();
	rtc_write(cen, RTC_CENTURY);
	rtc_write(yrs, RTC_YEAR);
	rtc_write((rtc_read(RTC_MON) & 0xe0) | mon, RTC_MON);
	rtc_write(day, RTC_DOM);
	rtc_write(hrs, RTC_HOUR);
	rtc_write(min, RTC_MIN);
	rtc_write(sec, RTC_SEC);
	rtc_write(dow, RTC_DOW);
	rtc_enable_update();
	spin_unlock_irqrestore(&ds1511_lock, flags);

	return 0;
}
コード例 #9
0
ファイル: rtc-omap.c プロジェクト: mrtos/Logitech-Revue
static int __devinit omap_rtc_probe(struct platform_device *pdev)
{
	struct resource		*res, *mem;
	struct rtc_device	*rtc;
	u8			reg, new_ctrl;

	omap_rtc_timer = platform_get_irq(pdev, 0);
	if (omap_rtc_timer <= 0) {
		pr_debug("%s: no update irq?\n", pdev->name);
		return -ENOENT;
	}

	omap_rtc_alarm = platform_get_irq(pdev, 1);
	if (omap_rtc_alarm <= 0) {
		pr_debug("%s: no alarm irq?\n", pdev->name);
		return -ENOENT;
	}

	/* NOTE:  using static mapping for RTC registers */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res && res->start != OMAP_RTC_BASE) {
		pr_debug("%s: RTC registers at %08x, expected %08x\n",
			pdev->name, (unsigned) res->start, OMAP_RTC_BASE);
		return -ENOENT;
	}

	if (res)
		mem = request_mem_region(res->start,
				res->end - res->start + 1,
				pdev->name);
	else
		mem = NULL;
	if (!mem) {
		pr_debug("%s: RTC registers at %08x are not free\n",
			pdev->name, OMAP_RTC_BASE);
		return -EBUSY;
	}

	rtc = rtc_device_register(pdev->name, &pdev->dev,
			&omap_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc)) {
		pr_debug("%s: can't register RTC device, err %ld\n",
			pdev->name, PTR_ERR(rtc));
		goto fail;
	}
	platform_set_drvdata(pdev, rtc);
	class_set_devdata(&rtc->class_dev, mem);

	/* clear pending irqs, and set 1/second periodic,
	 * which we'll use instead of update irqs
	 */
	rtc_write(0, OMAP_RTC_INTERRUPTS_REG);

	/* clear old status */
	reg = rtc_read(OMAP_RTC_STATUS_REG);
	if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) {
		pr_info("%s: RTC power up reset detected\n",
			pdev->name);
		rtc_write(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG);
	}
	if (reg & (u8) OMAP_RTC_STATUS_ALARM)
		rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);

	/* handle periodic and alarm irqs */
	if (request_irq(omap_rtc_timer, rtc_irq, SA_INTERRUPT,
			rtc->class_dev.class_id, &rtc->class_dev)) {
		pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
			pdev->name, omap_rtc_timer);
		goto fail0;
	}
	if (request_irq(omap_rtc_alarm, rtc_irq, SA_INTERRUPT,
			rtc->class_dev.class_id, &rtc->class_dev)) {
		pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
			pdev->name, omap_rtc_alarm);
		goto fail1;
	}

	/* On boards with split power, RTC_ON_NOFF won't reset the RTC */
	reg = rtc_read(OMAP_RTC_CTRL_REG);
	if (reg & (u8) OMAP_RTC_CTRL_STOP)
		pr_info("%s: already running\n", pdev->name);

	/* force to 24 hour mode */
	new_ctrl = reg & ~(OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP);
	new_ctrl |= OMAP_RTC_CTRL_STOP;

	/* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
	 *
	 *  - Boards wired so that RTC_WAKE_INT does something, and muxed
	 *    right (W13_1610_RTC_WAKE_INT is the default after chip reset),
	 *    should initialize the device wakeup flag appropriately.
	 *
	 *  - Boards wired so RTC_ON_nOFF is used as the reset signal,
	 *    rather than nPWRON_RESET, should forcibly enable split
	 *    power mode.  (Some chip errata report that RTC_CTRL_SPLIT
	 *    is write-only, and always reads as zero...)
	 */
	device_init_wakeup(&pdev->dev, 0);

	if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT)
		pr_info("%s: split power mode\n", pdev->name);

	if (reg != new_ctrl)
		rtc_write(new_ctrl, OMAP_RTC_CTRL_REG);

	return 0;

fail1:
	free_irq(omap_rtc_timer, NULL);
fail0:
	rtc_device_unregister(rtc);
fail:
	release_resource(mem);
	return -EIO;
}
コード例 #10
0
static void rtc_tasklet_handler(unsigned long data)
{
	u16 irqsta, pdn1, pdn2, spar1;
	bool pwron_alm = false;

	spin_lock(&rtc_lock);
	irqsta = rtc_read(RTC_IRQ_STA);		/* read clear */
	if (unlikely(!(irqsta & RTC_IRQ_STA_AL))) {
#ifndef USER_BUILD_KERNEL
		if (irqsta & RTC_IRQ_STA_LP)
			rtc_lp_exception();
#endif
		spin_unlock(&rtc_lock);
		enable_irq(MT6573_RTC_IRQ_LINE);
		return;
	}

#if RTC_RELPWR_WHEN_XRST
{
	/* set AUTO bit because AUTO = 0 when PWREN = 1 and alarm occurs */
	u16 bbpu = rtc_read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_AUTO;
	rtc_write(RTC_BBPU, bbpu);
	rtc_write_trigger();
}
#endif

	pdn1 = rtc_read(RTC_PDN1);
	pdn2 = rtc_read(RTC_PDN2);
	spar1 = rtc_read(RTC_SPAR1);
	if (pdn1 & 0x0080) {	/* power-on time is available */
		u16 now_sec, now_min, now_hou, now_dom, now_mth;
		u16 irqen, min, hou, dom, mth;

		now_sec = rtc_read(RTC_TC_SEC);
		now_min = rtc_read(RTC_TC_MIN);
		now_hou = rtc_read(RTC_TC_HOU);
		now_dom = rtc_read(RTC_TC_DOM);
		now_mth = rtc_read(RTC_TC_MTH);
		if (rtc_read(RTC_TC_SEC) < now_sec) {	/* SEC has carried */
			now_sec = rtc_read(RTC_TC_SEC);
			now_min = rtc_read(RTC_TC_MIN);
			now_hou = rtc_read(RTC_TC_HOU);
			now_dom = rtc_read(RTC_TC_DOM);
			now_mth = rtc_read(RTC_TC_MTH);
		}

		min = spar1 & 0x003f;
		hou = (spar1 & 0x07c0) >> 6;
		dom = (spar1 & 0xf800) >> 11;
		mth = pdn2 & 0x000f;

		if (now_mth == mth && now_dom == dom &&
		    now_hou == hou && now_min == min &&
		    now_sec >= (RTC_PWRON_SEC - 1) && now_sec <= (RTC_PWRON_SEC + 4)) {
			rtc_write(RTC_PDN1, pdn1 & ~0x0080);
			rtc_write(RTC_PDN2, pdn2 | 0x0010);
			rtc_write_trigger();
			pwron_alm = true;
		} else {
			/* set power-on alarm when power-on time is available */
			rtc_write(RTC_AL_MTH, mth);
			rtc_write(RTC_AL_DOM, dom);
			rtc_write(RTC_AL_HOU, hou);
			rtc_write(RTC_AL_MIN, min);
			rtc_write(RTC_AL_SEC, RTC_PWRON_SEC);
			rtc_write(RTC_AL_MASK, 0x0050);		/* mask YEA and DOW */
			rtc_write_trigger();
			irqen = rtc_read(RTC_IRQ_EN) | RTC_IRQ_EN_ONESHOT_AL;
			rtc_write(RTC_IRQ_EN, irqen);
			rtc_write_trigger();
		}
	}
コード例 #11
0
ファイル: rtc_api.c プロジェクト: yanesca/mbed
void rtc_init(void) {
    RCC_OscInitTypeDef RCC_OscInitStruct;

#if RTC_LSI
    if (rtc_inited) return;
    rtc_inited = 1;
#endif

    RtcHandle.Instance = RTC;

#if !RTC_LSI
    // Enable LSE Oscillator
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
    RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
    RCC_OscInitStruct.LSEState       = RCC_LSE_ON; // External 32.768 kHz clock on OSC_IN/OSC_OUT
    RCC_OscInitStruct.LSIState       = RCC_LSI_OFF;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) { // Check if LSE has started correctly
        // Connect LSE to RTC
        __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
    } else {
	    error("Cannot initialize RTC with LSE\n");
    }
#else
    // Enable Power clock
    __PWR_CLK_ENABLE();

    // Enable access to Backup domain
    HAL_PWR_EnableBkUpAccess();

    // Reset Backup domain
    __HAL_RCC_BACKUPRESET_FORCE();
    __HAL_RCC_BACKUPRESET_RELEASE();
	
    // Enable LSI clock
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
    RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!
    RCC_OscInitStruct.LSEState       = RCC_LSE_OFF;
    RCC_OscInitStruct.LSIState       = RCC_LSI_ON;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        error("Cannot initialize RTC with LSI\n");
    }
    // Connect LSI to RTC
    __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
#endif

    // Enable RTC
    __HAL_RCC_RTC_ENABLE();

    RtcHandle.Init.HourFormat     = RTC_HOURFORMAT_24;
    RtcHandle.Init.AsynchPrediv   = RTC_ASYNCH_PREDIV;
    RtcHandle.Init.SynchPrediv    = RTC_SYNCH_PREDIV;
    RtcHandle.Init.OutPut         = RTC_OUTPUT_DISABLE;
    RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
    RtcHandle.Init.OutPutType     = RTC_OUTPUT_TYPE_OPENDRAIN;

    if (HAL_RTC_Init(&RtcHandle) != HAL_OK) {
        error("RTC error: RTC initialization failed.");
    }

#if DEVICE_LOWPOWERTIMER
#if RTC_LSI
    rtc_write(0);
#else
    if (!rtc_isenabled()) {
        rtc_write(0);
    }
#endif
    NVIC_ClearPendingIRQ(RTC_IRQn);
    NVIC_DisableIRQ(RTC_IRQn);
    NVIC_SetVector(RTC_IRQn, (uint32_t)RTC_IRQHandler);
    NVIC_EnableIRQ(RTC_IRQn);
#endif
}
コード例 #12
0
static void rtc_write_trigger(void)
{
	rtc_write(RTC_WRTGR, 1);
	rtc_busy_wait();
}
コード例 #13
0
ファイル: rtc.c プロジェクト: gmarsh/thin18
void rtc_init(void) {

	/* step #1: initialize SERCOM */
	
	// enable clock to SERCOM3 - 8MHz core clock, 32KHz slow clock
	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM3_GCLK_ID_CORE) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);
	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM3_GCLK_ID_SLOW) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(2);
	PM->APBCMASK.reg |= PM_APBCMASK_SERCOM3;
	
	// configure PA22/PA23 as SC3[0] and SC3[1] respectively
	PORT->Group[0].PMUX[23/2].bit.PMUXO = PORT_PMUX_PMUXO_C_Val;
	PORT->Group[0].PMUX[22/2].bit.PMUXE = PORT_PMUX_PMUXE_C_Val;
	PORT->Group[0].PINCFG[23].bit.PMUXEN = 1;
	PORT->Group[0].PINCFG[22].bit.PMUXEN = 1;
	
	// initialize SERCOM3 into TWI mode
	// high/low time periods are (5+N) GCLK cycles
	// values of 5 give 400KHz TWI speed
	// values of 15 give 200KHz TWI speed
	// values of 75 gives 50KHz TWI speed

	SERCOM3->I2CM.BAUD.reg = \
		(15<<SERCOM_I2CM_BAUD_BAUD_Pos)| \
		(15<<SERCOM_I2CM_BAUD_BAUDLOW_Pos);
	while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY);
	
	
	// enable TWI mode
	SERCOM3->I2CM.CTRLA.reg = \
		(3<<SERCOM_I2CM_CTRLA_SDAHOLD_Pos) |\
		(0<<SERCOM_I2CM_CTRLA_INACTOUT_Pos) |\
		(0<<SERCOM_I2CM_CTRLA_PINOUT_Pos) |\
		SERCOM_I2CM_CTRLA_MODE_I2C_MASTER |\
		(0<<SERCOM_I2CM_CTRLA_ENABLE_Pos);
	while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY);
	
	// don't enable smart mode
	SERCOM3->I2CM.CTRLB.reg = 0;
	while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY);
	
	// force TWI unit into idle mode
	SERCOM3->I2CM.STATUS.bit.BUSSTATE = 1;
	while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY);

	// enable!
	SERCOM3->I2CM.CTRLA.bit.ENABLE = 1;
	while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY);

	// force TWI unit into idle mode
	SERCOM3->I2CM.STATUS.bit.BUSSTATE = 1;
	while(SERCOM3->I2CM.STATUS.bit.SYNCBUSY);
	
	/* step #2: initialize RTC chip itself */
	
	// read entire RTC chip
	rtc_read(0x00,(uint8_t *) &rtc_data,sizeof(rtc_data));
	
	// check config
	
	uint8_t csr_int_cache = rtc_data.csr.csr_int;

	
	// WRTC=1 (enable RTC)
	// FOBATB=1 (disable /INT output)
	// FO=10 (1Hz frequency output)
	rtc_data.csr.csr_int = (1<<6)|(1<<4)|(10<<0);
	// clear timestamps, VDD brownout = 2.8V, battery brownouts = see datasheet.
	rtc_data.csr.csr_pwr_vdd = (1<<7)|(2<<0);
	rtc_data.csr.csr_pwr_vbat = (0<<6)|(3<<3)|(3<<0);
	// rest of CSR registers is trimming - leave alone!
	
	// disable alarms
	rtc_data.alarm.alarm_sca0 = 0;
	rtc_data.alarm.alarm_mna0 = 0;
	rtc_data.alarm.alarm_hra0 = 0;
	rtc_data.alarm.alarm_dta0 = 0;
	rtc_data.alarm.alarm_moa0 = 0;
	rtc_data.alarm.alarm_dwa0 = 0;
	
	// disable DST
	rtc_data.dstcr.dstcr_DstMoFd = 0;
	
	// write everything back to RTC
	rtc_write(0x07,&rtc_data.csr.csr_sr,42);
	
	// if RTCF was set, write new time (00:00, jan 1, 2016)
	if (csr_int_cache & 0x01) {
		rtc_data.rtc.rtc_sc = 0x00;
		rtc_data.rtc.rtc_mn = 0x00;
		rtc_data.rtc.rtc_hr = 0x00;
		rtc_data.rtc.rtc_dt = 0x01;
		rtc_data.rtc.rtc_mo = 0x01;
		rtc_data.rtc.rtc_yr = 0x16;
		rtc_data.rtc.rtc_dw = 0;
		rtc_write(0x00,(uint8_t *) &rtc_data, 7);
	}
	
}
コード例 #14
0
void rtc_reset (void)
{
	rtc_write (RTC_CTL_REG_ADDR, RTC_DS1337_RESET_VAL);
}
コード例 #15
0
ファイル: rtc-ds1511.c プロジェクト: Cool-Joe/imx23-audio
static inline void
rtc_write_alarm(uint8_t val, enum ds1511reg reg)
{
	rtc_write((val | 0x80), reg);
}
コード例 #16
0
/*
 * ioctl calls for this driver. Why return -ENOTTY upon error? Because
 * POSIX says so!
 */
int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
	unsigned long arg)
{
	/* Some sanity checks. */
	if (_IOC_TYPE(cmd) != RTC_MAGIC)
		return -ENOTTY;

	if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
		return -ENOTTY;

	switch (cmd) {
	case RTC_RD_TIME:
	{
		struct rtc_time tm;

		mutex_lock(&rtc_lock);
		memset(&tm, 0, sizeof tm);
		get_rtc_time(&tm);

		if (copy_to_user((struct rtc_time *) arg, &tm,
				 sizeof tm)) {
			mutex_unlock(&rtc_lock);
			return -EFAULT;
		}

		mutex_unlock(&rtc_lock);

		return 0;
	}
	case RTC_SET_TIME:
	{
		int leap;
		int year;
		int century;
		struct rtc_time tm;

		memset(&tm, 0, sizeof tm);
		if (!capable(CAP_SYS_TIME))
			return -EPERM;

		if (copy_from_user(&tm, (struct rtc_time *) arg,
				   sizeof tm))
			return -EFAULT;

		/* Convert from struct tm to struct rtc_time. */
		tm.tm_year += 1900;
		tm.tm_mon += 1;

		/*
		 * Check if tm.tm_year is a leap year. A year is a leap
		 * year if it is divisible by 4 but not 100, except
		 * that years divisible by 400 _are_ leap years.
		 */
		year = tm.tm_year;
		leap = (tm.tm_mon == 2) &&
			((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);

		/* Perform some sanity checks. */
		if ((tm.tm_year < 1970) ||
		    (tm.tm_mon > 12) ||
		    (tm.tm_mday == 0) ||
		    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
		    (tm.tm_wday >= 7) ||
		    (tm.tm_hour >= 24) ||
		    (tm.tm_min >= 60) ||
		    (tm.tm_sec >= 60))
			return -EINVAL;

		century = (tm.tm_year >= 2000) ? 0x80 : 0;
		tm.tm_year = tm.tm_year % 100;

		tm.tm_year = bin2bcd(tm.tm_year);
		tm.tm_mon = bin2bcd(tm.tm_mon);
		tm.tm_mday = bin2bcd(tm.tm_mday);
		tm.tm_hour = bin2bcd(tm.tm_hour);
		tm.tm_min = bin2bcd(tm.tm_min);
		tm.tm_sec = bin2bcd(tm.tm_sec);
		tm.tm_mon |= century;

		mutex_lock(&rtc_lock);

		rtc_write(RTC_YEAR, tm.tm_year);
		rtc_write(RTC_MONTH, tm.tm_mon);
		rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
		rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
		rtc_write(RTC_HOURS, tm.tm_hour);
		rtc_write(RTC_MINUTES, tm.tm_min);
		rtc_write(RTC_SECONDS, tm.tm_sec);

		mutex_unlock(&rtc_lock);

		return 0;
	}
	case RTC_VL_READ:
		if (voltage_low)
			printk(KERN_ERR "%s: RTC Voltage Low - "
			       "reliable date/time information is no "
			       "longer guaranteed!\n", PCF8563_NAME);

		if (copy_to_user((int *) arg, &voltage_low, sizeof(int)))
			return -EFAULT;
		return 0;

	case RTC_VL_CLR:
	{
		/* Clear the VL bit in the seconds register in case
		 * the time has not been set already (which would
		 * have cleared it). This does not really matter
		 * because of the cached voltage_low value but do it
		 * anyway for consistency. */

		int ret = rtc_read(RTC_SECONDS);

		rtc_write(RTC_SECONDS, (ret & 0x7F));

		/* Clear the cached value. */
		voltage_low = 0;

		return 0;
	}
	default:
		return -ENOTTY;
	}

	return 0;
}
コード例 #17
0
ファイル: rtc-ds1511.c プロジェクト: Cool-Joe/imx23-audio
static inline void
rtc_disable_update(void)
{
	rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD);
}
コード例 #18
0
ファイル: rtc-omap.c プロジェクト: krzk/linux
static int omap_rtc_probe(struct platform_device *pdev)
{
	struct omap_rtc	*rtc;
	struct resource	*res;
	u8 reg, mask, new_ctrl;
	const struct platform_device_id *id_entry;
	const struct of_device_id *of_id;
	int ret;

	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
	if (!rtc)
		return -ENOMEM;

	of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
	if (of_id) {
		rtc->type = of_id->data;
		rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
				of_property_read_bool(pdev->dev.of_node,
						"system-power-controller");
	} else {
		id_entry = platform_get_device_id(pdev);
		rtc->type = (void *)id_entry->driver_data;
	}

	rtc->irq_timer = platform_get_irq(pdev, 0);
	if (rtc->irq_timer <= 0)
		return -ENOENT;

	rtc->irq_alarm = platform_get_irq(pdev, 1);
	if (rtc->irq_alarm <= 0)
		return -ENOENT;

	rtc->clk = devm_clk_get(&pdev->dev, "ext-clk");
	if (!IS_ERR(rtc->clk))
		rtc->has_ext_clk = true;
	else
		rtc->clk = devm_clk_get(&pdev->dev, "int-clk");

	if (!IS_ERR(rtc->clk))
		clk_prepare_enable(rtc->clk);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	rtc->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(rtc->base)) {
		clk_disable_unprepare(rtc->clk);
		return PTR_ERR(rtc->base);
	}

	platform_set_drvdata(pdev, rtc);

	/* Enable the clock/module so that we can access the registers */
	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	rtc->type->unlock(rtc);

	/*
	 * disable interrupts
	 *
	 * NOTE: ALARM2 is not cleared on AM3352 if rtc_write (writeb) is used
	 */
	rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, 0);

	/* enable RTC functional clock */
	if (rtc->type->has_32kclk_en) {
		reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
		rtc_writel(rtc, OMAP_RTC_OSC_REG,
				reg | OMAP_RTC_OSC_32KCLK_EN);
	}

	/* clear old status */
	reg = rtc_read(rtc, OMAP_RTC_STATUS_REG);

	mask = OMAP_RTC_STATUS_ALARM;

	if (rtc->type->has_pmic_mode)
		mask |= OMAP_RTC_STATUS_ALARM2;

	if (rtc->type->has_power_up_reset) {
		mask |= OMAP_RTC_STATUS_POWER_UP;
		if (reg & OMAP_RTC_STATUS_POWER_UP)
			dev_info(&pdev->dev, "RTC power up reset detected\n");
	}

	if (reg & mask)
		rtc_write(rtc, OMAP_RTC_STATUS_REG, reg & mask);

	/* On boards with split power, RTC_ON_NOFF won't reset the RTC */
	reg = rtc_read(rtc, OMAP_RTC_CTRL_REG);
	if (reg & OMAP_RTC_CTRL_STOP)
		dev_info(&pdev->dev, "already running\n");

	/* force to 24 hour mode */
	new_ctrl = reg & (OMAP_RTC_CTRL_SPLIT | OMAP_RTC_CTRL_AUTO_COMP);
	new_ctrl |= OMAP_RTC_CTRL_STOP;

	/*
	 * BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
	 *
	 *  - Device wake-up capability setting should come through chip
	 *    init logic. OMAP1 boards should initialize the "wakeup capable"
	 *    flag in the platform device if the board is wired right for
	 *    being woken up by RTC alarm. For OMAP-L138, this capability
	 *    is built into the SoC by the "Deep Sleep" capability.
	 *
	 *  - Boards wired so RTC_ON_nOFF is used as the reset signal,
	 *    rather than nPWRON_RESET, should forcibly enable split
	 *    power mode.  (Some chip errata report that RTC_CTRL_SPLIT
	 *    is write-only, and always reads as zero...)
	 */

	if (new_ctrl & OMAP_RTC_CTRL_SPLIT)
		dev_info(&pdev->dev, "split power mode\n");

	if (reg != new_ctrl)
		rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl);

	/*
	 * If we have the external clock then switch to it so we can keep
	 * ticking across suspend.
	 */
	if (rtc->has_ext_clk) {
		reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
		reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE;
		reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC;
		rtc_writel(rtc, OMAP_RTC_OSC_REG, reg);
	}

	rtc->type->lock(rtc);

	device_init_wakeup(&pdev->dev, true);

	rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
	if (IS_ERR(rtc->rtc)) {
		ret = PTR_ERR(rtc->rtc);
		goto err;
	}

	rtc->rtc->ops = &omap_rtc_ops;
	omap_rtc_nvmem_config.priv = rtc;

	/* handle periodic and alarm irqs */
	ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0,
			dev_name(&rtc->rtc->dev), rtc);
	if (ret)
		goto err;

	if (rtc->irq_timer != rtc->irq_alarm) {
		ret = devm_request_irq(&pdev->dev, rtc->irq_alarm, rtc_irq, 0,
				dev_name(&rtc->rtc->dev), rtc);
		if (ret)
			goto err;
	}

	if (rtc->is_pmic_controller) {
		if (!pm_power_off) {
			omap_rtc_power_off_rtc = rtc;
			pm_power_off = omap_rtc_power_off;
		}
	}

	/* Support ext_wakeup pinconf */
	rtc_pinctrl_desc.name = dev_name(&pdev->dev);

	rtc->pctldev = pinctrl_register(&rtc_pinctrl_desc, &pdev->dev, rtc);
	if (IS_ERR(rtc->pctldev)) {
		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
		ret = PTR_ERR(rtc->pctldev);
		goto err;
	}

	ret = rtc_register_device(rtc->rtc);
	if (ret)
		goto err;

	rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config);

	return 0;

err:
	clk_disable_unprepare(rtc->clk);
	device_init_wakeup(&pdev->dev, false);
	rtc->type->lock(rtc);
	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	return ret;
}
コード例 #19
0
ファイル: rtc-ds1511.c プロジェクト: Cool-Joe/imx23-audio
static int ds1511_rtc_probe(struct platform_device *pdev)
{
	struct rtc_device *rtc;
	struct resource *res;
	struct rtc_plat_data *pdata;
	int ret = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;
	pdata->size = resource_size(res);
	if (!devm_request_mem_region(&pdev->dev, res->start, pdata->size,
			pdev->name))
		return -EBUSY;
	ds1511_base = devm_ioremap(&pdev->dev, res->start, pdata->size);
	if (!ds1511_base)
		return -ENOMEM;
	pdata->ioaddr = ds1511_base;
	pdata->irq = platform_get_irq(pdev, 0);

	/*
	 * turn on the clock and the crystal, etc.
	 */
	rtc_write(0, RTC_CMD);
	rtc_write(0, RTC_CMD1);
	/*
	 * clear the wdog counter
	 */
	rtc_write(0, DS1511_WD_MSEC);
	rtc_write(0, DS1511_WD_SEC);
	/*
	 * start the clock
	 */
	rtc_enable_update();

	/*
	 * check for a dying bat-tree
	 */
	if (rtc_read(RTC_CMD1) & DS1511_BLF1)
		dev_warn(&pdev->dev, "voltage-low detected.\n");

	spin_lock_init(&pdata->lock);
	platform_set_drvdata(pdev, pdata);
	/*
	 * if the platform has an interrupt in mind for this device,
	 * then by all means, set it
	 */
	if (pdata->irq > 0) {
		rtc_read(RTC_CMD1);
		if (devm_request_irq(&pdev->dev, pdata->irq, ds1511_interrupt,
			IRQF_SHARED, pdev->name, pdev) < 0) {

			dev_warn(&pdev->dev, "interrupt not available.\n");
			pdata->irq = 0;
		}
	}

	rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &ds1511_rtc_ops,
					THIS_MODULE);
	if (IS_ERR(rtc))
		return PTR_ERR(rtc);
	pdata->rtc = rtc;

	ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr);

	return ret;
}
コード例 #20
0
ファイル: rtc-omap.c プロジェクト: mbgg/linux
static int __init omap_rtc_probe(struct platform_device *pdev)
{
	struct resource		*res, *mem;
	struct rtc_device	*rtc;
	u8			reg, new_ctrl;
	const struct platform_device_id *id_entry;
	const struct of_device_id *of_id;

	of_id = of_match_device(omap_rtc_of_match, &pdev->dev);
	if (of_id)
		pdev->id_entry = of_id->data;

	omap_rtc_timer = platform_get_irq(pdev, 0);
	if (omap_rtc_timer <= 0) {
		pr_debug("%s: no update irq?\n", pdev->name);
		return -ENOENT;
	}

	omap_rtc_alarm = platform_get_irq(pdev, 1);
	if (omap_rtc_alarm <= 0) {
		pr_debug("%s: no alarm irq?\n", pdev->name);
		return -ENOENT;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		pr_debug("%s: RTC resource data missing\n", pdev->name);
		return -ENOENT;
	}

	mem = request_mem_region(res->start, resource_size(res), pdev->name);
	if (!mem) {
		pr_debug("%s: RTC registers at %08x are not free\n",
			pdev->name, res->start);
		return -EBUSY;
	}

	rtc_base = ioremap(res->start, resource_size(res));
	if (!rtc_base) {
		pr_debug("%s: RTC registers can't be mapped\n", pdev->name);
		goto fail;
	}

	/* Enable the clock/module so that we can access the registers */
	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	id_entry = platform_get_device_id(pdev);
	if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER)) {
		rtc_writel(KICK0_VALUE, OMAP_RTC_KICK0_REG);
		rtc_writel(KICK1_VALUE, OMAP_RTC_KICK1_REG);
	}

	rtc = rtc_device_register(pdev->name, &pdev->dev,
			&omap_rtc_ops, THIS_MODULE);
	if (IS_ERR(rtc)) {
		pr_debug("%s: can't register RTC device, err %ld\n",
			pdev->name, PTR_ERR(rtc));
		goto fail0;
	}
	platform_set_drvdata(pdev, rtc);
	dev_set_drvdata(&rtc->dev, mem);

	/* clear pending irqs, and set 1/second periodic,
	 * which we'll use instead of update irqs
	 */
	rtc_write(0, OMAP_RTC_INTERRUPTS_REG);

	/* clear old status */
	reg = rtc_read(OMAP_RTC_STATUS_REG);
	if (reg & (u8) OMAP_RTC_STATUS_POWER_UP) {
		pr_info("%s: RTC power up reset detected\n",
			pdev->name);
		rtc_write(OMAP_RTC_STATUS_POWER_UP, OMAP_RTC_STATUS_REG);
	}
	if (reg & (u8) OMAP_RTC_STATUS_ALARM)
		rtc_write(OMAP_RTC_STATUS_ALARM, OMAP_RTC_STATUS_REG);

	/* handle periodic and alarm irqs */
	if (request_irq(omap_rtc_timer, rtc_irq, 0,
			dev_name(&rtc->dev), rtc)) {
		pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
			pdev->name, omap_rtc_timer);
		goto fail1;
	}
	if ((omap_rtc_timer != omap_rtc_alarm) &&
		(request_irq(omap_rtc_alarm, rtc_irq, 0,
			dev_name(&rtc->dev), rtc))) {
		pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
			pdev->name, omap_rtc_alarm);
		goto fail2;
	}

	/* On boards with split power, RTC_ON_NOFF won't reset the RTC */
	reg = rtc_read(OMAP_RTC_CTRL_REG);
	if (reg & (u8) OMAP_RTC_CTRL_STOP)
		pr_info("%s: already running\n", pdev->name);

	/* force to 24 hour mode */
	new_ctrl = reg & (OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP);
	new_ctrl |= OMAP_RTC_CTRL_STOP;

	/* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE:
	 *
	 *  - Device wake-up capability setting should come through chip
	 *    init logic. OMAP1 boards should initialize the "wakeup capable"
	 *    flag in the platform device if the board is wired right for
	 *    being woken up by RTC alarm. For OMAP-L138, this capability
	 *    is built into the SoC by the "Deep Sleep" capability.
	 *
	 *  - Boards wired so RTC_ON_nOFF is used as the reset signal,
	 *    rather than nPWRON_RESET, should forcibly enable split
	 *    power mode.  (Some chip errata report that RTC_CTRL_SPLIT
	 *    is write-only, and always reads as zero...)
	 */

	if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT)
		pr_info("%s: split power mode\n", pdev->name);

	if (reg != new_ctrl)
		rtc_write(new_ctrl, OMAP_RTC_CTRL_REG);

	return 0;

fail2:
	free_irq(omap_rtc_timer, rtc);
fail1:
	rtc_device_unregister(rtc);
fail0:
	if (id_entry && (id_entry->driver_data & OMAP_RTC_HAS_KICKER))
		rtc_writel(0, OMAP_RTC_KICK0_REG);
	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	iounmap(rtc_base);
fail:
	release_mem_region(mem->start, resource_size(mem));
	return -EIO;
}
コード例 #21
0
ファイル: rtc.c プロジェクト: canistation/coreboot
static void dcxo_init(void)
{
	/* Buffer setting */
	rtc_write(PMIC_RG_DCXO_CW15, 0xA2AA);
	rtc_write(PMIC_RG_DCXO_CW13, 0x98E9);
	rtc_write(PMIC_RG_DCXO_CW16, 0x9855);

	/* 26M enable control */
	/* Enable clock buffer XO_SOC, XO_CEL */
	rtc_write(PMIC_RG_DCXO_CW00, 0x4805);
	rtc_write(PMIC_RG_DCXO_CW11, 0x8000);

	/* Load thermal coefficient */
	rtc_write(PMIC_RG_TOP_TMA_KEY, 0x9CA7);
	rtc_write(PMIC_RG_DCXO_CW21, 0x12A7);
	rtc_write(PMIC_RG_DCXO_ELR0, 0xD004);
	rtc_write(PMIC_RG_TOP_TMA_KEY, 0x0000);

	/* Adjust OSC FPM setting */
	rtc_write(PMIC_RG_DCXO_CW07, 0x8FFE);

	/* Re-Calibrate OSC current */
	rtc_write(PMIC_RG_DCXO_CW09, 0x008F);
	udelay(100);
	rtc_write(PMIC_RG_DCXO_CW09, 0x408F);
	mdelay(5);
}
コード例 #22
0
ファイル: rtc-omap.c プロジェクト: mbgg/linux
static void omap_rtc_shutdown(struct platform_device *pdev)
{
	rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
}
コード例 #23
0
void rtc_set( struct rtc_time *tmp )
{
	if (phantom_flag < 0)
		phantom_flag = get_phantom_flag();

	if (phantom_flag) {
		uint year;
		unsigned char rtc[8];

		year = tmp->tm_year;
		year -= (year < 2000) ? 1900 : 2000;

		rtc[0] = bin2bcd(0);
		rtc[1] = bin2bcd(tmp->tm_sec);
		rtc[2] = bin2bcd(tmp->tm_min);
		rtc[3] = bin2bcd(tmp->tm_hour);
		rtc[4] = bin2bcd(tmp->tm_wday);
		rtc[5] = bin2bcd(tmp->tm_mday);
		rtc[6] = bin2bcd(tmp->tm_mon);
		rtc[7] = bin2bcd(year);

		phantom_rtc_write(RTC_BASE, rtc);
	} else {
		uchar reg_a;
		if (century_flag < 0)
			century_flag = get_century_flag();

		/* lock clock registers for write */
		reg_a = rtc_read( RTC_CONTROLA );
		rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));

		rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));

		rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
		rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
		rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
		rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
		rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));

		/* break year up into century and year in century */
		if (century_flag) {
			rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
			rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
			reg_a &= 0xc0;
			reg_a |= bin2bcd( tmp->tm_year / 100 );
		} else {
			rtc_write(RTC_YEAR, bin2bcd(tmp->tm_year -
				((tmp->tm_year < 2000) ? 1900 : 2000)));
		}

		/* unlock clock registers after read */
		rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
	}
}
コード例 #24
0
ファイル: rtc.c プロジェクト: lacombar/netbsd-alc
int
settime_old(todr_chip_handle_t tcr, struct clock_ymdhms *dt)
{
	u_char h;

	/* Stop the clock */
	rtc_write(RTC_CONTROL,rtc_read(RTC_CONTROL) & ~RTC_START);

#ifdef RTC_DEBUG
	printf("Setting RTC to 0x%08x.  Regs before:\n",secs);
	rtc_print();
#endif

	rtc_write(RTC_SEC,TOBCD(dt->dt_sec));
	rtc_write(RTC_MIN,TOBCD(dt->dt_min));
	h = rtc_read(RTC_HRS);
	if (h & 0x80) {		/* time is am/pm format */
		if (dt->dt_hour == 0) {
			rtc_write(RTC_HRS,TOBCD(12)|0x80);
		} else if (dt->dt_hour < 12) {	/* am */
			rtc_write(RTC_HRS,TOBCD(dt->dt_hour)|0x80);
		} else if (dt->dt_hour == 12) {
				rtc_write(RTC_HRS,TOBCD(12)|0x80|0x20);
		} else 		/* pm */
			rtc_write(RTC_HRS,TOBCD(dt->dt_hour-12)|0x80|0x20);
	} else {	/* time is 24 hour format */
			rtc_write(RTC_HRS,TOBCD(dt->dt_hour));
	}
	rtc_write(RTC_DAY,TOBCD(dt->dt_wday));
	rtc_write(RTC_DATE,TOBCD(dt->dt_day));
	rtc_write(RTC_MON,TOBCD(dt->dt_mon));
	rtc_write(RTC_YR,TOBCD(dt->dt_year%100));

#ifdef RTC_DEBUG
	printf("Regs after:\n",secs);
	rtc_print();
#endif

	/* restart the clock */
	rtc_write(RTC_CONTROL,rtc_read(RTC_CONTROL) | RTC_START);
	return 0;
}
コード例 #25
0
int __init
pcf8563_init(void)
{
    static int res;
    static int first = 1;

    if (!first)
        return res;
    first = 0;

    /* Initiate the i2c protocol. */
    res = i2c_init();
    if (res < 0) {
        printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
        return res;
    }

    /*
     * First of all we need to reset the chip. This is done by
     * clearing control1, control2 and clk freq and resetting
     * all alarms.
     */
    if (rtc_write(RTC_CONTROL1, 0x00) < 0)
        goto err;

    if (rtc_write(RTC_CONTROL2, 0x00) < 0)
        goto err;

    if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
        goto err;

    if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
        goto err;

    /* Reset the alarms. */
    if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
        goto err;

    if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
        goto err;

    if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
        goto err;

    if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
        goto err;

    /* Check for low voltage, and warn about it. */
    if (rtc_read(RTC_SECONDS) & 0x80) {
        voltage_low = 1;
        printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
               "date/time information is no longer guaranteed!\n",
               PCF8563_NAME);
    }

    return res;

err:
    printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
    res = -1;
    return res;
}
コード例 #26
0
ファイル: file_op.c プロジェクト: HLi91/ECE391OS
/*
 * sys_rtc_write
 * Description:  write system RTC
 * INPUTS:	
		 int32_t fd -- file descriptor
		 void* buf -- buffer address
		 int32_t nbytes -- number of bytes
		 pcb_t* mypcb -- Process control block
 * OUTPUTS:	None
 * RETURN: None
 * SIDE EFFECTS: None
 */
extern int32_t sys_rtc_write(int32_t fd, const void* buf, int32_t nbytes, pcb_t* mypcb)
{
	return rtc_write(fd, buf, nbytes);

}