RE: [RFC 4/4] charger-manager: Enable psy based charge control

2015-03-09 Thread Tc, Jenny
Hi,
 
> On Fri, Mar 06, 2015 at 04:03:27PM +0530, Jenny TC wrote:
> > At present charger manager support only regulator based charging
> > control. But most of the charger drivers are registered with power
> > supply subsystem. This patch adds support for power supply based
> > charging control along with the regulator based control. With the
> > patch, charging control can be done either using power supply
> > interface or with regulator interface. The charging is setup
> > based on battery parameters received through the battery info
> > handlers.
> 
> [...]
> 
> (so far I only skipped over the patch)

Appreciate if you could review entire patch. I will submit next patch set
addressing all your comments.

> [...]
> 
> > @@ -1704,6 +1968,10 @@ static int charger_manager_probe(struct
> platform_device *pdev)
> > strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX);
> > cm->charger_psy.name = cm->psy_name_buf;
> >
> > +   if (!power_supply_get_property(fuel_gauge,
> POWER_SUPPLY_PROP_MODEL_NAME,
> > +   &val))
> > +   cm->battery_info = psy_get_battery_info(val.strval);
> > +
> > /* Allocate for psy properties because they may vary */
> > cm->charger_psy.properties = devm_kzalloc(&pdev->dev,
> > sizeof(enum power_supply_property)
> 
> We are currently splitting battery data from fuel gauge data, so
> acquiring the battery using the fuel gauge's MODEL_NAME is not very
> nice.


Will enhance struct charger_desc{ ..} to support list of battery model name
supported. This can be used to query battery_info using psy_get_battery_info()

-Jenny
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC 4/4] charger-manager: Enable psy based charge control

2015-03-07 Thread Sebastian Reichel
Hi,

On Fri, Mar 06, 2015 at 04:03:27PM +0530, Jenny TC wrote:
> At present charger manager support only regulator based charging
> control. But most of the charger drivers are registered with power
> supply subsystem. This patch adds support for power supply based
> charging control along with the regulator based control. With the
> patch, charging control can be done either using power supply
> interface or with regulator interface. The charging is setup
> based on battery parameters received through the battery info
> handlers.

[...]

(so far I only skipped over the patch)

[...]

> @@ -1704,6 +1968,10 @@ static int charger_manager_probe(struct 
> platform_device *pdev)
>   strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX);
>   cm->charger_psy.name = cm->psy_name_buf;
>  
> + if (!power_supply_get_property(fuel_gauge, POWER_SUPPLY_PROP_MODEL_NAME,
> + &val))
> + cm->battery_info = psy_get_battery_info(val.strval);
> +
>   /* Allocate for psy properties because they may vary */
>   cm->charger_psy.properties = devm_kzalloc(&pdev->dev,
>   sizeof(enum power_supply_property)

We are currently splitting battery data from fuel gauge data, so
acquiring the battery using the fuel gauge's MODEL_NAME is not very
nice.

-- Sebastian


signature.asc
Description: Digital signature


[RFC 4/4] charger-manager: Enable psy based charge control

2015-03-06 Thread Jenny TC
At present charger manager support only regulator based charging
control. But most of the charger drivers are registered with power
supply subsystem. This patch adds support for power supply based
charging control along with the regulator based control. With the
patch, charging control can be done either using power supply
interface or with regulator interface. The charging is setup
based on battery parameters received through the battery info
handlers.

Signed-off-by: Jenny TC 
---
 drivers/power/charger-manager.c   |  486 +
 include/linux/power/charger-manager.h |   30 +-
 2 files changed, 399 insertions(+), 117 deletions(-)

diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
index 14b0d85..b455ac2 100644
--- a/drivers/power/charger-manager.c
+++ b/drivers/power/charger-manager.c
@@ -42,6 +42,7 @@ static const char * const default_event_names[] = {
[CM_EVENT_BATT_OUT] = "Battery Pulled Out",
[CM_EVENT_BATT_OVERHEAT] = "Battery Overheat",
[CM_EVENT_BATT_COLD] = "Battery Cold",
+   [CM_EVENT_BATT_TZONE_CHANGE] = "Battery Temp Zone Change",
[CM_EVENT_EXT_PWR_IN_OUT] = "External Power Attach/Detach",
[CM_EVENT_CHG_START_STOP] = "Charging Start/Stop",
[CM_EVENT_OTHERS] = "Other battery events"
@@ -81,6 +82,97 @@ static unsigned long next_polling; /* Next appointed polling 
time */
 static struct workqueue_struct *cm_wq; /* init at driver add */
 static struct delayed_work cm_monitor_work; /* init at driver add */
 
+static inline int psy_set_charger_contol_prop(struct power_supply *psy,
+   enum psy_charger_control_property pscp,
+   const union power_supply_propval *val)
+{
+   struct power_supply_charger *psyc;
+
+   psyc = psy->psy_charger;
+
+   if (psyc && psyc->set_property)
+   return psyc->set_property(psyc, pscp, val);
+
+   return -EINVAL;
+}
+
+static inline int psy_get_charger_contol_prop(struct power_supply *psy,
+   enum psy_charger_control_property pscp,
+   union power_supply_propval *val)
+{
+   struct power_supply_charger *psyc;
+
+   psyc = psy->psy_charger;
+
+   if (psyc && psyc->get_property)
+   return psyc->get_property(psyc, pscp, val);
+
+   return -EINVAL;
+}
+
+static inline int psy_enable_charger(struct power_supply *psy, bool enable)
+{
+   union power_supply_propval prop_val;
+
+   prop_val.intval = enable;
+   return psy_set_charger_contol_prop(psy,
+   PSY_CHARGER_PROP_ENABLE_CHARGER, &prop_val);
+}
+
+static inline int psy_is_charger_enabled(struct power_supply *psy)
+{
+   union power_supply_propval prop_val;
+   int ret;
+
+   ret = psy_get_charger_contol_prop(psy,
+   PSY_CHARGER_PROP_ENABLE_CHARGER, &prop_val);
+   if (ret)
+   return ret;
+
+   return prop_val.intval;
+}
+
+static inline int psy_set_inlimit(struct power_supply *psy, int inlimit)
+{
+   union power_supply_propval prop_val;
+
+   prop_val.intval = inlimit;
+   return power_supply_set_property(psy,
+   POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
+   &prop_val);
+}
+
+static int enable_charger(struct charger_controller *charger, bool enable)
+{
+   if (charger->regulator_control) {
+   if (enable)
+   return regulator_enable(charger->regulator_control);
+   else
+   return regulator_disable(charger->regulator_control);
+   }
+
+   return psy_enable_charger(charger->psy_control, enable);
+}
+
+static int is_charger_enabled(struct charger_controller *charger)
+{
+   if (charger->regulator_control)
+   return regulator_is_enabled(charger->regulator_control);
+
+   return psy_is_charger_enabled(charger->psy_control);
+}
+
+static int set_input_current(struct charger_cable *cable)
+{
+   if (cable->charger->regulator_control)
+   return regulator_set_current_limit(
+   cable->charger->regulator_control,
+   cable->min_uA, cable->max_uA);
+
+   return psy_set_inlimit(cable->charger->psy_control,
+   cable->max_uA / 1000);
+}
+
 /**
  * is_batt_present - See if the battery presents in place.
  * @cm: the Charger Manager representing the battery.
@@ -328,6 +420,140 @@ static bool is_polling_required(struct charger_manager 
*cm)
return false;
 }
 
+static int get_temp_zone_index(struct psy_charging_obj *cobj, int temp)
+{
+   int i, tzone_count;
+
+   tzone_count = cobj->temp_mon_count > PSY_MAX_TEMP_ZONE ?
+   PSY_MAX_TEMP_ZONE : cobj->temp_mon_count;
+
+   for (i = 0; i < tzone_count; i++) {
+   if (temp <=  cobj-