static int x1205_set_datetime()

in rtc-x1205.c [172:277]


static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
			u8 reg_base, unsigned char alm_enable)
{
	int i, xfer;
	unsigned char rdata[10] = { 0, reg_base };
	unsigned char *buf = rdata + 2;

	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: sec=%d min=%d hour=%d mday=%d mon=%d year=%d wday=%d\n",
		__func__, tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday,
		tm->tm_mon, tm->tm_year, tm->tm_wday);

	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 + 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 + 1900) / 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 */
	xfer = i2c_master_send(client, wel, 3);
	if (xfer != 3) {
		dev_err(&client->dev, "%s: wel - %d\n", __func__, xfer);
		return -EIO;
	}

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

	xfer = i2c_master_send(client, rdata, sizeof(rdata));
	if (xfer != sizeof(rdata)) {
		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 */
	xfer = i2c_master_send(client, diswe, 3);
	if (xfer != 3) {
		dev_err(&client->dev, "%s: diswe - %d\n", __func__, xfer);
		return -EIO;
	}

	return 0;
}