rtc: ds1390: Add trickle charger device tree binding

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

Signed-off-by: Ivan Grimaldi <grimaldi.ivan@gmail.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
This commit is contained in:
Ivan Grimaldi 2015-09-18 17:27:57 +02:00 committed by Alexandre Belloni
parent 2ec68825fc
commit fa395fb8fc
3 changed files with 83 additions and 2 deletions

View File

@ -0,0 +1,18 @@
* 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>;
};

View File

@ -666,8 +666,8 @@ config RTC_DRV_DS1390
If you say yes here you get support for the If you say yes here you get support for the
Dallas/Maxim DS1390/93/94 chips. Dallas/Maxim DS1390/93/94 chips.
This driver only supports the RTC feature, and not other chip This driver supports the RTC feature and trickle charging but not
features such as alarms and trickle charging. other chip features such as alarms.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called rtc-ds1390. will be called rtc-ds1390.

View File

@ -20,6 +20,7 @@
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of.h>
#define DS1390_REG_100THS 0x00 #define DS1390_REG_100THS 0x00
#define DS1390_REG_SECONDS 0x01 #define DS1390_REG_SECONDS 0x01
@ -40,11 +41,31 @@
#define DS1390_REG_STATUS 0x0E #define DS1390_REG_STATUS 0x0E
#define DS1390_REG_TRICKLE 0x0F #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 ds1390 {
struct rtc_device *rtc; struct rtc_device *rtc;
u8 txrx_buf[9]; /* cmd + 8 registers */ 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, static int ds1390_get_reg(struct device *dev, unsigned char address,
unsigned char *data) unsigned char *data)
{ {
@ -67,6 +88,45 @@ static int ds1390_get_reg(struct device *dev, unsigned char address,
return 0; 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) static int ds1390_read_time(struct device *dev, struct rtc_time *dt)
{ {
struct spi_device *spi = to_spi_device(dev); struct spi_device *spi = to_spi_device(dev);
@ -143,6 +203,9 @@ static int ds1390_probe(struct spi_device *spi)
return res; return res;
} }
if (spi->dev.of_node)
ds1390_trickle_of_init(spi);
chip->rtc = devm_rtc_device_register(&spi->dev, "ds1390", chip->rtc = devm_rtc_device_register(&spi->dev, "ds1390",
&ds1390_rtc_ops, THIS_MODULE); &ds1390_rtc_ops, THIS_MODULE);
if (IS_ERR(chip->rtc)) { if (IS_ERR(chip->rtc)) {