From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Subject: [PATCH v2 2/3] bq2415x_charger: Use power_supply notifier for automode Date: Tue, 19 Nov 2013 11:18:04 +0100 Message-ID: <1384856285-19593-3-git-send-email-pali.rohar@gmail.com> References: <1378630239-10006-1-git-send-email-pali.rohar@gmail.com> <1384856285-19593-1-git-send-email-pali.rohar@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Return-path: In-Reply-To: <1384856285-19593-1-git-send-email-pali.rohar@gmail.com> Sender: linux-kernel-owner@vger.kernel.org To: Anton Vorontsov , David Woodhouse , Tony Lindgren , Russell King Cc: linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org, freemangordon@abv.bg, aaro.koskinen@iki.fi, pavel@ucw.cz, =?UTF-8?q?Pali=20Roh=C3=A1r?= List-Id: linux-omap@vger.kernel.org This patch removing set_mode_hook function from board data and replacin= g 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=C3=A1r --- drivers/power/bq2415x_charger.c | 77 +++++++++++++++++++++++++= -------- include/linux/power/bq2415x_charger.h | 48 +++----------------- 2 files changed, 65 insertions(+), 60 deletions(-) diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_ch= arger.c index 0727f92..d89583d 100644 --- a/drivers/power/bq2415x_charger.c +++ b/drivers/power/bq2415x_charger.c @@ -1,7 +1,7 @@ /* * bq2415x charger driver * - * Copyright (C) 2011-2012 Pali Roh=C3=A1r + * Copyright (C) 2011-2013 Pali Roh=C3=A1r * * This program is free software; you can redistribute it and/or modif= y * it under the terms of the GNU General Public License as published b= y @@ -170,6 +170,7 @@ struct bq2415x_device { struct bq2415x_platform_data init_data; struct power_supply charger; struct delayed_work work; + struct notifier_block nb; enum bq2415x_mode reported_mode;/* mode reported by hook function */ enum bq2415x_mode mode; /* current configured mode */ enum bq2415x_chip chip; @@ -791,24 +792,53 @@ static int bq2415x_set_mode(struct bq2415x_device= *bq, enum bq2415x_mode mode) =20 } =20 -/* hook function called by other driver which set reported mode */ -static void bq2415x_hook_function(enum bq2415x_mode mode, void *data) +static int bq2415x_notifier_call(struct notifier_block *nb, + unsigned long val, void *v) { - struct bq2415x_device *bq =3D data; + struct bq2415x_device *bq =3D + container_of(nb, struct bq2415x_device, nb); + struct power_supply *psy =3D v; + enum bq2415x_mode mode; + union power_supply_propval prop; + int ret; + int mA; =20 - if (!bq) - return; + if (val !=3D PSY_EVENT_PROP_CHANGED) + return NOTIFY_OK; + + if (strcmp(psy->name, bq->init_data.notify_device) !=3D 0) + return NOTIFY_OK; + + dev_dbg(bq->dev, "notifier call was called\n"); + + ret =3D psy->get_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX, &prop); + if (ret !=3D 0) + return NOTIFY_OK; + + mA =3D prop.intval; + + if (mA =3D=3D 0) + mode =3D BQ2415X_MODE_OFF; + else if (mA < 500) + mode =3D BQ2415X_MODE_NONE; + else if (mA < 1800) + mode =3D BQ2415X_MODE_HOST_CHARGER; + else + mode =3D BQ2415X_MODE_DEDICATED_CHARGER; + + if (bq->reported_mode =3D=3D mode) + return NOTIFY_OK; =20 - dev_dbg(bq->dev, "hook function was called\n"); bq->reported_mode =3D mode; =20 /* if automode is not enabled do not tell about reported_mode */ if (bq->automode < 1) - return; + return NOTIFY_OK; =20 sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode"); bq2415x_set_mode(bq, bq->reported_mode); =20 + return NOTIFY_OK; } =20 /**** timer functions ****/ @@ -1508,6 +1538,7 @@ static int bq2415x_probe(struct i2c_client *clien= t, int num; char *name; struct bq2415x_device *bq; + struct power_supply *psy; =20 if (!client->dev.platform_data) { dev_err(&client->dev, "platform data not set\n"); @@ -1569,16 +1600,27 @@ static int bq2415x_probe(struct i2c_client *cli= ent, goto error_4; } =20 - if (bq->init_data.set_mode_hook) { - if (bq->init_data.set_mode_hook( - bq2415x_hook_function, bq)) { - bq->automode =3D 1; + if (bq->init_data.notify_device) { + bq->nb.notifier_call =3D bq2415x_notifier_call; + ret =3D power_supply_reg_notifier(&bq->nb); + if (ret) { + dev_err(bq->dev, "failed to reg notifier: %d\n", ret); + goto error_5; + } + psy =3D power_supply_get_by_name(bq->init_data.notify_device); + if (psy) { + /* Query for initial reported_mode and set it */ + bq2415x_notifier_call(&bq->nb, + PSY_EVENT_PROP_CHANGED, psy); bq2415x_set_mode(bq, bq->reported_mode); - dev_info(bq->dev, "automode enabled\n"); } else { - bq->automode =3D -1; - dev_info(bq->dev, "automode failed\n"); + dev_info(bq->dev, "notifier power supply device (%s) " + "for automode is not registred yet... " + "automode will not work without that device\n", + bq->init_data.notify_device); } + bq->automode =3D 1; + dev_info(bq->dev, "automode enabled\n"); } else { bq->automode =3D -1; dev_info(bq->dev, "automode not supported\n"); @@ -1590,6 +1632,7 @@ static int bq2415x_probe(struct i2c_client *clien= t, dev_info(bq->dev, "driver registered\n"); return 0; =20 +error_5: error_4: bq2415x_sysfs_exit(bq); error_3: @@ -1610,8 +1653,8 @@ static int bq2415x_remove(struct i2c_client *clie= nt) { struct bq2415x_device *bq =3D i2c_get_clientdata(client); =20 - if (bq->init_data.set_mode_hook) - bq->init_data.set_mode_hook(NULL, NULL); + if (bq->init_data.notify_device) + power_supply_unreg_notifier(&bq->nb); =20 bq2415x_sysfs_exit(bq); bq2415x_power_supply_exit(bq); diff --git a/include/linux/power/bq2415x_charger.h b/include/linux/powe= r/bq2415x_charger.h index 8dcc0f4..50762af 100644 --- a/include/linux/power/bq2415x_charger.h +++ b/include/linux/power/bq2415x_charger.h @@ -1,7 +1,7 @@ /* * bq2415x charger driver * - * Copyright (C) 2011-2012 Pali Roh=C3=A1r + * Copyright (C) 2011-2013 Pali Roh=C3=A1r * * This program is free software; you can redistribute it and/or modif= y * it under the terms of the GNU General Public License as published b= y @@ -31,46 +31,9 @@ * termination current. It it is less or equal to zero, configuring ch= arge * and termination current will not be possible. * - * Function set_mode_hook is needed for automode (setting correct curr= ent - * limit when charger is connected/disconnected or setting boost mode)= =2E - * When is NULL, automode function is disabled. When is not NULL, it m= ust - * have this prototype: - * - * int (*set_mode_hook)( - * void (*hook)(enum bq2415x_mode mode, void *data), - * void *data) - * - * hook is hook function (see below) and data is pointer to driver pri= vate - * data - * - * bq2415x driver will call it as: - * - * platform_data->set_mode_hook(bq2415x_hook_function, bq2415x_devi= ce); - * - * Board/platform function set_mode_hook return non zero value when ho= ok - * function was successful registered. Platform code should call that = hook - * function (which get from pointer, with data) every time when charge= r - * was connected/disconnected or require to enable boost mode. bq2415x - * driver then will set correct current limit, enable/disable charger = or - * boost mode. - * - * Hook function has this prototype: - * - * void hook(enum bq2415x_mode mode, void *data); - * - * mode is bq2415x mode (charger or boost) - * data is pointer to driver private data (which get from - * set_charger_type_hook) - * - * When bq driver is being unloaded, it call function: - * - * platform_data->set_mode_hook(NULL, NULL); - * - * (hook function and driver private data are NULL) - * - * After that board/platform code must not call driver hook function! = It - * is possible that pointer to hook function will not be valid and cal= ling - * will cause undefined result. + * For automode support is needed to provide name of power supply devi= ce + * in value notify_device. Device driver must immediately report prope= rty + * POWER_SUPPLY_PROP_CURRENT_MAX when current changed. */ =20 /* Supported modes with maximal current limit */ @@ -89,8 +52,7 @@ struct bq2415x_platform_data { int charge_current; /* mA */ int termination_current; /* mA */ int resistor_sense; /* m ohm */ - int (*set_mode_hook)(void (*hook)(enum bq2415x_mode mode, void *data)= , - void *data); + const char *notify_device; /* name */ }; =20 #endif --=20 1.7.9.5