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)) { |