diff options
author | Marek Vasut <marex@denx.de> | 2018-12-07 18:40:53 +0100 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2018-12-18 22:53:27 +0100 |
commit | ffe1c5a2d4271a0e04e2576ab0a53ac09a14e065 (patch) | |
tree | b052907a8e934b0670ef753cca5b8aeb22810c33 /drivers/rtc/rtc-abx80x.c | |
parent | fc979933bcf162595b6004d0de4effb64c323152 (diff) | |
download | lwn-ffe1c5a2d4271a0e04e2576ab0a53ac09a14e065.tar.gz lwn-ffe1c5a2d4271a0e04e2576ab0a53ac09a14e065.zip |
rtc: abx80x: Implement RTC_VL_READ,CLR ioctls
Implement standard ioctls for polling the battery status and clearing
the battery low indication from userspace.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Diffstat (limited to 'drivers/rtc/rtc-abx80x.c')
-rw-r--r-- | drivers/rtc/rtc-abx80x.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index d8e94edcb0ba..4d24f7288ad7 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -38,6 +38,7 @@ #define ABX8XX_REG_STATUS 0x0f #define ABX8XX_STATUS_AF BIT(2) +#define ABX8XX_STATUS_BLF BIT(4) #define ABX8XX_STATUS_WDT BIT(6) #define ABX8XX_REG_CTRL1 0x10 @@ -507,12 +508,49 @@ static int abx80x_alarm_irq_enable(struct device *dev, unsigned int enabled) return err; } +static int abx80x_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ + struct i2c_client *client = to_i2c_client(dev); + int status, tmp; + + switch (cmd) { + case RTC_VL_READ: + status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS); + if (status < 0) + return status; + + tmp = !!(status & ABX8XX_STATUS_BLF); + + if (copy_to_user((void __user *)arg, &tmp, sizeof(int))) + return -EFAULT; + + return 0; + + case RTC_VL_CLR: + status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS); + if (status < 0) + return status; + + status &= ~ABX8XX_STATUS_BLF; + + tmp = i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0); + if (tmp < 0) + return tmp; + + return 0; + + default: + return -ENOIOCTLCMD; + } +} + static const struct rtc_class_ops abx80x_rtc_ops = { .read_time = abx80x_rtc_read_time, .set_time = abx80x_rtc_set_time, .read_alarm = abx80x_read_alarm, .set_alarm = abx80x_set_alarm, .alarm_irq_enable = abx80x_alarm_irq_enable, + .ioctl = abx80x_ioctl, }; static int abx80x_dt_trickle_cfg(struct device_node *np) |