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; }
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, ®s[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); }
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; }
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; }
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; }
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; }