rtc: ds1307: add trickle charger device tree binding
[deliverable/linux.git] / drivers / rtc / rtc-ds1307.c
index f03d5ba96db1fe3f5e063e15957056604896570b..bb43cf703efc590bf40ba62a3de52aeea64d71b4 100644 (file)
@@ -126,9 +126,14 @@ struct chip_desc {
        u16                     nvram_offset;
        u16                     nvram_size;
        u16                     trickle_charger_reg;
+       u8                      trickle_charger_setup;
+       u8                      (*do_trickle_setup)(struct i2c_client *, uint32_t, bool);
 };
 
-static const struct chip_desc chips[last_ds_type] = {
+static u8 do_trickle_setup_ds1339(struct i2c_client *,
+                                 uint32_t ohms, bool diode);
+
+static struct chip_desc chips[last_ds_type] = {
        [ds_1307] = {
                .nvram_offset   = 8,
                .nvram_size     = 56,
@@ -143,6 +148,7 @@ static const struct chip_desc chips[last_ds_type] = {
        [ds_1339] = {
                .alarm          = 1,
                .trickle_charger_reg = 0x10,
+               .do_trickle_setup = &do_trickle_setup_ds1339,
        },
        [ds_1340] = {
                .trickle_charger_reg = 0x08,
@@ -833,15 +839,58 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj,
        return count;
 }
 
+
 /*----------------------------------------------------------------------*/
 
+static u8 do_trickle_setup_ds1339(struct i2c_client *client,
+                                 uint32_t ohms, bool diode)
+{
+       u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE :
+               DS1307_TRICKLE_CHARGER_NO_DIODE;
+
+       switch (ohms) {
+       case 250:
+               setup |= DS1307_TRICKLE_CHARGER_250_OHM;
+               break;
+       case 2000:
+               setup |= DS1307_TRICKLE_CHARGER_2K_OHM;
+               break;
+       case 4000:
+               setup |= DS1307_TRICKLE_CHARGER_4K_OHM;
+               break;
+       default:
+               dev_warn(&client->dev,
+                        "Unsupported ohm value %u in dt\n", ohms);
+               return 0;
+       }
+       return setup;
+}
+
+static void ds1307_trickle_of_init(struct i2c_client *client,
+                                  struct chip_desc *chip)
+{
+       uint32_t ohms = 0;
+       bool diode = true;
+
+       if (!chip->do_trickle_setup)
+               goto out;
+       if (of_property_read_u32(client->dev.of_node, "trickle-resistor-ohms" , &ohms))
+               goto out;
+       if (of_property_read_bool(client->dev.of_node, "trickle-diode-disable"))
+               diode = false;
+       chip->trickle_charger_setup = chip->do_trickle_setup(client,
+                                                            ohms, diode);
+out:
+       return;
+}
+
 static int ds1307_probe(struct i2c_client *client,
                        const struct i2c_device_id *id)
 {
        struct ds1307           *ds1307;
        int                     err = -ENODEV;
        int                     tmp;
-       const struct chip_desc  *chip = &chips[id->driver_data];
+       struct chip_desc        *chip = &chips[id->driver_data];
        struct i2c_adapter      *adapter = to_i2c_adapter(client->dev.parent);
        bool                    want_irq = false;
        unsigned char           *buf;
@@ -866,9 +915,19 @@ static int ds1307_probe(struct i2c_client *client,
        ds1307->client  = client;
        ds1307->type    = id->driver_data;
 
-       if (pdata && pdata->trickle_charger_setup && chip->trickle_charger_reg)
+       if (!pdata && client->dev.of_node)
+               ds1307_trickle_of_init(client, chip);
+       else if (pdata && pdata->trickle_charger_setup)
+               chip->trickle_charger_setup = pdata->trickle_charger_setup;
+
+       if (chip->trickle_charger_setup && chip->trickle_charger_reg) {
+               dev_dbg(&client->dev, "writing trickle charger info 0x%x to 0x%x\n",
+                   DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup,
+                   chip->trickle_charger_reg);
                i2c_smbus_write_byte_data(client, chip->trickle_charger_reg,
-                       DS13XX_TRICKLE_CHARGER_MAGIC | pdata->trickle_charger_setup);
+                   DS13XX_TRICKLE_CHARGER_MAGIC |
+                   chip->trickle_charger_setup);
+       }
 
        buf = ds1307->regs;
        if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
This page took 0.027047 seconds and 5 git commands to generate.