示例#1
0
static int da8xx_rtc_bin2bcd(struct rtc_time *tm)
{
	if (rtc_valid_tm(tm) != 0)
		return -EINVAL;

	tm->tm_sec = BIN2BCD(tm->tm_sec);
	tm->tm_min = BIN2BCD(tm->tm_min);
	tm->tm_hour = BIN2BCD(tm->tm_hour);
	tm->tm_mday = BIN2BCD(tm->tm_mday);
	tm->tm_mon = BIN2BCD(tm->tm_mon + 1);
	tm->tm_year = BIN2BCD(tm->tm_year % 100);

	return 0;
}
示例#2
0
static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
    void __iomem *ioaddr = pdata->ioaddr;
    u8 flags;

    flags = readb(pdata->ioaddr + RTC_FLAGS);
    writeb(flags | RTC_WRITE, pdata->ioaddr + RTC_FLAGS);

    writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR);
    writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH);
    writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
    writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE);
    writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS);
    writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES);
    writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
    writeb(BIN2BCD((tm->tm_year + 1900) / 100), ioaddr + RTC_CENTURY);

    writeb(flags & ~RTC_WRITE, pdata->ioaddr + RTC_FLAGS);
    return 0;
}
示例#3
0
int m48t37y_set_time(unsigned long sec)
{
#ifdef CONFIG_MIPS64
	unsigned char* rtc_base = (unsigned char*)0xfffffffffc800000;
#else
	unsigned char* rtc_base = (unsigned char*)0xfc800000;
#endif
	struct rtc_time tm;

	/* convert to a more useful format -- note months count from 0 */
	to_tm(sec, &tm);
	tm.tm_mon += 1;

	/* enable writing */
	rtc_base[0x7ff8] = 0x80;

	/* year */
	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);

	/* month */
	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);

	/* day */
	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);

	/* hour/min/sec */
	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);

	/* day of week -- not really used, but let's keep it up-to-date */
	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);

	/* disable writing */
	rtc_base[0x7ff8] = 0x00;

	return 0;
}
示例#4
0
int
RTCFUNC(set,ds15x1)(struct tm *tm, int cent_reg) {
	unsigned	seconds;
	unsigned	minutes;
	unsigned	hours;
	unsigned	day;
	unsigned	month;
	unsigned	year;
	unsigned	cent;
	unsigned	ctrlb;

	/* convert binary to BCD */
	seconds	= BIN2BCD(tm->tm_sec);
	minutes	= BIN2BCD(tm->tm_min);
	hours	= BIN2BCD(tm->tm_hour);
	day 	= BIN2BCD(tm->tm_mday);
	month	= BIN2BCD(tm->tm_mon + 1);
	year	= BIN2BCD(tm->tm_year % 100);
	cent	= BIN2BCD((tm->tm_year / 100) + 19);

#ifdef DIAG
	fprintf(stderr,"rtc set: cent=%d; year=%d (after adjustment)\n",cent,year);
#endif

	month |= chip_read8(5) & 0xE0;	/* EOSC#/E32K#/BB32 */

	ctrlb = chip_read8(DS15x1_CONTROLB);
	chip_write8(DS15x1_CONTROLB, ctrlb & ~TRANSFER_ENABLE);

	chip_write8(0, seconds);
	chip_write8(1, minutes);
	chip_write8(2, hours);
	chip_write8(3, tm->tm_wday + 1);
	chip_write8(4, day);
	chip_write8(5, month);
	chip_write8(6, year);
	if (cent_reg >= 0)
		chip_write8(cent_reg, cent);

	chip_write8(DS15x1_CONTROLB, ctrlb | TRANSFER_ENABLE);

	return (0);
}
int
RTCFUNC(set,ds1386)(struct tm *tm, int cent_reg) {
	unsigned	seconds;
	unsigned	minutes;
	unsigned	hours;
	unsigned	day;
	unsigned	month;
	unsigned	year;
	unsigned	cent;

	// convert binary to BCD
	seconds	= BIN2BCD(tm->tm_sec);
	minutes	= BIN2BCD(tm->tm_min);
	hours	= BIN2BCD(tm->tm_hour);
	day 	= BIN2BCD(tm->tm_mday);
	month	= BIN2BCD(tm->tm_mon + 1);
	year	= BIN2BCD(tm->tm_year % 100);
	cent	= BIN2BCD((tm->tm_year / 100) + 19);

#ifdef DIAG
	fprintf(stderr,"rtc set: cent=%d; year=%d (after adjustment)\n",cent,year);
#endif

	month |= chip_read8(9) & 0x40;	/* ESQW# */

	chip_write8(9, 0);	/* turn off clock */

	chip_write8(0, 0);	//hundredth's of second
	chip_write8(1, seconds);
	chip_write8(2, minutes);
	chip_write8(4, hours | MILTIME);
	chip_write8(6, tm->tm_wday + 1);
	chip_write8(8, day);
	chip_write8(10, year);
	if(cent_reg >= 0) {
		chip_write8(cent_reg, cent);
	}

	chip_write8(9, month & 0x5f);	/* EOSC# low to start clock */
	chip_write8(CMD_REG, chip_read8(CMD_REG) | TRANSFER_ENABLE);

	return(0);
}
示例#6
0
int rtc_set (struct rtc_time* tm)
{
	if(tm->tm_year < 2000)
		tm->tm_year -= 1900;
	else
		tm->tm_year -= 2000;

	RTCCON |= 1;
	BCDYEAR = BIN2BCD(tm->tm_year);
	BCDMON = BIN2BCD(tm->tm_mon);
	BCDDAY = BIN2BCD(tm->tm_mday);
	BCDDATE = BIN2BCD(tm->tm_wday);
	BCDHOUR = BIN2BCD(tm->tm_hour);
	BCDMIN = BIN2BCD(tm->tm_min);
	BCDSEC = BIN2BCD(tm->tm_sec);
	RTCCON &= 1;

	return 0;
}
示例#7
0
static int s3c2410_rtc_settime(struct rtc_time *tm)
{
	/* the rtc gets round the y2k problem by just not supporting it */

	if (tm->tm_year < 100)
		return -EINVAL;

	writeb(BIN2BCD(tm->tm_sec),  S3C2410_RTCSEC);
	writeb(BIN2BCD(tm->tm_min),  S3C2410_RTCMIN);
	writeb(BIN2BCD(tm->tm_hour), S3C2410_RTCHOUR);
	writeb(BIN2BCD(tm->tm_mday), S3C2410_RTCDATE);
	writeb(BIN2BCD(tm->tm_mon + 1), S3C2410_RTCMON);
	writeb(BIN2BCD(tm->tm_year - 100), S3C2410_RTCYEAR);

	return 0;
}
示例#8
0
int m41t81_set_time(unsigned long t)
{
	struct rtc_time tm;

	to_tm(t, &tm);

	/*
	 * Note the write order matters as it ensures the correctness.
	 * When we write sec, 10th sec is clear.  It is reasonable to 
	 * believe we should finish writing min within a second.
	 */

	tm.tm_sec = BIN2BCD(tm.tm_sec);
	m41t81_write(M41T81REG_SC, tm.tm_sec);
	
	tm.tm_min = BIN2BCD(tm.tm_min);
	m41t81_write(M41T81REG_MN, tm.tm_min);

	tm.tm_hour = BIN2BCD(tm.tm_hour);
	tm.tm_hour = (tm.tm_hour & 0x3f) | (m41t81_read(M41T81REG_HR) & 0xc0);
	m41t81_write(M41T81REG_HR, tm.tm_hour);

	/* tm_wday starts from 0 to 6 */
	if (tm.tm_wday == 0) tm.tm_wday = 7;
	tm.tm_wday = BIN2BCD(tm.tm_wday);
	m41t81_write(M41T81REG_DY, tm.tm_wday);

	tm.tm_mday = BIN2BCD(tm.tm_mday);
	m41t81_write(M41T81REG_DT, tm.tm_mday);

	/* tm_mon starts from 0, *ick* */
	tm.tm_mon ++;
	tm.tm_mon = BIN2BCD(tm.tm_mon);
	m41t81_write(M41T81REG_MO, tm.tm_mon);

	/* we don't do century, everything is beyond 2000 */
	tm.tm_year %= 100;
	tm.tm_year = BIN2BCD(tm.tm_year);
	m41t81_write(M41T81REG_YR, tm.tm_year);

	return 0;
}
示例#9
0
文件: setup.c 项目: 1x23/unifi-gpl
int m48t37y_set_time(unsigned long sec)
{
	struct rtc_time tm;
	unsigned long flags;

	/* convert to a more useful format -- note months count from 0 */
	to_tm(sec, &tm);
	tm.tm_mon += 1;

	spin_lock_irqsave(&rtc_lock, flags);
	/* enable writing */
	rtc_base[0x7ff8] = 0x80;

	/* year */
	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);

	/* month */
	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);

	/* day */
	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);

	/* hour/min/sec */
	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);

	/* day of week -- not really used, but let's keep it up-to-date */
	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);

	/* disable writing */
	rtc_base[0x7ff8] = 0x00;
	spin_unlock_irqrestore(&rtc_lock, flags);

	return 0;
}
int m48t37y_set_time(unsigned long sec)
{
	struct rtc_time tm;
	unsigned long flags;

	/* convert to a more useful format -- note months count from 0 */
	to_tm(sec, &tm);
	tm.tm_mon += 1;

	spin_lock_irqsave(&rtc_lock, flags);
	/* enable writing */
	m48t37_base->control = 0x80;

	/* year */
	m48t37_base->year = BIN2BCD(tm.tm_year % 100);
	m48t37_base->century = BIN2BCD(tm.tm_year / 100);

	/* month */
	m48t37_base->month = BIN2BCD(tm.tm_mon);

	/* day */
	m48t37_base->date = BIN2BCD(tm.tm_mday);

	/* hour/min/sec */
	m48t37_base->hour = BIN2BCD(tm.tm_hour);
	m48t37_base->min = BIN2BCD(tm.tm_min);
	m48t37_base->sec = BIN2BCD(tm.tm_sec);

	/* day of week -- not really used, but let's keep it up-to-date */
	m48t37_base->day = BIN2BCD(tm.tm_wday + 1);

	/* disable writing */
	m48t37_base->control = 0x00;
	spin_unlock_irqrestore(&rtc_lock, flags);

	return 0;
}
示例#11
0
int
RTCFUNC(set,mc9s08dz60)(struct tm *tm, int cent_reg)
{
    uint8_t		date[7];

    date[MC9S08DZ60_SEC]   = BIN2BCD(tm->tm_sec) | MC9S08DZ60_RTC_RUN;
    date[MC9S08DZ60_MIN]   = BIN2BCD(tm->tm_min);
	date[MC9S08DZ60_HOUR]  = BIN2BCD(tm->tm_hour);
    date[MC9S08DZ60_DAY]   = BIN2BCD(tm->tm_wday + 1);
    date[MC9S08DZ60_DATE]  = BIN2BCD(tm->tm_mday - 1);
    date[MC9S08DZ60_MONTH] = BIN2BCD(tm->tm_mon);
    date[MC9S08DZ60_YEAR]  = BIN2BCD(tm->tm_year % 100);

    if (mc9s08dz60_i2c_write(MC9S08DZ60_REAL_TIME_DATA, date, 7) != EOK) {
    	fprintf(stderr, "Unable to write data to I2C device\n");
    	return -1;
    }

    return(0);
}
示例#12
0
/*!
 * \brief Set an PCF85XX hardware clock.
 *
 * New time will be taken over at the beginning of the next second.
 *
 * \param rtc Specifies the RTC device.
 * \param tm  Points to a structure which contains the date and time
 *            information.
 *
 * \return 0 on success or -1 in case of an error.
 */
static int I2cPcfSetClock(NUTRTC *rtc, const struct _tm *tm)
{
    uint8_t data[8];

    data[0] = 2;
    data[1] = BIN2BCD(tm->tm_sec);
    data[2] = BIN2BCD(tm->tm_min);
    data[3] = BIN2BCD(tm->tm_hour);
    data[4] = BIN2BCD(tm->tm_mday);
    data[5] = tm->tm_wday;
    data[6] = BIN2BCD(tm->tm_mon + 1);
    if (tm->tm_year > 99) {
        data[7] = BIN2BCD(tm->tm_year - 100);
        data[6] |= 0x80;
    }
    else {
        data[7] = BIN2BCD(tm->tm_year);
    }
    return NutI2cMasterTransceive(rtc->dcb, data, 8, NULL, 0);
}
示例#13
0
static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
	void __iomem *ioaddr = pdata->ioaddr_rtc;
	u8 century;

	century = BIN2BCD((tm->tm_year + 1900) / 100);

	writeb(RTC_WRITE, ioaddr + RTC_CONTROL);

	writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR);
	writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH);
	writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
	writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE);
	writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS);
	writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES);
	writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);

	/* RTC_CENTURY and RTC_CONTROL share same register */
	writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY);
	writeb(century & RTC_CENTURY_MASK, ioaddr + RTC_CONTROL);
	return 0;
}
示例#14
0
static int max6902_set_datetime(struct device *dev, struct rtc_time *dt)
{
	dt->tm_year = dt->tm_year+1900;

#ifdef MAX6902_DEBUG
	printk("\n%s : Setting RTC values\n",__FUNCTION__);
	printk("tm_sec : %i\n",dt->tm_sec);
	printk("tm_min : %i\n",dt->tm_min);
	printk("tm_hour: %i\n",dt->tm_hour);
	printk("tm_mday: %i\n",dt->tm_mday);
	printk("tm_wday: %i\n",dt->tm_wday);
	printk("tm_year: %i\n",dt->tm_year);
#endif

	/* Remove write protection */
	max6902_set_reg(dev, 0xF, 0);

	max6902_set_reg(dev, 0x01, BIN2BCD(dt->tm_sec));
	max6902_set_reg(dev, 0x03, BIN2BCD(dt->tm_min));
	max6902_set_reg(dev, 0x05, BIN2BCD(dt->tm_hour));

	max6902_set_reg(dev, 0x07, BIN2BCD(dt->tm_mday));
	max6902_set_reg(dev, 0x09, BIN2BCD(dt->tm_mon+1));
	max6902_set_reg(dev, 0x0B, BIN2BCD(dt->tm_wday));
	max6902_set_reg(dev, 0x0D, BIN2BCD(dt->tm_year%100));
	max6902_set_reg(dev, 0x13, BIN2BCD(dt->tm_year/100));

	/* Compulab used a delay here. However, the datasheet
	 * does not mention a delay being required anywhere... */
	/* delay(2000); */

	/* Write protect */
	max6902_set_reg(dev, 0xF, 0x80);

	return 0;
}
int
RTCFUNC(set,m41t6x)(struct tm *tm, int cent_reg)
{
    unsigned char   date[7];
    char   century;

    date[M41T6x_SEC]   = BIN2BCD(tm->tm_sec); 	    /* implicitly clears stop bit */
    date[M41T6x_MIN]   = BIN2BCD(tm->tm_min);
    date[M41T6x_HOUR]  = BIN2BCD(tm->tm_hour);
    date[M41T6x_DAY]   = BIN2BCD(tm->tm_wday + 1);
    date[M41T6x_DATE]  = BIN2BCD(tm->tm_mday);
    date[M41T6x_MONTH] = BIN2BCD(tm->tm_mon + 1);
    date[M41T6x_YEAR]  = BIN2BCD(tm->tm_year % 100);

    century = tm->tm_year / 100 - 1;
    date[M41T6x_MONTH] |= century << 6;

    m41t6x_i2c_write(M41T6x_REGOFFSET, date, 7);

    return(0);
}
示例#16
0
static int menelaus_set_time(struct device *dev, struct rtc_time *t)
{
	int		status;

	/* write date and time registers */
	status = time_to_menelaus(t, MENELAUS_RTC_SEC);
	if (status < 0)
		return status;
	status = menelaus_write_reg(MENELAUS_RTC_WKDAY, BIN2BCD(t->tm_wday));
	if (status < 0) {
		dev_err(&the_menelaus->client->dev, "rtc write reg %02x"
				"err %d\n", MENELAUS_RTC_WKDAY, status);
		return status;
	}

	/* now commit the write */
	status = menelaus_write_reg(MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
	if (status < 0)
		dev_err(&the_menelaus->client->dev, "rtc commit time, err %d\n",
				status);

	return 0;
}
static int r9701_set_datetime(struct device *dev, struct rtc_time *dt)
{
	int ret, year;

	year = dt->tm_year + 1900;
	if (year >= 2100 || year < 2000)
		return -EINVAL;

	ret = write_reg(dev, RHRCNT, BIN2BCD(dt->tm_hour));
	ret = ret ? ret : write_reg(dev, RMINCNT, BIN2BCD(dt->tm_min));
	ret = ret ? ret : write_reg(dev, RSECCNT, BIN2BCD(dt->tm_sec));
	ret = ret ? ret : write_reg(dev, RDAYCNT, BIN2BCD(dt->tm_mday));
	ret = ret ? ret : write_reg(dev, RMONCNT, BIN2BCD(dt->tm_mon + 1));
	ret = ret ? ret : write_reg(dev, RYRCNT, BIN2BCD(dt->tm_year - 100));
	ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday);

	return ret;
}
示例#18
0
static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
	int i, err;
	unsigned char buf[9];

	dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
		"mday=%d, mon=%d, year=%d, wday=%d\n",
		__FUNCTION__,
		tm->tm_sec, tm->tm_min, tm->tm_hour,
		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

	/* hours, minutes and seconds */
	buf[PCF8563_REG_SC] = BIN2BCD(tm->tm_sec);
	buf[PCF8563_REG_MN] = BIN2BCD(tm->tm_min);
	buf[PCF8563_REG_HR] = BIN2BCD(tm->tm_hour);

	buf[PCF8563_REG_DM] = BIN2BCD(tm->tm_mday);

	/* month, 1 - 12 */
	buf[PCF8563_REG_MO] = BIN2BCD(tm->tm_mon + 1);

	/* year and century */
	buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
	if (tm->tm_year / 100)
		buf[PCF8563_REG_MO] |= PCF8563_MO_C;

	buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;

	/* write register's data */
	for (i = 0; i < 7; i++) {
		unsigned char data[2] = { PCF8563_REG_SC + i,
						buf[PCF8563_REG_SC + i] };

		err = i2c_master_send(client, data, sizeof(data));
		if (err != sizeof(data)) {
			dev_err(&client->dev,
				"%s: err=%d addr=%02x, data=%02x\n",
				__FUNCTION__, err, data[0], data[1]);
			return -EIO;
		}
	};

	return 0;
}
示例#19
0
int
RTCFUNC(set,m41t00)(struct tm *tm, int cent_reg)
{
    unsigned char   date[7];
    char   century;

    date[M41T00_SEC]   = BIN2BCD(tm->tm_sec); /* implicitly clears stop bit */
    date[M41T00_MIN]   = BIN2BCD(tm->tm_min);
    date[M41T00_HOUR]  = BIN2BCD(tm->tm_hour) | M41T00_HOUR_CEB;
    date[M41T00_DAY]   = BIN2BCD(tm->tm_wday + 1);
    date[M41T00_DATE]  = BIN2BCD(tm->tm_mday);
    date[M41T00_MONTH] = BIN2BCD(tm->tm_mon + 1);
    date[M41T00_YEAR]  = BIN2BCD(tm->tm_year % 100);

    century = tm->tm_year / 100 - 1;
    if (century != 0)
        date[M41T00_HOUR] |= M41T00_HOUR_CB;

    m41t00_i2c_write(M41T00_SEC, date, 7);

    return(0);
}
示例#20
0
/* this hardware doesn't support "don't care" alarm fields */
static int tm2bcd(struct rtc_time *tm)
{
	if (rtc_valid_tm(tm) != 0)
		return -EINVAL;

	tm->tm_sec = BIN2BCD(tm->tm_sec);
	tm->tm_min = BIN2BCD(tm->tm_min);
	tm->tm_hour = BIN2BCD(tm->tm_hour);
	tm->tm_mday = BIN2BCD(tm->tm_mday);

	tm->tm_mon = BIN2BCD(tm->tm_mon + 1);

	/* epoch == 1900 */
	if (tm->tm_year < 100 || tm->tm_year > 199)
		return -EINVAL;
	tm->tm_year = BIN2BCD(tm->tm_year - 100);

	return 0;
}
示例#21
0
/*!
 * \brief Set an PCF8563 hardware clock.
 *
 * New time will be taken over at the beginning of the next second.
 *
 * \param tm Points to a structure which contains the date and time
 *           information.
 *
 * \return 0 on success or -1 in case of an error.
 */
int PcfRtcSetClock(NUTRTC *rtc, const struct _tm *tm)
{
    uint8_t data[8];

    memset(data, 0, sizeof(data));
    if (tm) {
        data[0] = 0x02;
        data[1] = BIN2BCD(tm->tm_sec);
        data[2] = BIN2BCD(tm->tm_min);
        data[3] = BIN2BCD(tm->tm_hour);
        data[4] = BIN2BCD(tm->tm_mday);
        data[5] = tm->tm_wday;
        data[6] = BIN2BCD(tm->tm_mon + 1);
        if (tm->tm_year > 99) {
            data[7] = BIN2BCD(tm->tm_year - 100);
            data[6] |= 0x80;
        }
        else {
            data[7] = BIN2BCD(tm->tm_year);
        }
    }
    return PcfRtcWrite(0, data, 8);
}
示例#22
0
int rtc_set(struct rtc_time *tm)
{
	int i;
	u8 buf[8];

	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
	      tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
	      tm->tm_hour, tm->tm_min, tm->tm_sec);

	buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
	buf[CCR_MIN] = BIN2BCD(tm->tm_min);

	/* set hour and 24hr bit */
	buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL;

	buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);

	/* month, 1 - 12 */
	buf[CCR_MONTH] = BIN2BCD(tm->tm_mon);

	/* year, since the rtc epoch*/
	buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100);
	buf[CCR_WDAY] = tm->tm_wday & 0x07;
	buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100);

	/* this sequence is required to unlock the chip */
	rtc_write(X1205_REG_SR, X1205_SR_WEL);
	rtc_write(X1205_REG_SR, X1205_SR_WEL | X1205_SR_RWEL);

	/* write register's data */
	for (i = 0; i < 8; i++)
		rtc_write(X1205_CCR_BASE + i, buf[i]);

	rtc_write(X1205_REG_SR, 0);

	return 0;
}
示例#23
0
static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
	unsigned char save_control;
	unsigned char rtc_data[ALL_TIME_REGS + 1];
	int ret;

	/* Month range is 01..12 */
	tm->tm_mon++;

	rtc_data[1] = BIN2BCD(tm->tm_sec);
	rtc_data[2] = BIN2BCD(tm->tm_min);
	rtc_data[3] = BIN2BCD(tm->tm_hour);
	rtc_data[4] = BIN2BCD(tm->tm_mday);
	rtc_data[5] = BIN2BCD(tm->tm_mon);
	rtc_data[6] = BIN2BCD(tm->tm_year);

	/* Stop RTC while updating the TC registers */
	ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
	if (ret < 0)
		goto out;

	save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
	twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
	if (ret < 0)
		goto out;

	/* update all the alarm registers in one shot */
	ret = twl4030_i2c_write(TWL4030_MODULE_RTC, rtc_data,
			        REG_SECONDS_REG, ALL_TIME_REGS);
	if (ret < 0) {
		printk(KERN_ERR "twl4030: twl4030_i2c_write error.\n");
		goto out;
	}

	/* Start back RTC */
	save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
	ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);

out:
	return ret;
}
示例#24
0
int  set_time(unsigned int year0,unsigned int year1,unsigned int month,unsigned int day,unsigned int hour,unsigned int min,unsigned int sec)
{
    int i;
    unsigned char buf[7];
    unsigned char i2cdata[3];

    rtc_tm.tm_year =year1;
    rtc_tm.tm_mon = month;
    rtc_tm.tm_mday = day;
    rtc_tm.tm_hour = hour;
    rtc_tm.tm_min = min;
    rtc_tm.tm_sec = sec;

    DebugPrintf("\nwrite rtc %02d%02d%02d%02d%d.%02d",rtc_tm.tm_mon,rtc_tm.tm_mday,rtc_tm.tm_hour,rtc_tm.tm_min,rtc_tm.tm_year,rtc_tm.tm_sec);

    buf[0] = BIN2BCD(rtc_tm.tm_sec);
    buf[1] = BIN2BCD(rtc_tm.tm_min);
    buf[2] = BIN2BCD(rtc_tm.tm_hour);
    buf[3] = 0x01;             				//由于设置时间时不用星期这个项,故每次设置时默认为星期一
    buf[4] = BIN2BCD(rtc_tm.tm_mday);
    buf[5] = BIN2BCD(rtc_tm.tm_mon);
    buf[6] = BIN2BCD(rtc_tm.tm_year);

    if (fd_i2c)
    {
         for(i=0;i<7;i++)
         {
              i2cdata[0] = i;
              i2cdata[1] = buf[i];
              if (write(fd_i2c,&i2cdata[0], 2) != 2)
              {
                  DebugPrintf("\nWrite error at %d", i);
                  return -1;
              }
         }
    }
    return 0;
}
示例#25
0
/*!
 * \brief Set alarm of an X12xx hardware clock.
 *
 * \deprecated New applications must use NutRtcSetAlarm().
 *
 * \param idx   Zero based index. Two alarms are supported.
 * \param tm    Points to a structure which contains the date and time
 *              information. May be NULL to clear the alarm.
 * \param aflgs Each bit enables a specific comparision.
 *              - Bit 0: Seconds
 *              - Bit 1: Minutes
 *              - Bit 2: Hours
 *              - Bit 3: Day of month
 *              - Bit 4: Month
 *              - Bit 7: Day of week (Sunday is zero)
 *
 * \return 0 on success or -1 in case of an error.
 */
int X12RtcSetAlarm(int idx, CONST struct _tm *tm, int aflgs)
{
    u_char data[10];

	int flags;
    memset(data, 0, sizeof(data));
    data[1] = idx * 8;
    if (tm)
    {
        if (aflgs & RTC_ALARM_SECOND)
        {
            data[2] = BIN2BCD(tm->tm_sec) | X12RTC_SCA_ESC;
        }
        if (aflgs & RTC_ALARM_MINUTE)
        {
            data[3] = BIN2BCD(tm->tm_min) | X12RTC_MNA_EMN;
        }
        if (aflgs & RTC_ALARM_HOUR)
        {
            data[4] = BIN2BCD(tm->tm_hour) | X12RTC_HRA_EHR;
        }
        if (aflgs & RTC_ALARM_MDAY)
        {
            data[5] = BIN2BCD(tm->tm_mday) | X12RTC_DTA_EDT;
        }
        if (aflgs & RTC_ALARM_MONTH)
        {
            data[6] = BIN2BCD(tm->tm_mon + 1) | X12RTC_MOA_EMO;
        }
        if (aflgs & RTC_ALARM_WDAY)
        {
            data[8] = BIN2BCD(tm->tm_wday) | X12RTC_DWA_EDW;
        }
    }
	X12RtcGetAlarm(1, &test, &flags);
    //printf("\n set Alarm: date: %d-%d-%d Time: %d:%d:%d \n", test.tm_year, test.tm_mon, test.tm_mday, test.tm_hour, test.tm_min, test.tm_sec);
    return(X12RtcWrite(1, data, 10));
}
示例#26
0
文件: rtc.c 项目: TitaniumBoy/lin
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		     unsigned long arg)
{
	volatile MK48T08ptr_t rtc = (MK48T08ptr_t)MVME_RTC_BASE;
	unsigned long flags;
	struct rtc_time wtime; 

	switch (cmd) {
	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
	{
		save_flags(flags);
		cli();
		/* Ensure clock and real-time-mode-register are accessible */
		rtc->ctrl = RTC_READ;
		wtime.tm_sec =  BCD2BIN(rtc->bcd_sec);
		wtime.tm_min =  BCD2BIN(rtc->bcd_min);
		wtime.tm_hour = BCD2BIN(rtc->bcd_hr);
		wtime.tm_mday =  BCD2BIN(rtc->bcd_dom);
		wtime.tm_mon =  BCD2BIN(rtc->bcd_mth)-1;
		wtime.tm_year = BCD2BIN(rtc->bcd_year);
		if (wtime.tm_year < 70)
			wtime.tm_year += 100;
		wtime.tm_wday = BCD2BIN(rtc->bcd_dow)-1;
		rtc->ctrl = 0;
		restore_flags(flags);
		return copy_to_user((void *)arg, &wtime, sizeof wtime) ?
								-EFAULT : 0;
	}
	case RTC_SET_TIME:	/* Set the RTC */
	{
		struct rtc_time rtc_tm;
		unsigned char mon, day, hrs, min, sec, leap_yr;
		unsigned int yrs;

		if (!capable(CAP_SYS_ADMIN))
			return -EACCES;

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

		yrs = rtc_tm.tm_year;
		if (yrs < 1900)
			yrs += 1900;
		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
		day = rtc_tm.tm_mday;
		hrs = rtc_tm.tm_hour;
		min = rtc_tm.tm_min;
		sec = rtc_tm.tm_sec;

		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));

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

		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
			return -EINVAL;

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

		if (yrs >= 2070)
			return -EINVAL;
		
		save_flags(flags);
		cli();
		rtc->ctrl     = RTC_WRITE;

		rtc->bcd_sec  = BIN2BCD(sec);
		rtc->bcd_min  = BIN2BCD(min);
		rtc->bcd_hr   = BIN2BCD(hrs);
		rtc->bcd_dom  = BIN2BCD(day);
		rtc->bcd_mth  = BIN2BCD(mon);
		rtc->bcd_year = BIN2BCD(yrs%100);

		rtc->ctrl     = 0;
		restore_flags(flags);
		return 0;
	}
	default:
		return -EINVAL;
	}
}
示例#27
0
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		     unsigned long arg)
{

	struct rtc_time wtime;

	switch (cmd) {
	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
	{
		get_rtc_time(&wtime);
		break;
	}
	case RTC_SET_TIME:	/* Set the RTC */
	{
		struct rtc_time rtc_tm;
		unsigned char mon, day, hrs, min, sec, leap_yr;
		unsigned int yrs;

		if (!capable(CAP_SYS_TIME))
			return -EACCES;

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

		yrs = rtc_tm.tm_year + 1900;
		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
		day = rtc_tm.tm_mday;
		hrs = rtc_tm.tm_hour;
		min = rtc_tm.tm_min;
		sec = rtc_tm.tm_sec;

		if (yrs < 1970)
			return -EINVAL;

		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));

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

		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
			return -EINVAL;

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

		if ((yrs -= epoch) > 255)    /* They are unsigned */
			return -EINVAL;

		if (yrs > 169)
			return -EINVAL;

		if (yrs >= 100)
			yrs -= 100;

		sec = BIN2BCD(sec);
		min = BIN2BCD(min);
		hrs = BIN2BCD(hrs);
		day = BIN2BCD(day);
		mon = BIN2BCD(mon);
		yrs = BIN2BCD(yrs);

		spin_lock_irq(&rtc_lock);
		rtc->control |= M48T35_RTC_SET;
		rtc->year = yrs;
		rtc->month = mon;
		rtc->date = day;
		rtc->hour = hrs;
		rtc->min = min;
		rtc->sec = sec;
		rtc->control &= ~M48T35_RTC_SET;
		spin_unlock_irq(&rtc_lock);

		return 0;
	}
	default:
		return -EINVAL;
	}
	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
}
示例#28
0
//------------------------------------------------------------------------------
//
//  Function:  OALIoCtlHalInitRTC
//
//  This function is called by WinCE OS to initialize the time after boot. 
//  Input buffer contains SYSTEMTIME structure with default time value.
//
//
BOOL OALIoCtlHalInitRTC( UINT32 code, 
						 VOID *pInBuffer, 
						 UINT32 inSize, 
						 VOID *pOutBuffer, 
						 UINT32 outSize, 
						 UINT32 *pOutSize
                        )
{
    BOOL            rc = FALSE;
    SYSTEMTIME      *pGivenTime = (LPSYSTEMTIME) pInBuffer;
    UCHAR           bcdTime[6];
    UCHAR           status;
    UCHAR           secure;

    UNREFERENCED_PARAMETER(pOutSize);
    UNREFERENCED_PARAMETER(outSize);
    UNREFERENCED_PARAMETER(pOutBuffer);
    UNREFERENCED_PARAMETER(inSize);
    UNREFERENCED_PARAMETER(code);

    OALMSG(OAL_TIMER && OAL_FUNC, (L"+OALIoCtlHalInitRTC()\r\n"));

   
    // Initialize RTC critical section
    InitializeCriticalSection(&s_rtc.cs);

    // Set CPU GPIO_64 (T2 MSECURE) to be output/high (unsecure)
    // This allows write access to the T2 RTC calendar/time registers
    // OMAP35XX GP only
    if( dwOEMHighSecurity == OEM_HIGH_SECURITY_GP )
    {
        BSPSetT2MSECURE(TRUE);
    }

    // First read RTC status from Triton 
    s_rtc.hTWL = TWLOpen();
    if (s_rtc.hTWL == NULL)
	{
        OALMSG(OAL_ERROR, (L" OALIoCtlHalInitRTC(): Failed to open Triton\r\n"));
        goto cleanUp;
	}

    // Read secure registers for secure hash
    status = 0;

    TWLReadByteReg(s_rtc.hTWL, TWL_SECURED_REG_A, &secure);
    status |= secure;

    TWLReadByteReg(s_rtc.hTWL, TWL_SECURED_REG_B, &secure);
    status |= secure;

    TWLReadByteReg(s_rtc.hTWL, TWL_SECURED_REG_C, &secure);
    status |= secure;

    TWLReadByteReg(s_rtc.hTWL, TWL_SECURED_REG_D, &secure);
    status |= secure;


    OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC():  RTC TWL_SECURED_REG_= 0x%x\r\n", status));

#if 1 // brian
    // Not needed for CE embedded, only need to reset RTC if TWL/TPS PMIC is reset
    // Check for a clean boot of device - if so, reset date/time to system default (LTK2026)
    //pColdBoot = OALArgsQuery(OAL_ARGS_QUERY_COLDBOOT);
    //if ((pColdBoot != NULL) && *pColdBoot)
    //    {
	OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC():  Clean boot, reset date time\r\n"));
	status = 0;
    //    }
#endif
		
    // Start RTC when it isn't running
    if (status == 0 && pGivenTime != NULL)
	{
        OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC():  Resetting RTC\r\n"));

        // Write power_up and alarm bits to clear power up flag (and any interrupt flag)
        TWLWriteByteReg(s_rtc.hTWL, TWL_RTC_STATUS_REG, TWL_RTC_STATUS_POWER_UP|TWL_RTC_STATUS_ALARM);

        //  Convert system time to BCD
        bcdTime[5] = BIN2BCD(pGivenTime->wYear - RTC_BASE_YEAR_MIN);
        bcdTime[4] = BIN2BCD(pGivenTime->wMonth);
        bcdTime[3] = BIN2BCD(pGivenTime->wDay);
        bcdTime[2] = BIN2BCD(pGivenTime->wHour);
        bcdTime[1] = BIN2BCD(pGivenTime->wMinute);
        bcdTime[0] = BIN2BCD(pGivenTime->wSecond);

        //  Initialize RTC with given values
        TWLWriteByteReg(s_rtc.hTWL, TWL_YEARS_REG,  bcdTime[5]);
        TWLWriteByteReg(s_rtc.hTWL, TWL_MONTHS_REG, bcdTime[4]);
        TWLWriteByteReg(s_rtc.hTWL, TWL_DAYS_REG,   bcdTime[3]);
        TWLWriteByteReg(s_rtc.hTWL, TWL_HOURS_REG,  bcdTime[2]);
        TWLWriteByteReg(s_rtc.hTWL, TWL_MINUTES_REG, bcdTime[1]);
        TWLWriteByteReg(s_rtc.hTWL, TWL_SECONDS_REG, bcdTime[0]);

        //  Enable RTC
        TWLWriteByteReg(s_rtc.hTWL, TWL_RTC_CTRL_REG, TWL_RTC_CTRL_RUN);

        //  Write fake hash to secure regs
        TWLWriteByteReg(s_rtc.hTWL, TWL_SECURED_REG_A, 0xAA);
        TWLWriteByteReg(s_rtc.hTWL, TWL_SECURED_REG_B, 0xBB);
        TWLWriteByteReg(s_rtc.hTWL, TWL_SECURED_REG_C, 0xCC);
        TWLWriteByteReg(s_rtc.hTWL, TWL_SECURED_REG_D, 0xDD);

        //  Convert given time initialization date/time to FILETIME
        NKSystemTimeToFileTime(pGivenTime, (FILETIME*)&s_rtc.baseFiletime);

        //  Set a default value for base offset
        s_rtc.baseOffset = 0;

        //  Save off base offset to the backup regs
        WriteBaseOffset( &s_rtc.baseOffset ); 
	}
    else
	{
        SYSTEMTIME  baseSystemTime;

        OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC():  Getting RTC\r\n"));

        //  Set get time flag            
        TWLReadByteReg(s_rtc.hTWL, TWL_RTC_CTRL_REG, &status);

        status |= TWL_RTC_CTRL_RUN | TWL_RTC_CTRL_GET_TIME;
        TWLWriteByteReg(s_rtc.hTWL, TWL_RTC_CTRL_REG, status);

        //  Get date and time from RTC
        TWLReadByteReg(s_rtc.hTWL, TWL_YEARS_REG, &bcdTime[5]);
        TWLReadByteReg(s_rtc.hTWL, TWL_MONTHS_REG, &bcdTime[4]);
        TWLReadByteReg(s_rtc.hTWL, TWL_DAYS_REG, &bcdTime[3]);
        TWLReadByteReg(s_rtc.hTWL, TWL_HOURS_REG, &bcdTime[2]);
        TWLReadByteReg(s_rtc.hTWL, TWL_MINUTES_REG, &bcdTime[1]);
        TWLReadByteReg(s_rtc.hTWL, TWL_SECONDS_REG, &bcdTime[0]);

        //  Convert current RTC date/time to FILETIME
        baseSystemTime.wYear    = BCD2BIN(bcdTime[5]) + RTC_BASE_YEAR_MIN;
        baseSystemTime.wMonth   = BCD2BIN(bcdTime[4]);
        baseSystemTime.wDay     = BCD2BIN(bcdTime[3]);
        baseSystemTime.wHour    = BCD2BIN(bcdTime[2]);
        baseSystemTime.wMinute  = BCD2BIN(bcdTime[1]);
        baseSystemTime.wSecond  = BCD2BIN(bcdTime[0]);
        baseSystemTime.wMilliseconds = 0;

        NKSystemTimeToFileTime(&baseSystemTime, (FILETIME*)&s_rtc.baseFiletime);

        //  Read the offset from the backup regs
        ReadBaseOffset( &s_rtc.baseOffset ); 
	}        


    OALMSG(OAL_TIMER && OAL_FUNC, (L" OALIoCtlHalInitRTC():  RTC = %s\r\n", HWTimeToString(bcdTime)));


    // Now update RTC state values
    s_rtc.initialized   = TRUE;
    s_rtc.baseTickCount = OEMGetTickCount();


    //  Success
    rc = TRUE;


cleanUp:
    OALMSG(OAL_TIMER && OAL_FUNC, (L"-OALIoCtlHalInitRTC() rc = %d\r\n", rc));
    return rc;
}
示例#29
0
文件: rtc-x1205.c 项目: 274914765/C
static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
            int datetoo, u8 reg_base, unsigned char alm_enable)
{
    int i, xfer, nbytes;
    unsigned char buf[8];
    unsigned char rdata[10] = { 0, reg_base };

    static const unsigned char wel[3] = { 0, X1205_REG_SR,
                        X1205_SR_WEL };

    static const unsigned char rwel[3] = { 0, X1205_REG_SR,
                        X1205_SR_WEL | X1205_SR_RWEL };

    static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };

    dev_dbg(&client->dev,
        "%s: secs=%d, mins=%d, hours=%d\n",
        __func__,
        tm->tm_sec, tm->tm_min, tm->tm_hour);

    buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
    buf[CCR_MIN] = BIN2BCD(tm->tm_min);

    /* set hour and 24hr bit */
    buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL;

    /* should we also set the date? */
    if (datetoo) {
        dev_dbg(&client->dev,
            "%s: mday=%d, mon=%d, year=%d, wday=%d\n",
            __func__,
            tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);

        buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);

        /* month, 1 - 12 */
        buf[CCR_MONTH] = BIN2BCD(tm->tm_mon + 1);

        /* year, since the rtc epoch*/
        buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100);
        buf[CCR_WDAY] = tm->tm_wday & 0x07;
        buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100);
    }

    /* If writing alarm registers, set compare bits on registers 0-4 */
    if (reg_base < X1205_CCR_BASE)
        for (i = 0; i <= 4; i++)
            buf[i] |= 0x80;

    /* this sequence is required to unlock the chip */
    if ((xfer = i2c_master_send(client, wel, 3)) != 3) {
        dev_err(&client->dev, "%s: wel - %d\n", __func__, xfer);
        return -EIO;
    }

    if ((xfer = i2c_master_send(client, rwel, 3)) != 3) {
        dev_err(&client->dev, "%s: rwel - %d\n", __func__, xfer);
        return -EIO;
    }


    /* write register's data */
    if (datetoo)
        nbytes = 8;
    else
        nbytes = 3;
    for (i = 0; i < nbytes; i++)
        rdata[2+i] = buf[i];

    xfer = i2c_master_send(client, rdata, nbytes+2);
    if (xfer != nbytes+2) {
        dev_err(&client->dev,
            "%s: result=%d addr=%02x, data=%02x\n",
            __func__,
             xfer, rdata[1], rdata[2]);
        return -EIO;
    }

    /* If we wrote to the nonvolatile region, wait 10msec for write cycle*/
    if (reg_base < X1205_CCR_BASE) {
        unsigned char al0e[3] = { 0, X1205_REG_INT, 0 };

        msleep(10);

        /* ...and set or clear the AL0E bit in the INT register */

        /* Need to set RWEL again as the write has cleared it */
        xfer = i2c_master_send(client, rwel, 3);
        if (xfer != 3) {
            dev_err(&client->dev,
                "%s: aloe rwel - %d\n",
                __func__,
                xfer);
            return -EIO;
        }

        if (alm_enable)
            al0e[2] = X1205_INT_AL0E;

        xfer = i2c_master_send(client, al0e, 3);
        if (xfer != 3) {
            dev_err(&client->dev,
                "%s: al0e - %d\n",
                __func__,
                xfer);
            return -EIO;
        }

        /* and wait 10msec again for this write to complete */
        msleep(10);
    }

    /* disable further writes */
    if ((xfer = i2c_master_send(client, diswe, 3)) != 3) {
        dev_err(&client->dev, "%s: diswe - %d\n", __func__, xfer);
        return -EIO;
    }

    return 0;
}
示例#30
0
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		     unsigned long arg)
{
	struct rtc_time wtime; 
	struct upd4990a_raw_data raw;

	switch (cmd) {
	case RTC_UIE_OFF:	/* Mask ints from RTC updates.	*/
		spin_lock_irq(&rtc_lock);
		if (rtc_status & RTC_UIE_TIMER_ON) {
			rtc_status &= ~RTC_UIE_TIMER_ON;
			del_timer(&rtc_uie_timer);
		}
		spin_unlock_irq(&rtc_lock);
		return 0;

	case RTC_UIE_ON:	/* Allow ints for RTC updates.	*/
		spin_lock_irq(&rtc_lock);
		rtc_irq_data = 0;
		if (!(rtc_status & RTC_UIE_TIMER_ON)) {
			rtc_status |= RTC_UIE_TIMER_ON;
			rtc_uie_timer.expires = jiffies + 1;
			add_timer(&rtc_uie_timer);
		}
		/* Just in case... */
		upd4990a_serial_command(UPD4990A_REGISTER_HOLD);
		old_refclk = ~UPD4990A_READ_DATA();
		spin_unlock_irq(&rtc_lock);
		return 0;

	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
		spin_lock_irq(&rtc_lock);
		upd4990a_get_time(&raw, 0);
		spin_unlock_irq(&rtc_lock);

		wtime.tm_sec	= BCD2BIN(raw.sec);
		wtime.tm_min	= BCD2BIN(raw.min);
		wtime.tm_hour	= BCD2BIN(raw.hour);
		wtime.tm_mday	= BCD2BIN(raw.mday);
		wtime.tm_mon	= raw.mon - 1; /* convert to 0-base */
		wtime.tm_wday	= raw.wday;

		/*
		 * Account for differences between how the RTC uses the values
		 * and how they are defined in a struct rtc_time;
		 */
		if ((wtime.tm_year = BCD2BIN(raw.year)) < 95)
			wtime.tm_year += 100;

		wtime.tm_isdst = 0;
		break;

	case RTC_SET_TIME:	/* Set the RTC */
	{
		int leap_yr;

		if (!capable(CAP_SYS_TIME))
			return -EACCES;

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

		/* Valid year is 1995 - 2094, inclusive.  */
		if (wtime.tm_year < 95 || wtime.tm_year > 194)
			return -EINVAL;

		if (wtime.tm_mon > 11 || wtime.tm_mday == 0)
			return -EINVAL;

		/* For acceptable year domain (1995 - 2094),
		   this IS sufficient.  */
		leap_yr = !(wtime.tm_year % 4);

		if (wtime.tm_mday > (days_in_mo[wtime.tm_mon]
				     + (wtime.tm_mon == 2 && leap_yr)))
			return -EINVAL;
			
		if (wtime.tm_hour >= 24
		    || wtime.tm_min >= 60 || wtime.tm_sec >= 60)
			return -EINVAL;

		if (wtime.tm_wday > 6)
			return -EINVAL;

		raw.sec  = BIN2BCD(wtime.tm_sec);
		raw.min  = BIN2BCD(wtime.tm_min);
		raw.hour = BIN2BCD(wtime.tm_hour);
		raw.mday = BIN2BCD(wtime.tm_mday);
		raw.mon  = wtime.tm_mon + 1;
		raw.wday = wtime.tm_wday;
		raw.year = BIN2BCD(wtime.tm_year % 100);

		spin_lock_irq(&rtc_lock);
		upd4990a_set_time(&raw, 0);
		spin_unlock_irq(&rtc_lock);

		return 0;
	}
	default:
		return -EINVAL;
	}
	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
}