rtc: ds1390: Add trickle charger device tree binding
authorIvan Grimaldi <grimaldi.ivan@gmail.com>
Fri, 18 Sep 2015 15:27:57 +0000 (17:27 +0200)
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>
Sun, 8 Nov 2015 13:12:23 +0000 (14:12 +0100)
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>
Documentation/devicetree/bindings/rtc/dallas,ds1390.txt [new file with mode: 0644]
drivers/rtc/Kconfig
drivers/rtc/rtc-ds1390.c

diff --git a/Documentation/devicetree/bindings/rtc/dallas,ds1390.txt b/Documentation/devicetree/bindings/rtc/dallas,ds1390.txt
new file mode 100644 (file)
index 0000000..8e76f26
--- /dev/null
@@ -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>;
+       };
index 9d4290617cee5ab2969999ddb098db46b30f8e9d..57c2dbc4f438a9c18b32df68bece3fa467c374e6 100644 (file)
@@ -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.
index a4303b43a36acae5bf2226e9445bba1113193ba8..b2b9454aa7a2554b1c66326b9e7b65caed9bcdb2 100644 (file)
@@ -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
 #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)) {