diff options
Diffstat (limited to 'drivers/rtc/rtc-ds1307.c')
| -rw-r--r-- | drivers/rtc/rtc-ds1307.c | 67 |
1 files 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 { | |||
| 126 | u16 nvram_offset; | 126 | u16 nvram_offset; |
| 127 | u16 nvram_size; | 127 | u16 nvram_size; |
| 128 | u16 trickle_charger_reg; | 128 | u16 trickle_charger_reg; |
| 129 | u8 trickle_charger_setup; | ||
| 130 | u8 (*do_trickle_setup)(struct i2c_client *, uint32_t, bool); | ||
| 129 | }; | 131 | }; |
| 130 | 132 | ||
| 131 | static const struct chip_desc chips[last_ds_type] = { | 133 | static u8 do_trickle_setup_ds1339(struct i2c_client *, |
| 134 | uint32_t ohms, bool diode); | ||
| 135 | |||
| 136 | static struct chip_desc chips[last_ds_type] = { | ||
| 132 | [ds_1307] = { | 137 | [ds_1307] = { |
| 133 | .nvram_offset = 8, | 138 | .nvram_offset = 8, |
| 134 | .nvram_size = 56, | 139 | .nvram_size = 56, |
| @@ -143,6 +148,7 @@ static const struct chip_desc chips[last_ds_type] = { | |||
| 143 | [ds_1339] = { | 148 | [ds_1339] = { |
| 144 | .alarm = 1, | 149 | .alarm = 1, |
| 145 | .trickle_charger_reg = 0x10, | 150 | .trickle_charger_reg = 0x10, |
| 151 | .do_trickle_setup = &do_trickle_setup_ds1339, | ||
| 146 | }, | 152 | }, |
| 147 | [ds_1340] = { | 153 | [ds_1340] = { |
| 148 | .trickle_charger_reg = 0x08, | 154 | .trickle_charger_reg = 0x08, |
| @@ -833,15 +839,58 @@ ds1307_nvram_write(struct file *filp, struct kobject *kobj, | |||
| 833 | return count; | 839 | return count; |
| 834 | } | 840 | } |
| 835 | 841 | ||
| 842 | |||
| 836 | /*----------------------------------------------------------------------*/ | 843 | /*----------------------------------------------------------------------*/ |
| 837 | 844 | ||
| 845 | static u8 do_trickle_setup_ds1339(struct i2c_client *client, | ||
| 846 | uint32_t ohms, bool diode) | ||
| 847 | { | ||
| 848 | u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE : | ||
| 849 | DS1307_TRICKLE_CHARGER_NO_DIODE; | ||
| 850 | |||
| 851 | switch (ohms) { | ||
| 852 | case 250: | ||
| 853 | setup |= DS1307_TRICKLE_CHARGER_250_OHM; | ||
| 854 | break; | ||
| 855 | case 2000: | ||
| 856 | setup |= DS1307_TRICKLE_CHARGER_2K_OHM; | ||
| 857 | break; | ||
| 858 | case 4000: | ||
| 859 | setup |= DS1307_TRICKLE_CHARGER_4K_OHM; | ||
| 860 | break; | ||
| 861 | default: | ||
| 862 | dev_warn(&client->dev, | ||
| 863 | "Unsupported ohm value %u in dt\n", ohms); | ||
| 864 | return 0; | ||
| 865 | } | ||
| 866 | return setup; | ||
| 867 | } | ||
| 868 | |||
| 869 | static void ds1307_trickle_of_init(struct i2c_client *client, | ||
| 870 | struct chip_desc *chip) | ||
| 871 | { | ||
| 872 | uint32_t ohms = 0; | ||
| 873 | bool diode = true; | ||
| 874 | |||
| 875 | if (!chip->do_trickle_setup) | ||
| 876 | goto out; | ||
| 877 | if (of_property_read_u32(client->dev.of_node, "trickle-resistor-ohms" , &ohms)) | ||
| 878 | goto out; | ||
| 879 | if (of_property_read_bool(client->dev.of_node, "trickle-diode-disable")) | ||
| 880 | diode = false; | ||
| 881 | chip->trickle_charger_setup = chip->do_trickle_setup(client, | ||
| 882 | ohms, diode); | ||
| 883 | out: | ||
| 884 | return; | ||
| 885 | } | ||
| 886 | |||
| 838 | static int ds1307_probe(struct i2c_client *client, | 887 | static int ds1307_probe(struct i2c_client *client, |
| 839 | const struct i2c_device_id *id) | 888 | const struct i2c_device_id *id) |
| 840 | { | 889 | { |
| 841 | struct ds1307 *ds1307; | 890 | struct ds1307 *ds1307; |
| 842 | int err = -ENODEV; | 891 | int err = -ENODEV; |
| 843 | int tmp; | 892 | int tmp; |
| 844 | const struct chip_desc *chip = &chips[id->driver_data]; | 893 | struct chip_desc *chip = &chips[id->driver_data]; |
| 845 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 894 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| 846 | bool want_irq = false; | 895 | bool want_irq = false; |
| 847 | unsigned char *buf; | 896 | unsigned char *buf; |
| @@ -866,9 +915,19 @@ static int ds1307_probe(struct i2c_client *client, | |||
| 866 | ds1307->client = client; | 915 | ds1307->client = client; |
| 867 | ds1307->type = id->driver_data; | 916 | ds1307->type = id->driver_data; |
| 868 | 917 | ||
| 869 | if (pdata && pdata->trickle_charger_setup && chip->trickle_charger_reg) | 918 | if (!pdata && client->dev.of_node) |
| 919 | ds1307_trickle_of_init(client, chip); | ||
| 920 | else if (pdata && pdata->trickle_charger_setup) | ||
| 921 | chip->trickle_charger_setup = pdata->trickle_charger_setup; | ||
| 922 | |||
| 923 | if (chip->trickle_charger_setup && chip->trickle_charger_reg) { | ||
| 924 | dev_dbg(&client->dev, "writing trickle charger info 0x%x to 0x%x\n", | ||
| 925 | DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup, | ||
| 926 | chip->trickle_charger_reg); | ||
| 870 | i2c_smbus_write_byte_data(client, chip->trickle_charger_reg, | 927 | i2c_smbus_write_byte_data(client, chip->trickle_charger_reg, |
| 871 | DS13XX_TRICKLE_CHARGER_MAGIC | pdata->trickle_charger_setup); | 928 | DS13XX_TRICKLE_CHARGER_MAGIC | |
| 929 | chip->trickle_charger_setup); | ||
| 930 | } | ||
| 872 | 931 | ||
| 873 | buf = ds1307->regs; | 932 | buf = ds1307->regs; |
| 874 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { | 933 | if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { |
