summaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorEnric Balletbo i Serra <enric.balletbo@collabora.com>2017-01-27 12:43:46 -0500
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2017-02-01 06:44:23 -0500
commit4c466872d8ae8e3cdc3e5e1a47e28a15e3020d8b (patch)
tree12e1940455bb76c712476e5ef2e66244c09b68f0 /drivers/rtc
parent5dff3a3113173a0c835abbda0eef3c0a2a56cc3a (diff)
rtc: bq32000: add support to enable disable the trickle charge FET bypass
The bq32000 includes a trickle charge circuit to maintain the charge of the backup supply when a super capacitor is used. You can enable the charging circuit by setting 'trickle-resistor-ohms', additionally you can set TCFE to 1 to bypass the internal diode and boost the charge voltage of the backup supply. You might want to enable/disable the TCFE switch from userspace (e.g when device is only connected to a battery) This patch introduces a new sysfs entry to enable and disable this FET form userspace. Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-bq32k.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c
index 397742446007..2b223935001f 100644
--- a/drivers/rtc/rtc-bq32k.c
+++ b/drivers/rtc/rtc-bq32k.c
@@ -34,6 +34,7 @@
34#define BQ32K_CALIBRATION 0x07 /* CAL_CFG1, calibration and control */ 34#define BQ32K_CALIBRATION 0x07 /* CAL_CFG1, calibration and control */
35#define BQ32K_TCH2 0x08 /* Trickle charge enable */ 35#define BQ32K_TCH2 0x08 /* Trickle charge enable */
36#define BQ32K_CFG2 0x09 /* Trickle charger control */ 36#define BQ32K_CFG2 0x09 /* Trickle charger control */
37#define BQ32K_TCFE BIT(6) /* Trickle charge FET bypass */
37 38
38struct bq32k_regs { 39struct bq32k_regs {
39 uint8_t seconds; 40 uint8_t seconds;
@@ -188,6 +189,65 @@ static int trickle_charger_of_init(struct device *dev, struct device_node *node)
188 return 0; 189 return 0;
189} 190}
190 191
192static ssize_t bq32k_sysfs_show_tricklecharge_bypass(struct device *dev,
193 struct device_attribute *attr,
194 char *buf)
195{
196 int reg, error;
197
198 error = bq32k_read(dev, &reg, BQ32K_CFG2, 1);
199 if (error)
200 return error;
201
202 return sprintf(buf, "%d\n", (reg & BQ32K_TCFE) ? 1 : 0);
203}
204
205static ssize_t bq32k_sysfs_store_tricklecharge_bypass(struct device *dev,
206 struct device_attribute *attr,
207 const char *buf, size_t count)
208{
209 int reg, enable, error;
210
211 if (kstrtoint(buf, 0, &enable))
212 return -EINVAL;
213
214 error = bq32k_read(dev, &reg, BQ32K_CFG2, 1);
215 if (error)
216 return error;
217
218 if (enable) {
219 reg |= BQ32K_TCFE;
220 error = bq32k_write(dev, &reg, BQ32K_CFG2, 1);
221 if (error)
222 return error;
223
224 dev_info(dev, "Enabled trickle charge FET bypass.\n");
225 } else {
226 reg &= ~BQ32K_TCFE;
227 error = bq32k_write(dev, &reg, BQ32K_CFG2, 1);
228 if (error)
229 return error;
230
231 dev_info(dev, "Disabled trickle charge FET bypass.\n");
232 }
233
234 return count;
235}
236
237static DEVICE_ATTR(trickle_charge_bypass, 0644,
238 bq32k_sysfs_show_tricklecharge_bypass,
239 bq32k_sysfs_store_tricklecharge_bypass);
240
241static int bq32k_sysfs_register(struct device *dev)
242{
243 return device_create_file(dev, &dev_attr_trickle_charge_bypass);
244}
245
246static void bq32k_sysfs_unregister(struct device *dev)
247{
248 device_remove_file(dev, &dev_attr_trickle_charge_bypass);
249}
250
191static int bq32k_probe(struct i2c_client *client, 251static int bq32k_probe(struct i2c_client *client,
192 const struct i2c_device_id *id) 252 const struct i2c_device_id *id)
193{ 253{
@@ -224,11 +284,26 @@ static int bq32k_probe(struct i2c_client *client,
224 if (IS_ERR(rtc)) 284 if (IS_ERR(rtc))
225 return PTR_ERR(rtc); 285 return PTR_ERR(rtc);
226 286
287 error = bq32k_sysfs_register(&client->dev);
288 if (error) {
289 dev_err(&client->dev,
290 "Unable to create sysfs entries for rtc bq32000\n");
291 return error;
292 }
293
294
227 i2c_set_clientdata(client, rtc); 295 i2c_set_clientdata(client, rtc);
228 296
229 return 0; 297 return 0;
230} 298}
231 299
300static int bq32k_remove(struct i2c_client *client)
301{
302 bq32k_sysfs_unregister(&client->dev);
303
304 return 0;
305}
306
232static const struct i2c_device_id bq32k_id[] = { 307static const struct i2c_device_id bq32k_id[] = {
233 { "bq32000", 0 }, 308 { "bq32000", 0 },
234 { } 309 { }
@@ -240,6 +315,7 @@ static struct i2c_driver bq32k_driver = {
240 .name = "bq32k", 315 .name = "bq32k",
241 }, 316 },
242 .probe = bq32k_probe, 317 .probe = bq32k_probe,
318 .remove = bq32k_remove,
243 .id_table = bq32k_id, 319 .id_table = bq32k_id,
244}; 320};
245 321