aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPali Rohár <pali.rohar@gmail.com>2013-11-19 05:18:04 -0500
committerAnton Vorontsov <anton@enomsg.org>2013-12-23 20:58:03 -0500
commit32260308b4cafcd71b1c0aac35675dc68120c33d (patch)
tree9d8b0c54b2e89b9ccf94b8143099da369af46e02 /drivers
parent56fb8de53e20a853e1a919bf9fb25148ef7560cb (diff)
bq2415x_charger: Use power_supply notifier for automode
This patch removing set_mode_hook function from board data and replacing it with new string variable of notifier power supply device. After this change it is possible to add DT support because driver does not need specific board function anymore. Only static data and name of power supply device is required. Signed-off-by: Pali Rohár <pali.rohar@gmail.com> Reviewed-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Anton Vorontsov <anton@enomsg.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/power/bq2415x_charger.c77
1 files changed, 60 insertions, 17 deletions
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
index df893dd1447d..0bece7026056 100644
--- a/drivers/power/bq2415x_charger.c
+++ b/drivers/power/bq2415x_charger.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * bq2415x charger driver 2 * bq2415x charger driver
3 * 3 *
4 * Copyright (C) 2011-2012 Pali Rohár <pali.rohar@gmail.com> 4 * Copyright (C) 2011-2013 Pali Rohár <pali.rohar@gmail.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -170,6 +170,7 @@ struct bq2415x_device {
170 struct bq2415x_platform_data init_data; 170 struct bq2415x_platform_data init_data;
171 struct power_supply charger; 171 struct power_supply charger;
172 struct delayed_work work; 172 struct delayed_work work;
173 struct notifier_block nb;
173 enum bq2415x_mode reported_mode;/* mode reported by hook function */ 174 enum bq2415x_mode reported_mode;/* mode reported by hook function */
174 enum bq2415x_mode mode; /* current configured mode */ 175 enum bq2415x_mode mode; /* current configured mode */
175 enum bq2415x_chip chip; 176 enum bq2415x_chip chip;
@@ -795,24 +796,53 @@ static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode)
795 796
796} 797}
797 798
798/* hook function called by other driver which set reported mode */ 799static int bq2415x_notifier_call(struct notifier_block *nb,
799static void bq2415x_hook_function(enum bq2415x_mode mode, void *data) 800 unsigned long val, void *v)
800{ 801{
801 struct bq2415x_device *bq = data; 802 struct bq2415x_device *bq =
803 container_of(nb, struct bq2415x_device, nb);
804 struct power_supply *psy = v;
805 enum bq2415x_mode mode;
806 union power_supply_propval prop;
807 int ret;
808 int mA;
802 809
803 if (!bq) 810 if (val != PSY_EVENT_PROP_CHANGED)
804 return; 811 return NOTIFY_OK;
812
813 if (strcmp(psy->name, bq->init_data.notify_device) != 0)
814 return NOTIFY_OK;
815
816 dev_dbg(bq->dev, "notifier call was called\n");
817
818 ret = psy->get_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX, &prop);
819 if (ret != 0)
820 return NOTIFY_OK;
821
822 mA = prop.intval;
823
824 if (mA == 0)
825 mode = BQ2415X_MODE_OFF;
826 else if (mA < 500)
827 mode = BQ2415X_MODE_NONE;
828 else if (mA < 1800)
829 mode = BQ2415X_MODE_HOST_CHARGER;
830 else
831 mode = BQ2415X_MODE_DEDICATED_CHARGER;
832
833 if (bq->reported_mode == mode)
834 return NOTIFY_OK;
805 835
806 dev_dbg(bq->dev, "hook function was called\n");
807 bq->reported_mode = mode; 836 bq->reported_mode = mode;
808 837
809 /* if automode is not enabled do not tell about reported_mode */ 838 /* if automode is not enabled do not tell about reported_mode */
810 if (bq->automode < 1) 839 if (bq->automode < 1)
811 return; 840 return NOTIFY_OK;
812 841
813 sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode"); 842 sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode");
814 bq2415x_set_mode(bq, bq->reported_mode); 843 bq2415x_set_mode(bq, bq->reported_mode);
815 844
845 return NOTIFY_OK;
816} 846}
817 847
818/**** timer functions ****/ 848/**** timer functions ****/
@@ -1512,6 +1542,7 @@ static int bq2415x_probe(struct i2c_client *client,
1512 int num; 1542 int num;
1513 char *name; 1543 char *name;
1514 struct bq2415x_device *bq; 1544 struct bq2415x_device *bq;
1545 struct power_supply *psy;
1515 1546
1516 if (!client->dev.platform_data) { 1547 if (!client->dev.platform_data) {
1517 dev_err(&client->dev, "platform data not set\n"); 1548 dev_err(&client->dev, "platform data not set\n");
@@ -1573,16 +1604,27 @@ static int bq2415x_probe(struct i2c_client *client,
1573 goto error_4; 1604 goto error_4;
1574 } 1605 }
1575 1606
1576 if (bq->init_data.set_mode_hook) { 1607 if (bq->init_data.notify_device) {
1577 if (bq->init_data.set_mode_hook( 1608 bq->nb.notifier_call = bq2415x_notifier_call;
1578 bq2415x_hook_function, bq)) { 1609 ret = power_supply_reg_notifier(&bq->nb);
1579 bq->automode = 1; 1610 if (ret) {
1611 dev_err(bq->dev, "failed to reg notifier: %d\n", ret);
1612 goto error_5;
1613 }
1614 psy = power_supply_get_by_name(bq->init_data.notify_device);
1615 if (psy) {
1616 /* Query for initial reported_mode and set it */
1617 bq2415x_notifier_call(&bq->nb,
1618 PSY_EVENT_PROP_CHANGED, psy);
1580 bq2415x_set_mode(bq, bq->reported_mode); 1619 bq2415x_set_mode(bq, bq->reported_mode);
1581 dev_info(bq->dev, "automode enabled\n");
1582 } else { 1620 } else {
1583 bq->automode = -1; 1621 dev_info(bq->dev, "notifier power supply device (%s) "
1584 dev_info(bq->dev, "automode failed\n"); 1622 "for automode is not registred yet... "
1623 "automode will not work without that device\n",
1624 bq->init_data.notify_device);
1585 } 1625 }
1626 bq->automode = 1;
1627 dev_info(bq->dev, "automode enabled\n");
1586 } else { 1628 } else {
1587 bq->automode = -1; 1629 bq->automode = -1;
1588 dev_info(bq->dev, "automode not supported\n"); 1630 dev_info(bq->dev, "automode not supported\n");
@@ -1594,6 +1636,7 @@ static int bq2415x_probe(struct i2c_client *client,
1594 dev_info(bq->dev, "driver registered\n"); 1636 dev_info(bq->dev, "driver registered\n");
1595 return 0; 1637 return 0;
1596 1638
1639error_5:
1597error_4: 1640error_4:
1598 bq2415x_sysfs_exit(bq); 1641 bq2415x_sysfs_exit(bq);
1599error_3: 1642error_3:
@@ -1614,8 +1657,8 @@ static int bq2415x_remove(struct i2c_client *client)
1614{ 1657{
1615 struct bq2415x_device *bq = i2c_get_clientdata(client); 1658 struct bq2415x_device *bq = i2c_get_clientdata(client);
1616 1659
1617 if (bq->init_data.set_mode_hook) 1660 if (bq->init_data.notify_device)
1618 bq->init_data.set_mode_hook(NULL, NULL); 1661 power_supply_unreg_notifier(&bq->nb);
1619 1662
1620 bq2415x_sysfs_exit(bq); 1663 bq2415x_sysfs_exit(bq);
1621 bq2415x_power_supply_exit(bq); 1664 bq2415x_power_supply_exit(bq);