|
|
@@ -85,6 +85,18 @@ static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int pcf8523_voltage_low(struct i2c_client *client)
|
|
|
+{
|
|
|
+ u8 value;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ err = pcf8523_read(client, REG_CONTROL3, &value);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ return !!(value & REG_CONTROL3_BLF);
|
|
|
+}
|
|
|
+
|
|
|
static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
|
|
|
{
|
|
|
u8 value;
|
|
|
@@ -167,6 +179,14 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
|
|
struct i2c_msg msgs[2];
|
|
|
int err;
|
|
|
|
|
|
+ err = pcf8523_voltage_low(client);
|
|
|
+ if (err < 0) {
|
|
|
+ return err;
|
|
|
+ } else if (err > 0) {
|
|
|
+ dev_err(dev, "low voltage detected, time is unreliable\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
msgs[0].addr = client->addr;
|
|
|
msgs[0].flags = 0;
|
|
|
msgs[0].len = 1;
|
|
|
@@ -251,17 +271,13 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
|
|
|
unsigned long arg)
|
|
|
{
|
|
|
struct i2c_client *client = to_i2c_client(dev);
|
|
|
- u8 value;
|
|
|
- int ret = 0, err;
|
|
|
+ int ret;
|
|
|
|
|
|
switch (cmd) {
|
|
|
case RTC_VL_READ:
|
|
|
- err = pcf8523_read(client, REG_CONTROL3, &value);
|
|
|
- if (err < 0)
|
|
|
- return err;
|
|
|
-
|
|
|
- if (value & REG_CONTROL3_BLF)
|
|
|
- ret = 1;
|
|
|
+ ret = pcf8523_voltage_low(client);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
|
|
|
if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
|
|
|
return -EFAULT;
|