aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/power/bq2415x_charger.c77
-rw-r--r--include/linux/power/bq2415x_charger.h48
2 files changed, 65 insertions, 60 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);
diff --git a/include/linux/power/bq2415x_charger.h b/include/linux/power/bq2415x_charger.h
index 8dcc0f46fc0a..50762af8b834 100644
--- a/include/linux/power/bq2415x_charger.h
+++ b/include/linux/power/bq2415x_charger.h
@@ -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
@@ -31,46 +31,9 @@
31 * termination current. It it is less or equal to zero, configuring charge 31 * termination current. It it is less or equal to zero, configuring charge
32 * and termination current will not be possible. 32 * and termination current will not be possible.
33 * 33 *
34 * Function set_mode_hook is needed for automode (setting correct current 34 * For automode support is needed to provide name of power supply device
35 * limit when charger is connected/disconnected or setting boost mode). 35 * in value notify_device. Device driver must immediately report property
36 * When is NULL, automode function is disabled. When is not NULL, it must 36 * POWER_SUPPLY_PROP_CURRENT_MAX when current changed.
37 * have this prototype:
38 *
39 * int (*set_mode_hook)(
40 * void (*hook)(enum bq2415x_mode mode, void *data),
41 * void *data)
42 *
43 * hook is hook function (see below) and data is pointer to driver private
44 * data
45 *
46 * bq2415x driver will call it as:
47 *
48 * platform_data->set_mode_hook(bq2415x_hook_function, bq2415x_device);
49 *
50 * Board/platform function set_mode_hook return non zero value when hook
51 * function was successful registered. Platform code should call that hook
52 * function (which get from pointer, with data) every time when charger
53 * was connected/disconnected or require to enable boost mode. bq2415x
54 * driver then will set correct current limit, enable/disable charger or
55 * boost mode.
56 *
57 * Hook function has this prototype:
58 *
59 * void hook(enum bq2415x_mode mode, void *data);
60 *
61 * mode is bq2415x mode (charger or boost)
62 * data is pointer to driver private data (which get from
63 * set_charger_type_hook)
64 *
65 * When bq driver is being unloaded, it call function:
66 *
67 * platform_data->set_mode_hook(NULL, NULL);
68 *
69 * (hook function and driver private data are NULL)
70 *
71 * After that board/platform code must not call driver hook function! It
72 * is possible that pointer to hook function will not be valid and calling
73 * will cause undefined result.
74 */ 37 */
75 38
76/* Supported modes with maximal current limit */ 39/* Supported modes with maximal current limit */
@@ -89,8 +52,7 @@ struct bq2415x_platform_data {
89 int charge_current; /* mA */ 52 int charge_current; /* mA */
90 int termination_current; /* mA */ 53 int termination_current; /* mA */
91 int resistor_sense; /* m ohm */ 54 int resistor_sense; /* m ohm */
92 int (*set_mode_hook)(void (*hook)(enum bq2415x_mode mode, void *data), 55 const char *notify_device; /* name */
93 void *data);
94}; 56};
95 57
96#endif 58#endif