summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksij Rempel <fixed-term.Oleksij.Rempel@de.bosch.com>2016-06-29 17:40:01 +0300
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2016-10-12 14:24:39 +0300
commit1cd713762e4cd5378a488fd6eaa7507bf030a832 (patch)
tree56b4ad591010c88ddf7ce2e82933b73dd0528491
parenteff6675b5cc191308c0144dcd5dd2b49257e83d7 (diff)
downloadlinux-1cd713762e4cd5378a488fd6eaa7507bf030a832.tar.xz
rtc: rv8803: set VDETOFF and SWOFF via device tree
There might be designs where the power supply circuit is designed in a way that VDETOFF and SWOFF is required to be set. Otherwise the RTC detects a power loss. Add a device tree interface for this. Signed-off-by: Carsten Resch <Carsten.Resch@de.bosch.com> Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com> Signed-off-by: Oleksij Rempel <fixed-term.Oleksij.Rempel@de.bosch.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
-rw-r--r--drivers/rtc/rtc-rv8803.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c
index 9a2f6a95d5a7..f9277e536f7e 100644
--- a/drivers/rtc/rtc-rv8803.c
+++ b/drivers/rtc/rtc-rv8803.c
@@ -52,11 +52,21 @@
#define RV8803_CTRL_TIE BIT(4)
#define RV8803_CTRL_UIE BIT(5)
+#define RX8900_BACKUP_CTRL 0x18
+#define RX8900_FLAG_SWOFF BIT(2)
+#define RX8900_FLAG_VDETOFF BIT(3)
+
+enum rv8803_type {
+ rv_8803,
+ rx_8900
+};
+
struct rv8803_data {
struct i2c_client *client;
struct rtc_device *rtc;
struct mutex flags_lock;
u8 ctrl;
+ enum rv8803_type type;
};
static int rv8803_read_reg(const struct i2c_client *client, u8 reg)
@@ -497,6 +507,35 @@ static struct rtc_class_ops rv8803_rtc_ops = {
.ioctl = rv8803_ioctl,
};
+static int rx8900_trickle_charger_init(struct rv8803_data *rv8803)
+{
+ struct i2c_client *client = rv8803->client;
+ struct device_node *node = client->dev.of_node;
+ int err;
+ u8 flags;
+
+ if (!node)
+ return 0;
+
+ if (rv8803->type != rx_8900)
+ return 0;
+
+ err = i2c_smbus_read_byte_data(rv8803->client, RX8900_BACKUP_CTRL);
+ if (err < 0)
+ return err;
+
+ flags = ~(RX8900_FLAG_VDETOFF | RX8900_FLAG_SWOFF) & (u8)err;
+
+ if (of_property_read_bool(node, "epson,vdet-disable"))
+ flags |= RX8900_FLAG_VDETOFF;
+
+ if (of_property_read_bool(node, "trickle-diode-disable"))
+ flags |= RX8900_FLAG_SWOFF;
+
+ return i2c_smbus_write_byte_data(rv8803->client, RX8900_BACKUP_CTRL,
+ flags);
+}
+
static int rv8803_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -517,6 +556,7 @@ static int rv8803_probe(struct i2c_client *client,
mutex_init(&rv8803->flags_lock);
rv8803->client = client;
+ rv8803->type = id->driver_data;
i2c_set_clientdata(client, rv8803);
flags = rv8803_read_reg(client, RV8803_FLAG);
@@ -558,6 +598,12 @@ static int rv8803_probe(struct i2c_client *client,
if (err)
return err;
+ err = rx8900_trickle_charger_init(rv8803);
+ if (err) {
+ dev_err(&client->dev, "failed to init charger\n");
+ return err;
+ }
+
err = device_create_bin_file(&client->dev, &rv8803_nvram_attr);
if (err)
return err;
@@ -575,8 +621,8 @@ static int rv8803_remove(struct i2c_client *client)
}
static const struct i2c_device_id rv8803_id[] = {
- { "rv8803", 0 },
- { "rx8900", 0 },
+ { "rv8803", rv_8803 },
+ { "rx8900", rx_8900 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rv8803_id);