예제 #1
0
static int pcf8523_rtc_check_oscillator(struct i2c_client *client)
{
	u8 value;
	int err;

	err = pcf8523_read(client, REG_SECONDS, &value);
	if (err < 0)
		return err;

	if (value & REG_SECONDS_OS) {
		/*
		 * If the oscillator was stopped, try to clear the flag. Upon
		 * power-up the flag is always set, but if we cannot clear it
		 * the oscillator isn't running properly for some reason. The
		 * sensible thing therefore is to return an error, signalling
		 * that the clock cannot be assumed to be correct.
		 */

		value &= ~REG_SECONDS_OS;

		err = pcf8523_write(client, REG_SECONDS, value);
		if (err < 0)
			return err;

		err = pcf8523_read(client, REG_SECONDS, &value);
		if (err < 0)
			return err;

		if (value & REG_SECONDS_OS)
			return -EAGAIN;
	}

	return 0;
}
예제 #2
0
static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct i2c_client *client = to_i2c_client(dev);
	u8 start = REG_SECONDS, regs[7];
	struct i2c_msg msgs[2];
	int err;

	msgs[0].addr = client->addr;
	msgs[0].flags = 0;
	msgs[0].len = 1;
	msgs[0].buf = &start;

	msgs[1].addr = client->addr;
	msgs[1].flags = I2C_M_RD;
	msgs[1].len = sizeof(regs);
	msgs[1].buf = regs;

	err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
	if (err < 0)
		return err;

	if (regs[0] & REG_SECONDS_OS) {
		/*
		 * If the oscillator was stopped, try to clear the flag. Upon
		 * power-up the flag is always set, but if we cannot clear it
		 * the oscillator isn't running properly for some reason. The
		 * sensible thing therefore is to return an error, signalling
		 * that the clock cannot be assumed to be correct.
		 */

		regs[0] &= ~REG_SECONDS_OS;

		err = pcf8523_write(client, REG_SECONDS, regs[0]);
		if (err < 0)
			return err;

		err = pcf8523_read(client, REG_SECONDS, &regs[0]);
		if (err < 0)
			return err;

		if (regs[0] & REG_SECONDS_OS)
			return -EAGAIN;
	}

	tm->tm_sec = bcd2bin(regs[0] & 0x7f);
	tm->tm_min = bcd2bin(regs[1] & 0x7f);
	tm->tm_hour = bcd2bin(regs[2] & 0x3f);
	tm->tm_mday = bcd2bin(regs[3] & 0x3f);
	tm->tm_wday = regs[4] & 0x7;
	tm->tm_mon = bcd2bin(regs[5] & 0x1f);
	tm->tm_year = bcd2bin(regs[6]) + 100;

	return rtc_valid_tm(tm);
}
예제 #3
0
static int pcf8523_switch_capacitance(struct i2c_client *client)
{
	u8 value;
	int err;

	err = pcf8523_read(client, REG_CONTROL1, &value);
	if (err < 0)
		goto out;

	value ^= REG_CONTROL1_CAP_SEL;

	err = pcf8523_write(client, REG_CONTROL1, value);

out:
	return err;
}
예제 #4
0
static int pcf8523_start_rtc(struct i2c_client *client)
{
	u8 value;
	int err;

	err = pcf8523_read(client, REG_CONTROL1, &value);
	if (err < 0)
		return err;

	value &= ~REG_CONTROL1_STOP;

	err = pcf8523_write(client, REG_CONTROL1, value);
	if (err < 0)
		return err;

	return 0;
}
예제 #5
0
static int pcf8523_set_pm(struct i2c_client *client, u8 pm)
{
	u8 value;
	int err;

	err = pcf8523_read(client, REG_CONTROL3, &value);
	if (err < 0)
		return err;

	value = (value & ~REG_CONTROL3_PM_MASK) | pm;

	err = pcf8523_write(client, REG_CONTROL3, value);
	if (err < 0)
		return err;

	return 0;
}
예제 #6
0
static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
{
	u8 value;
	int err;

	err = pcf8523_read(client, REG_CONTROL1, &value);
	if (err < 0)
		return err;

	if (!high)
		value &= ~REG_CONTROL1_CAP_SEL;
	else
		value |= REG_CONTROL1_CAP_SEL;

	err = pcf8523_write(client, REG_CONTROL1, value);
	if (err < 0)
		return err;

	return err;
}