From 33b04b7b7c03d04584be3f91ebc1eb40eb1ed33c Mon Sep 17 00:00:00 2001 From: Matti Vaittinen Date: Mon, 13 Oct 2014 15:52:48 -0700 Subject: [PATCH] rtc: ds1307: add trickle charger device tree binding Some DS13XX devices have "trickle chargers". Introduce a device tree binding for specifying the trickle charger configuration for ds1339. Only ds1339 dt binding is supported because this is the only chip I have. I _assume_ the code would have worked on other allready supported chips. However I cannot check the resistor values for the other chips or test them. For other chips the driver code works as earlier Eg. it does not check the dt bindings at all Signed-off-by: Matti Vaittinen Cc: Rob Herring Cc: Pawel Moll Cc: Jason Cooper Cc: Guenter Roeck Cc: Alessandro Zummo Cc: Mark Rutland Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 67 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index f03d5ba96db1..bb43cf703efc 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -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)) { -- 2.30.2