Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1cd71376 authored by Oleksij Rempel's avatar Oleksij Rempel Committed by Alexandre Belloni
Browse files

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: default avatarCarsten Resch <Carsten.Resch@de.bosch.com>
Signed-off-by: default avatarDirk Behme <dirk.behme@de.bosch.com>
Signed-off-by: default avatarOleksij Rempel <fixed-term.Oleksij.Rempel@de.bosch.com>
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@free-electrons.com>
parent eff6675b
Loading
Loading
Loading
Loading
+48 −2
Original line number Diff line number Diff line
@@ -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);