diff options
author | Alexander Stein <alexander.stein@systec-electronic.com> | 2012-05-29 18:07:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-29 19:22:33 -0400 |
commit | 0f20b767e20a800030f51712b699a5c557f2514b (patch) | |
tree | cf918e394e14a3fd85e69494b714bdd65042cce7 /drivers/rtc | |
parent | e311c9295912209dcf8e54de5401f8518112b7f8 (diff) |
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: Alexander Stein <alexander.stein@systec-electronic.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Mikael Starvik <starvik@axis.com>
Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Wu Fengguang <wfg@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-pcf8563.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index bc0677de1996..97a3284bb7c6 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -64,6 +64,7 @@ struct pcf8563 { | |||
64 | * 1970...2069. | 64 | * 1970...2069. |
65 | */ | 65 | */ |
66 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ | 66 | int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ |
67 | int voltage_low; /* incicates if a low_voltage was detected */ | ||
67 | }; | 68 | }; |
68 | 69 | ||
69 | /* | 70 | /* |
@@ -86,9 +87,11 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
86 | return -EIO; | 87 | return -EIO; |
87 | } | 88 | } |
88 | 89 | ||
89 | if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) | 90 | if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) { |
91 | pcf8563->voltage_low = 1; | ||
90 | dev_info(&client->dev, | 92 | dev_info(&client->dev, |
91 | "low voltage detected, date/time is not reliable.\n"); | 93 | "low voltage detected, date/time is not reliable.\n"); |
94 | } | ||
92 | 95 | ||
93 | dev_dbg(&client->dev, | 96 | dev_dbg(&client->dev, |
94 | "%s: raw data is st1=%02x, st2=%02x, sec=%02x, min=%02x, hr=%02x, " | 97 | "%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 | return 0; | 176 | return 0; |
174 | } | 177 | } |
175 | 178 | ||
179 | #ifdef CONFIG_RTC_INTF_DEV | ||
180 | static int pcf8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
181 | { | ||
182 | struct pcf8563 *pcf8563 = i2c_get_clientdata(to_i2c_client(dev)); | ||
183 | struct rtc_time tm; | ||
184 | |||
185 | switch (cmd) { | ||
186 | case RTC_VL_READ: | ||
187 | if (pcf8563->voltage_low) | ||
188 | dev_info(dev, "low voltage detected, date/time is not reliable.\n"); | ||
189 | |||
190 | if (copy_to_user((void __user *)arg, &pcf8563->voltage_low, | ||
191 | sizeof(int))) | ||
192 | return -EFAULT; | ||
193 | return 0; | ||
194 | case RTC_VL_CLR: | ||
195 | /* | ||
196 | * Clear the VL bit in the seconds register in case | ||
197 | * the time has not been set already (which would | ||
198 | * have cleared it). This does not really matter | ||
199 | * because of the cached voltage_low value but do it | ||
200 | * anyway for consistency. | ||
201 | */ | ||
202 | if (pcf8563_get_datetime(to_i2c_client(dev), &tm)) | ||
203 | pcf8563_set_datetime(to_i2c_client(dev), &tm); | ||
204 | |||
205 | /* Clear the cached value. */ | ||
206 | pcf8563->voltage_low = 0; | ||
207 | |||
208 | return 0; | ||
209 | default: | ||
210 | return -ENOIOCTLCMD; | ||
211 | } | ||
212 | } | ||
213 | #else | ||
214 | #define pcf8563_rtc_ioctl NULL | ||
215 | #endif | ||
216 | |||
176 | static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) | 217 | static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm) |
177 | { | 218 | { |
178 | return pcf8563_get_datetime(to_i2c_client(dev), tm); | 219 | 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 | } | 225 | } |
185 | 226 | ||
186 | static const struct rtc_class_ops pcf8563_rtc_ops = { | 227 | static const struct rtc_class_ops pcf8563_rtc_ops = { |
228 | .ioctl = pcf8563_rtc_ioctl, | ||
187 | .read_time = pcf8563_rtc_read_time, | 229 | .read_time = pcf8563_rtc_read_time, |
188 | .set_time = pcf8563_rtc_set_time, | 230 | .set_time = pcf8563_rtc_set_time, |
189 | }; | 231 | }; |