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;
}