Commit fa395fb8 authored by Ivan Grimaldi's avatar Ivan Grimaldi Committed by Alexandre Belloni
Browse files

rtc: ds1390: Add trickle charger device tree binding



Introduce a device tree binding for specifying the trickle charger
configuration for ds1390.

Signed-off-by: default avatarIvan Grimaldi <grimaldi.ivan@gmail.com>
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@free-electrons.com>
parent 2ec68825
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
* Dallas DS1390		SPI Serial Real-Time Clock

Required properties:
- compatible: Should contain "dallas,ds1390".
- reg: SPI address for chip

Optional properties:
- trickle-resistor-ohms : Selected resistor for trickle charger
	Values usable for ds1390 are 250, 2000, 4000
	Should be given if trickle charger should be enabled
- trickle-diode-disable : Do not use internal trickle charger diode
	Should be given if internal trickle charger diode should be disabled
Example:
	ds1390: rtc@68 {
		compatible = "dallas,ds1390";
		trickle-resistor-ohms = <250>;
		reg = <0>;
	};
+2 −2
Original line number Diff line number Diff line
@@ -666,8 +666,8 @@ config RTC_DRV_DS1390
	  If you say yes here you get support for the
	  Dallas/Maxim DS1390/93/94 chips.

	  This driver only supports the RTC feature, and not other chip
	  features such as alarms and trickle charging.
	  This driver supports the RTC feature and trickle charging but not
	  other chip features such as alarms.

	  This driver can also be built as a module. If so, the module
	  will be called rtc-ds1390.
+63 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/spi/spi.h>
#include <linux/bcd.h>
#include <linux/slab.h>
#include <linux/of.h>

#define DS1390_REG_100THS		0x00
#define DS1390_REG_SECONDS		0x01
@@ -40,11 +41,31 @@
#define DS1390_REG_STATUS		0x0E
#define DS1390_REG_TRICKLE		0x0F

#define DS1390_TRICKLE_CHARGER_ENABLE	0xA0
#define DS1390_TRICKLE_CHARGER_250_OHM	0x01
#define DS1390_TRICKLE_CHARGER_2K_OHM	0x02
#define DS1390_TRICKLE_CHARGER_4K_OHM	0x03
#define DS1390_TRICKLE_CHARGER_NO_DIODE	0x04
#define DS1390_TRICKLE_CHARGER_DIODE	0x08

struct ds1390 {
	struct rtc_device *rtc;
	u8 txrx_buf[9];	/* cmd + 8 registers */
};

static void ds1390_set_reg(struct device *dev, unsigned char address,
			   unsigned char data)
{
	struct spi_device *spi = to_spi_device(dev);
	unsigned char buf[2];

	/* MSB must be '1' to write */
	buf[0] = address | 0x80;
	buf[1] = data;

	spi_write(spi, buf, 2);
}

static int ds1390_get_reg(struct device *dev, unsigned char address,
				unsigned char *data)
{
@@ -67,6 +88,45 @@ static int ds1390_get_reg(struct device *dev, unsigned char address,
	return 0;
}

static void ds1390_trickle_of_init(struct spi_device *spi)
{
	u32 ohms = 0;
	u8 value;

	if (of_property_read_u32(spi->dev.of_node, "trickle-resistor-ohms",
				 &ohms))
		goto out;

	/* Enable charger */
	value = DS1390_TRICKLE_CHARGER_ENABLE;
	if (of_property_read_bool(spi->dev.of_node, "trickle-diode-disable"))
		value |= DS1390_TRICKLE_CHARGER_NO_DIODE;
	else
		value |= DS1390_TRICKLE_CHARGER_DIODE;

	/* Resistor select */
	switch (ohms) {
	case 250:
		value |= DS1390_TRICKLE_CHARGER_250_OHM;
		break;
	case 2000:
		value |= DS1390_TRICKLE_CHARGER_2K_OHM;
		break;
	case 4000:
		value |= DS1390_TRICKLE_CHARGER_4K_OHM;
		break;
	default:
		dev_warn(&spi->dev,
			 "Unsupported ohm value %02ux in dt\n", ohms);
		return;
	}

	ds1390_set_reg(&spi->dev, DS1390_REG_TRICKLE, value);

out:
	return;
}

static int ds1390_read_time(struct device *dev, struct rtc_time *dt)
{
	struct spi_device *spi = to_spi_device(dev);
@@ -143,6 +203,9 @@ static int ds1390_probe(struct spi_device *spi)
		return res;
	}

	if (spi->dev.of_node)
		ds1390_trickle_of_init(spi);

	chip->rtc = devm_rtc_device_register(&spi->dev, "ds1390",
					&ds1390_rtc_ops, THIS_MODULE);
	if (IS_ERR(chip->rtc)) {