Commit 0f20b767 authored by Alexander Stein's avatar Alexander Stein Committed by Linus Torvalds

drivers/rtc/rtc-pcf8563.c: add RTC_VL_READ/RTC_VL_CLR ioctl feature

Changes are based on arch/cris/arch-v10/drivers/pcf8563.c

[akpm@linux-foundation.org: fix sparse warning]
Signed-off-by: default avatarAlexander Stein <alexander.stein@systec-electronic.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Mikael Starvik <starvik@axis.com>
Acked-by: default avatarJesper Nilsson <jesper.nilsson@axis.com>
Cc: Wu Fengguang <wfg@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent e311c929
...@@ -64,6 +64,7 @@ struct pcf8563 { ...@@ -64,6 +64,7 @@ struct pcf8563 {
* 1970...2069. * 1970...2069.
*/ */
int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
int voltage_low; /* incicates if a low_voltage was detected */
}; };
/* /*
...@@ -86,9 +87,11 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) ...@@ -86,9 +87,11 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
return -EIO; return -EIO;
} }
if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) {
pcf8563->voltage_low = 1;
dev_info(&client->dev, dev_info(&client->dev,
"low voltage detected, date/time is not reliable.\n"); "low voltage detected, date/time is not reliable.\n");
}
dev_dbg(&client->dev, dev_dbg(&client->dev,
"%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, " "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, "
...@@ -173,6 +176,44 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) ...@@ -173,6 +176,44 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
return 0; return 0;
} }
#ifdef CONFIG_RTC_INTF_DEV
static int pcf8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct pcf8563 *pcf8563 = i2c_get_clientdata(to_i2c_client(dev));
struct rtc_time tm;
switch (cmd) {
case RTC_VL_READ:
if (pcf8563->voltage_low)
dev_info(dev, "low voltage detected, date/time is not reliable.\n");
if (copy_to_user((void __user *)arg, &pcf8563->voltage_low,
sizeof(int)))
return -EFAULT;
return 0;
case RTC_VL_CLR:
/*
* Clear the VL bit in the seconds register in case
* the time has not been set already (which would
* have cleared it). This does not really matter
* because of the cached voltage_low value but do it
* anyway for consistency.
*/
if (pcf8563_get_datetime(to_i2c_client(dev), &tm))
pcf8563_set_datetime(to_i2c_client(dev), &tm);
/* Clear the cached value. */
pcf8563->voltage_low = 0;
return 0;
default:
return -ENOIOCTLCMD;
}
}
#else
#define pcf8563_rtc_ioctl NULL
#endif
static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ {
return pcf8563_get_datetime(to_i2c_client(dev), tm); return pcf8563_get_datetime(to_i2c_client(dev), tm);
...@@ -184,6 +225,7 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -184,6 +225,7 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
} }
static const struct rtc_class_ops pcf8563_rtc_ops = { static const struct rtc_class_ops pcf8563_rtc_ops = {
.ioctl = pcf8563_rtc_ioctl,
.read_time = pcf8563_rtc_read_time, .read_time = pcf8563_rtc_read_time,
.set_time = pcf8563_rtc_set_time, .set_time = pcf8563_rtc_set_time,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment