linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Implement device tree support for ab8500 BM Devices
@ 2012-10-31 15:40 Rajanikanth H.V
  2012-10-31 15:40 ` [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge Rajanikanth H.V
                   ` (4 more replies)
  0 siblings, 5 replies; 23+ messages in thread
From: Rajanikanth H.V @ 2012-10-31 15:40 UTC (permalink / raw)
  To: rob.herring, lee.jones, francescolavra.fl
  Cc: arnd, anton.vorontsov, linus.walleij, linux-arm-kernel,
	linux-kernel, linaro-dev, patches, STEricsson_nomadik_linux,
	rajanikanth.hv

From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>

This patch-set adds device tree binding for ab8500 battery-managed
devices. Removes the redundant platform structure maintained
across bm devices and implements common DT probe routine across all the
modules.

Test status:
a) Tested across 'legacy platform data' and DT binding support
	a.1) ab8500_charger driver fails to get regulator in the
		legacy platform mode.
b) Interrupt numbers assigned differs between legacy and FDT mode.
    (a) Legacy platform_data Mode:
    root@ME:/ cat /proc/interrupts
               CPU0       CPU1
    483:          0          0    ab8500  ab8500-ponkey-dbf
    484:          0          0    ab8500  ab8500-ponkey-dbr
    485:          0          0    ab8500  BATT_OVV
    494:          0          1    ab8500
    495:          0          0    ab8500  ab8500-rtc
    501:          0         13    ab8500  NCONV_ACCU
    503:          7         22    ab8500  CCEOC
    504:          0          1    ab8500  CC_INT_CALIB
    505:          0          0    ab8500  LOW_BAT_F
    516:          0         34    ab8500  ab8500-gpadc
    556:          0          0    ab8500  usb-link-status
    
    (b) FDT Mode:
    root@ME:/ cat /proc/interrupts
               CPU0       CPU1
      6:          0          0    ab8500  ab8500-ponkey-dbf
      7:          0          0    ab8500  ab8500-ponkey-dbr
      8:          0          0    ab8500  BATT_OVV
    162:          0          7    ab8500  ab8500-gpadc
    163:          0          1    ab8500
    164:          0          0    ab8500  ab8500-rtc
    484:          0          0    ab8500  usb-link-status
    499:          0          4    ab8500  NCONV_ACCU
    500:          0          0    ab8500  LOW_BAT_F
    502:          0          1    ab8500  CC_INT_CALIB
    503:          0          6    ab8500  CCEOC

c) Event handlers across bm-modules have been verified only
   during 'battery discharge process' as 'battery charging process'
   depends on ab8500-usb code

Rajanikanth H.V (4):
  mfd: ab8500: add devicetree support for fuelgauge
  mfd: ab8500: add devicetree support for btemp
  mfd: ab8500: add devicetree support for charger
  mfd: ab8500: add devicetree support for chargalg

 Documentation/devicetree/bindings/mfd/ab8500.txt   |   27 +-
 .../bindings/power_supply/ab8500/btemp.txt         |   16 +
 .../bindings/power_supply/ab8500/chargalg.txt      |   16 +
 .../bindings/power_supply/ab8500/charger.txt       |   25 +
 .../devicetree/bindings/power_supply/ab8500/fg.txt |   58 +++
 arch/arm/boot/dts/dbx5x0.dtsi                      |   28 +-
 drivers/mfd/ab8500-core.c                          |   20 +
 drivers/power/Kconfig                              |    6 -
 drivers/power/Makefile                             |    2 +-
 drivers/power/ab8500_bmdata.c                      |  518 ++++++++++++++++++++
 drivers/power/ab8500_btemp.c                       |   76 +--
 drivers/power/ab8500_charger.c                     |   83 ++--
 drivers/power/ab8500_fg.c                          |   81 +--
 drivers/power/abx500_chargalg.c                    |   56 ++-
 include/linux/mfd/abx500.h                         |   34 +-
 15 files changed, 881 insertions(+), 165 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt
 create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt
 create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/charger.txt
 create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
 create mode 100644 drivers/power/ab8500_bmdata.c

-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-10-31 15:40 [PATCH 0/4] Implement device tree support for ab8500 BM Devices Rajanikanth H.V
@ 2012-10-31 15:40 ` Rajanikanth H.V
  2012-11-01 15:15   ` Francesco Lavra
  2012-10-31 15:40 ` [PATCH 2/4] mfd: ab8500: add devicetree support for btemp Rajanikanth H.V
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 23+ messages in thread
From: Rajanikanth H.V @ 2012-10-31 15:40 UTC (permalink / raw)
  To: rob.herring, lee.jones, francescolavra.fl
  Cc: arnd, anton.vorontsov, linus.walleij, linux-arm-kernel,
	linux-kernel, linaro-dev, patches, STEricsson_nomadik_linux,
	rajanikanth.hv

From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>

- This patch adds device tree support for fuelgauge driver
- optimize bm devices platform_data usage and of_probe(...)
  Note: of_probe() routine for battery managed devices is made
  common across all bm drivers.
- test status:
  - interrupt numbers assigned differs between legacy and FDT mode.

Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
---
 Documentation/devicetree/bindings/mfd/ab8500.txt   |    7 +-
 .../devicetree/bindings/power_supply/ab8500/fg.txt |   58 +++
 arch/arm/boot/dts/dbx5x0.dtsi                      |   12 +-
 drivers/mfd/ab8500-core.c                          |    5 +
 drivers/power/Makefile                             |    2 +-
 drivers/power/ab8500_bmdata.c                      |  518 ++++++++++++++++++++
 drivers/power/ab8500_btemp.c                       |   16 +-
 drivers/power/ab8500_charger.c                     |   16 +-
 drivers/power/ab8500_fg.c                          |   81 +--
 drivers/power/abx500_chargalg.c                    |    8 +-
 include/linux/mfd/abx500.h                         |   36 +-
 11 files changed, 664 insertions(+), 95 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
 create mode 100644 drivers/power/ab8500_bmdata.c

diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
index ce83c8d..6ca8d81 100644
--- a/Documentation/devicetree/bindings/mfd/ab8500.txt
+++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
@@ -24,7 +24,12 @@ ab8500-bm                :                      :              : Battery Manager
 ab8500-btemp             :                      :              : Battery Temperature
 ab8500-charger           :                      :              : Battery Charger
 ab8500-codec             :                      :              : Audio Codec
-ab8500-fg                :                      :              : Fuel Gauge
+ab8500-fg                : 			: vddadc       : Fuel Gauge
+			 : NCONV_ACCU           :	       : Accumulate N Sample Conversion
+			 : BATT_OVV		:	       : Battery Over Voltage
+			 : LOW_BAT_F		:	       : LOW threshold battery voltage
+			 : CC_INT_CALIB		:	       : Coulomb Counter Internal Calibration
+			 : CCEOC		:	       : Coulomb Counter End of Conversion
 ab8500-gpadc             : HW_CONV_END          : vddadc       : Analogue to Digital Converter
                            SW_CONV_END          :              :
 ab8500-gpio              :                      :              : GPIO Controller
diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
new file mode 100644
index 0000000..ccafcb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
@@ -0,0 +1,58 @@
+=== AB8500 Fuel Gauge Driver ===
+
+AB8500 is a mixed signal multimedia and power management
+device comprising: power and energy-management-module,
+wall-charger, usb-charger, audio codec, general purpose adc,
+tvout, clock management and sim card interface.
+
+Fuelgauge support is part of energy-management-modules, other
+components of this module are:
+main-charger, usb-combo-charger and battery-temperature-monitoring.
+
+The properties below describes the node for fuelgauge driver.
+
+Required Properties:
+- compatible = This shall be: "stericsson,ab8500-fg"
+- battery = Shall be battery specific information
+	Example:
+	ab8500_fg {
+		compatible = "stericsson,ab8500-fg";
+		battery	   = <&ab8500_battery>;
+	};
+
+dependent node:
+	ab8500_battery: ab8500_battery {
+	};
+	This node will provide information on 'thermistor interface' and
+	'battery technology type' used.
+
+Properties of this node are:
+thermistor-on-batctrl:
+	A boolean value indicating thermistor interface	to battery
+
+	Note:
+	'btemp' and 'batctrl' are the pins interfaced for battery temperature
+	measurement, 'btemp' signal is used when NTC(negative temperature
+	coefficient) resister is interfaced external to battery whereas
+	'batctrl' pin is used when NTC resister is internal to battery.
+
+	Example:
+	ab8500_battery: ab8500_battery {
+		thermistor-on-batctrl;
+	};
+	indicates: NTC resister is internal to battery, 'batctrl' is used
+		for thermal measurement.
+
+	The absence of property 'thermal-on-batctrl' indicates
+	NTC resister is external to battery and  'btemp' signal is used
+	for thermal measurement.
+
+battery-type:
+	This shall be the battery manufacturing technology type,
+	allowed types are:
+		"UNKNOWN" "NiMH" "LION" "LIPO" "LiFe" "NiCd" "LiMn"
+	Example:
+	ab8500_battery: ab8500_battery {
+		stericsson,battery-type = "LIPO";
+	}
+
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 748ba7a..68317f5 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -352,7 +352,17 @@
 					vddadc-supply = <&ab8500_ldo_tvout_reg>;
 				};
 
-				ab8500-usb {
+				ab8500_battery: ab8500_battery {
+					stericsson,battery-type = "LIPO";
+					thermistor-on-batctrl;
+				};
+
+				ab8500_fg {
+					compatible = "stericsson,ab8500-fg";
+					battery	   = <&ab8500_battery>;
+				};
+
+				ab8500_usb {
 					compatible = "stericsson,ab8500-usb";
 					interrupts = < 90 0x4
 						       96 0x4
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 1667c77..7c3017b 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1051,8 +1051,13 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
 	},
 	{
 		.name = "ab8500-fg",
+		.of_compatible = "stericsson,ab8500-fg",
 		.num_resources = ARRAY_SIZE(ab8500_fg_resources),
 		.resources = ab8500_fg_resources,
+#ifndef CONFIG_OF
+		.platform_data = &ab8500_bm_data,
+		.pdata_size = sizeof(ab8500_bm_data),
+#endif
 	},
 	{
 		.name = "ab8500-chargalg",
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index ee58afb..2c58d4e 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -34,7 +34,7 @@ obj-$(CONFIG_BATTERY_S3C_ADC)	+= s3c_adc_battery.o
 obj-$(CONFIG_CHARGER_PCF50633)	+= pcf50633-charger.o
 obj-$(CONFIG_BATTERY_JZ4740)	+= jz4740-battery.o
 obj-$(CONFIG_BATTERY_INTEL_MID)	+= intel_mid_battery.o
-obj-$(CONFIG_AB8500_BM)		+= ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o
+obj-$(CONFIG_AB8500_BM)		+= ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o
 obj-$(CONFIG_CHARGER_ISP1704)	+= isp1704_charger.o
 obj-$(CONFIG_CHARGER_MAX8903)	+= max8903_charger.o
 obj-$(CONFIG_CHARGER_TWL4030)	+= twl4030_charger.o
diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c
new file mode 100644
index 0000000..fa6ea52
--- /dev/null
+++ b/drivers/power/ab8500_bmdata.c
@@ -0,0 +1,518 @@
+#include <linux/export.h>
+#include <linux/power_supply.h>
+#include <linux/of.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-bm.h>
+
+/*
+ * These are the defined batteries that uses a NTC and ID resistor placed
+ * inside of the battery pack.
+ * Note that the res_to_temp table must be strictly sorted by falling resistance
+ * values to work.
+ */
+static struct abx500_res_to_temp temp_tbl_A_thermistor[] = {
+	{-5, 53407},
+	{ 0, 48594},
+	{ 5, 43804},
+	{10, 39188},
+	{15, 34870},
+	{20, 30933},
+	{25, 27422},
+	{30, 24347},
+	{35, 21694},
+	{40, 19431},
+	{45, 17517},
+	{50, 15908},
+	{55, 14561},
+	{60, 13437},
+	{65, 12500},
+};
+static struct abx500_res_to_temp temp_tbl_B_thermistor[] = {
+	{-5, 165418},
+	{ 0, 159024},
+	{ 5, 151921},
+	{10, 144300},
+	{15, 136424},
+	{20, 128565},
+	{25, 120978},
+	{30, 113875},
+	{35, 107397},
+	{40, 101629},
+	{45,  96592},
+	{50,  92253},
+	{55,  88569},
+	{60,  85461},
+	{65,  82869},
+};
+static struct abx500_v_to_cap cap_tbl_A_thermistor[] = {
+	{4171,	100},
+	{4114,	 95},
+	{4009,	 83},
+	{3947,	 74},
+	{3907,	 67},
+	{3863,	 59},
+	{3830,	 56},
+	{3813,	 53},
+	{3791,	 46},
+	{3771,	 33},
+	{3754,	 25},
+	{3735,	 20},
+	{3717,	 17},
+	{3681,	 13},
+	{3664,	  8},
+	{3651,	  6},
+	{3635,	  5},
+	{3560,	  3},
+	{3408,    1},
+	{3247,	  0},
+};
+static struct abx500_v_to_cap cap_tbl_B_thermistor[] = {
+	{4161,	100},
+	{4124,	 98},
+	{4044,	 90},
+	{4003,	 85},
+	{3966,	 80},
+	{3933,	 75},
+	{3888,	 67},
+	{3849,	 60},
+	{3813,	 55},
+	{3787,	 47},
+	{3772,	 30},
+	{3751,	 25},
+	{3718,	 20},
+	{3681,	 16},
+	{3660,	 14},
+	{3589,	 10},
+	{3546,	  7},
+	{3495,	  4},
+	{3404,	  2},
+	{3250,	  0},
+};
+
+static struct abx500_v_to_cap cap_tbl[] = {
+	{4186,	100},
+	{4163,	 99},
+	{4114,	 95},
+	{4068,	 90},
+	{3990,	 80},
+	{3926,	 70},
+	{3898,	 65},
+	{3866,	 60},
+	{3833,	 55},
+	{3812,	 50},
+	{3787,	 40},
+	{3768,	 30},
+	{3747,	 25},
+	{3730,	 20},
+	{3705,	 15},
+	{3699,	 14},
+	{3684,	 12},
+	{3672,	  9},
+	{3657,	  7},
+	{3638,	  6},
+	{3556,	  4},
+	{3424,	  2},
+	{3317,	  1},
+	{3094,	  0},
+};
+
+/*
+ * Note that the res_to_temp table must be strictly sorted by falling
+ * resistance values to work.
+ */
+static struct abx500_res_to_temp temp_tbl[] = {
+	{-5, 214834},
+	{ 0, 162943},
+	{ 5, 124820},
+	{10,  96520},
+	{15,  75306},
+	{20,  59254},
+	{25,  47000},
+	{30,  37566},
+	{35,  30245},
+	{40,  24520},
+	{45,  20010},
+	{50,  16432},
+	{55,  13576},
+	{60,  11280},
+	{65,   9425},
+};
+
+/*
+ * Note that the batres_vs_temp table must be strictly sorted by falling
+ * temperature values to work.
+ */
+struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {
+	{ 40, 120},
+	{ 30, 135},
+	{ 20, 165},
+	{ 10, 230},
+	{ 00, 325},
+	{-10, 445},
+	{-20, 595},
+};
+
+/*
+ * Note that the batres_vs_temp table must be strictly sorted by falling
+ * temperature values to work.
+ */
+struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = {
+	{ 60, 300},
+	{ 30, 300},
+	{ 20, 300},
+	{ 10, 300},
+	{ 00, 300},
+	{-10, 300},
+	{-20, 300},
+};
+
+/* battery resistance table for LI ION 9100 battery */
+struct batres_vs_temp temp_to_batres_tbl_9100[] = {
+	{ 60, 180},
+	{ 30, 180},
+	{ 20, 180},
+	{ 10, 180},
+	{ 00, 180},
+	{-10, 180},
+	{-20, 180},
+};
+
+struct abx500_battery_type bat_type_thermistor[] = {
+[BATTERY_UNKNOWN] = {
+	/* First element always represent the UNKNOWN battery */
+	.name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
+	.resis_high = 0,
+	.resis_low = 0,
+	.battery_resistance = 300,
+	.charge_full_design = 612,
+	.nominal_voltage = 3700,
+	.termination_vol = 4050,
+	.termination_curr = 200,
+	.recharge_vol = 3990,
+	.normal_cur_lvl = 400,
+	.normal_vol_lvl = 4100,
+	.maint_a_cur_lvl = 400,
+	.maint_a_vol_lvl = 4050,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 400,
+	.maint_b_vol_lvl = 4000,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.resis_high = 53407,
+	.resis_low = 12500,
+	.battery_resistance = 300,
+	.charge_full_design = 900,
+	.nominal_voltage = 3600,
+	.termination_vol = 4150,
+	.termination_curr = 80,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_A_thermistor),
+	.r_to_t_tbl = temp_tbl_A_thermistor,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_A_thermistor),
+	.v_to_cap_tbl = cap_tbl_A_thermistor,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+
+},
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.resis_high = 165418,
+	.resis_low = 82869,
+	.battery_resistance = 300,
+	.charge_full_design = 900,
+	.nominal_voltage = 3600,
+	.termination_vol = 4150,
+	.termination_curr = 80,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_B_thermistor),
+	.r_to_t_tbl = temp_tbl_B_thermistor,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_B_thermistor),
+	.v_to_cap_tbl = cap_tbl_B_thermistor,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+};
+
+struct abx500_battery_type bat_type_ext_thermistor[] = {
+[BATTERY_UNKNOWN] = {
+	/* First element always represent the UNKNOWN battery */
+	.name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
+	.resis_high = 0,
+	.resis_low = 0,
+	.battery_resistance = 300,
+	.charge_full_design = 612,
+	.nominal_voltage = 3700,
+	.termination_vol = 4050,
+	.termination_curr = 200,
+	.recharge_vol = 3990,
+	.normal_cur_lvl = 400,
+	.normal_vol_lvl = 4100,
+	.maint_a_cur_lvl = 400,
+	.maint_a_vol_lvl = 4050,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 400,
+	.maint_b_vol_lvl = 4000,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+/*
+ * These are the batteries that doesn't have an internal NTC resistor to measure
+ * its temperature. The temperature in this case is measure with a NTC placed
+ * near the battery but on the PCB.
+ */
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.resis_high = 76000,
+	.resis_low = 53000,
+	.battery_resistance = 300,
+	.charge_full_design = 900,
+	.nominal_voltage = 3700,
+	.termination_vol = 4150,
+	.termination_curr = 100,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LION,
+	.resis_high = 30000,
+	.resis_low = 10000,
+	.battery_resistance = 300,
+	.charge_full_design = 950,
+	.nominal_voltage = 3700,
+	.termination_vol = 4150,
+	.termination_curr = 100,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LION,
+	.resis_high = 95000,
+	.resis_low = 76001,
+	.battery_resistance = 300,
+	.charge_full_design = 950,
+	.nominal_voltage = 3700,
+	.termination_vol = 4150,
+	.termination_curr = 100,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+};
+
+static const struct abx500_bm_capacity_levels cap_levels = {
+	.critical	= 2,
+	.low		= 10,
+	.normal		= 70,
+	.high		= 95,
+	.full		= 100,
+};
+
+static const struct abx500_fg_parameters fg = {
+	.recovery_sleep_timer = 10,
+	.recovery_total_time = 100,
+	.init_timer = 1,
+	.init_discard_time = 5,
+	.init_total_time = 40,
+	.high_curr_time = 60,
+	.accu_charging = 30,
+	.accu_high_curr = 30,
+	.high_curr_threshold = 50,
+	.lowbat_threshold = 3100,
+	.battok_falling_th_sel0 = 2860,
+	.battok_raising_th_sel1 = 2860,
+	.user_cap_limit = 15,
+	.maint_thres = 97,
+};
+
+static const struct abx500_maxim_parameters maxi_params = {
+	.ena_maxi = true,
+	.chg_curr = 910,
+	.wait_cycles = 10,
+	.charger_curr_step = 100,
+};
+
+static const struct abx500_bm_charger_parameters chg = {
+	.usb_volt_max		= 5500,
+	.usb_curr_max		= 1500,
+	.ac_volt_max		= 7500,
+	.ac_curr_max		= 1500,
+};
+
+struct abx500_bm_data ab8500_bm_data = {
+	.temp_under		= 3,
+	.temp_low		= 8,
+	.temp_high		= 43,
+	.temp_over		= 48,
+	.main_safety_tmr_h	= 4,
+	.temp_interval_chg	= 20,
+	.temp_interval_nochg	= 120,
+	.usb_safety_tmr_h	= 4,
+	.bkup_bat_v		= BUP_VCH_SEL_2P6V,
+	.bkup_bat_i		= BUP_ICH_SEL_150UA,
+	.no_maintenance		= false,
+	.adc_therm		= ABx500_ADC_THERM_BATCTRL,
+	.chg_unknown_bat	= false,
+	.enable_overshoot	= false,
+	.fg_res			= 100,
+	.cap_levels		= &cap_levels,
+	.bat_type		= bat_type_thermistor,
+	.n_btypes		= 3,
+	.batt_id		= 0,
+	.interval_charging	= 5,
+	.interval_not_charging	= 120,
+	.temp_hysteresis	= 3,
+	.gnd_lift_resistance	= 34,
+	.maxi			= &maxi_params,
+	.chg_params		= &chg,
+	.fg_params		= &fg,
+};
+
+int __devinit
+bmdevs_of_probe(struct device *dev,
+		struct device_node *np,
+		struct abx500_bm_data **battery)
+{
+	struct	abx500_battery_type *btype;
+	struct  device_node *np_bat_supply;
+	struct	abx500_bm_data *bat;
+	const char *btech;
+	char bat_tech[8];
+	int i, thermistor;
+
+	*battery = &ab8500_bm_data;
+
+	/* get phandle to 'battery-info' node */
+	np_bat_supply = of_parse_phandle(np, "battery", 0);
+	if (!np_bat_supply) {
+		dev_err(dev, "missing property battery\n");
+		return -EINVAL;
+	}
+	if (of_property_read_bool(np_bat_supply,
+			"thermistor-on-batctrl"))
+		thermistor = NTC_INTERNAL;
+	else
+		thermistor = NTC_EXTERNAL;
+
+	bat = *battery;
+	if (thermistor == NTC_EXTERNAL) {
+		bat->n_btypes  = 4;
+		bat->bat_type  = bat_type_ext_thermistor;
+		bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
+	}
+	btech = of_get_property(np_bat_supply,
+		"stericsson,battery-type", NULL);
+	if (!btech) {
+		dev_warn(dev, "missing property battery-name/type\n");
+		strcpy(bat_tech, "UNKNOWN");
+	} else {
+		strcpy(bat_tech, btech);
+	}
+
+	if (strncmp(bat_tech, "LION", 4) == 0) {
+		bat->no_maintenance  = true;
+		bat->chg_unknown_bat = true;
+		bat->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600;
+		bat->bat_type[BATTERY_UNKNOWN].termination_vol    = 4150;
+		bat->bat_type[BATTERY_UNKNOWN].recharge_vol	  = 4130;
+		bat->bat_type[BATTERY_UNKNOWN].normal_cur_lvl	  = 520;
+		bat->bat_type[BATTERY_UNKNOWN].normal_vol_lvl	  = 4200;
+	}
+	/* select the battery resolution table */
+	for (i = 0; i < bat->n_btypes; ++i) {
+		btype = (bat->bat_type + i);
+		if (thermistor == NTC_EXTERNAL) {
+			btype->batres_tbl =
+				temp_to_batres_tbl_ext_thermistor;
+		} else if (strncmp(bat_tech, "LION", 4) == 0) {
+			btype->batres_tbl =
+				temp_to_batres_tbl_9100;
+		} else {
+			btype->batres_tbl =
+				temp_to_batres_tbl_thermistor;
+		}
+	}
+	of_node_put(np_bat_supply);
+	return 0;
+}
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
index bba3cca..803870e 100644
--- a/drivers/power/ab8500_btemp.c
+++ b/drivers/power/ab8500_btemp.c
@@ -93,7 +93,7 @@ struct ab8500_btemp {
 	struct ab8500 *parent;
 	struct ab8500_gpadc *gpadc;
 	struct ab8500_fg *fg;
-	struct abx500_btemp_platform_data *pdata;
+	struct abx500_bmdevs_plat_data *pdata;
 	struct abx500_bm_data *bat;
 	struct power_supply btemp_psy;
 	struct ab8500_btemp_events events;
@@ -962,10 +962,10 @@ static int __devexit ab8500_btemp_remove(struct platform_device *pdev)
 
 static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
 {
+	struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
+	struct ab8500_btemp *di;
 	int irq, i, ret = 0;
 	u8 val;
-	struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
-	struct ab8500_btemp *di;
 
 	if (!plat_data) {
 		dev_err(&pdev->dev, "No platform data\n");
@@ -982,21 +982,13 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
 	di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
 
 	/* get btemp specific platform data */
-	di->pdata = plat_data->btemp;
+	di->pdata = plat_data;
 	if (!di->pdata) {
 		dev_err(di->dev, "no btemp platform data supplied\n");
 		ret = -EINVAL;
 		goto free_device_info;
 	}
 
-	/* get battery specific platform data */
-	di->bat = plat_data->battery;
-	if (!di->bat) {
-		dev_err(di->dev, "no battery platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
 	/* BTEMP supply */
 	di->btemp_psy.name = "ab8500_btemp";
 	di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY;
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index d4f0c98..78a730c 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -220,7 +220,7 @@ struct ab8500_charger {
 	bool autopower;
 	struct ab8500 *parent;
 	struct ab8500_gpadc *gpadc;
-	struct abx500_charger_platform_data *pdata;
+	struct abx500_bmdevs_plat_data *pdata;
 	struct abx500_bm_data *bat;
 	struct ab8500_charger_event_flags flags;
 	struct ab8500_charger_usb_state usb_state;
@@ -2533,9 +2533,9 @@ static int __devexit ab8500_charger_remove(struct platform_device *pdev)
 
 static int __devinit ab8500_charger_probe(struct platform_device *pdev)
 {
-	int irq, i, charger_status, ret = 0;
-	struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
+	struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
 	struct ab8500_charger *di;
+	int irq, i, charger_status, ret = 0;
 
 	if (!plat_data) {
 		dev_err(&pdev->dev, "No platform data\n");
@@ -2555,21 +2555,13 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
 	spin_lock_init(&di->usb_state.usb_lock);
 
 	/* get charger specific platform data */
-	di->pdata = plat_data->charger;
+	di->pdata = plat_data;
 	if (!di->pdata) {
 		dev_err(di->dev, "no charger platform data supplied\n");
 		ret = -EINVAL;
 		goto free_device_info;
 	}
 
-	/* get battery specific platform data */
-	di->bat = plat_data->battery;
-	if (!di->bat) {
-		dev_err(di->dev, "no battery platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
 	di->autopower = false;
 
 	/* AC supply */
diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
index bf02225..3207154 100644
--- a/drivers/power/ab8500_fg.c
+++ b/drivers/power/ab8500_fg.c
@@ -22,15 +22,16 @@
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
 #include <linux/kobject.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include <linux/mfd/abx500.h>
 #include <linux/slab.h>
-#include <linux/mfd/abx500/ab8500-bm.h>
 #include <linux/delay.h>
-#include <linux/mfd/abx500/ab8500-gpadc.h>
-#include <linux/mfd/abx500.h>
 #include <linux/time.h>
+#include <linux/of.h>
 #include <linux/completion.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-bm.h>
+#include <linux/mfd/abx500/ab8500-gpadc.h>
 
 #define MILLI_TO_MICRO			1000
 #define FG_LSB_IN_MA			1627
@@ -172,7 +173,6 @@ struct inst_curr_result_list {
  * @avg_cap:		Average capacity filter
  * @parent:		Pointer to the struct ab8500
  * @gpadc:		Pointer to the struct gpadc
- * @pdata:		Pointer to the abx500_fg platform data
  * @bat:		Pointer to the abx500_bm platform data
  * @fg_psy:		Structure that holds the FG specific battery properties
  * @fg_wq:		Work queue for running the FG algorithm
@@ -212,7 +212,6 @@ struct ab8500_fg {
 	struct ab8500_fg_avg_cap avg_cap;
 	struct ab8500 *parent;
 	struct ab8500_gpadc *gpadc;
-	struct abx500_fg_platform_data *pdata;
 	struct abx500_bm_data *bat;
 	struct power_supply fg_psy;
 	struct workqueue_struct *fg_wq;
@@ -2429,7 +2428,6 @@ static int __devexit ab8500_fg_remove(struct platform_device *pdev)
 	flush_scheduled_work();
 	power_supply_unregister(&di->fg_psy);
 	platform_set_drvdata(pdev, NULL);
-	kfree(di);
 	return ret;
 }
 
@@ -2442,21 +2440,39 @@ static struct ab8500_fg_interrupts ab8500_fg_irq[] = {
 	{"CCEOC", ab8500_fg_cc_data_end_handler},
 };
 
+static char *supply_interface[] = {
+	"ab8500_chargalg",
+	"ab8500_usb",
+};
+
 static int __devinit ab8500_fg_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
+	struct ab8500_fg *di;
 	int i, irq;
 	int ret = 0;
-	struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
-	struct ab8500_fg *di;
-
-	if (!plat_data) {
-		dev_err(&pdev->dev, "No platform data\n");
-		return -EINVAL;
-	}
 
-	di = kzalloc(sizeof(*di), GFP_KERNEL);
-	if (!di)
+	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+	if (!di) {
+		dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__);
 		return -ENOMEM;
+	}
+	di->bat = pdev->mfd_cell->platform_data;
+	if (!di->bat) {
+		if (np) {
+			ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"failed to get battery information\n");
+				return ret;
+			}
+		} else {
+			dev_err(&pdev->dev, "missing dt node for ab8500_fg\n");
+			return -EINVAL;
+		}
+	} else {
+		dev_info(&pdev->dev, "falling back to legacy platform data\n");
+	}
 
 	mutex_init(&di->cc_lock);
 
@@ -2465,29 +2481,13 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
 	di->parent = dev_get_drvdata(pdev->dev.parent);
 	di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
 
-	/* get fg specific platform data */
-	di->pdata = plat_data->fg;
-	if (!di->pdata) {
-		dev_err(di->dev, "no fg platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
-	/* get battery specific platform data */
-	di->bat = plat_data->battery;
-	if (!di->bat) {
-		dev_err(di->dev, "no battery platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
 	di->fg_psy.name = "ab8500_fg";
 	di->fg_psy.type = POWER_SUPPLY_TYPE_BATTERY;
 	di->fg_psy.properties = ab8500_fg_props;
 	di->fg_psy.num_properties = ARRAY_SIZE(ab8500_fg_props);
 	di->fg_psy.get_property = ab8500_fg_get_property;
-	di->fg_psy.supplied_to = di->pdata->supplied_to;
-	di->fg_psy.num_supplicants = di->pdata->num_supplicants;
+	di->fg_psy.supplied_to = supply_interface;
+	di->fg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
 	di->fg_psy.external_power_changed = ab8500_fg_external_power_changed;
 
 	di->bat_cap.max_mah_design = MILLI_TO_MICRO *
@@ -2506,7 +2506,7 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
 	di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq");
 	if (di->fg_wq == NULL) {
 		dev_err(di->dev, "failed to create work queue\n");
-		goto free_device_info;
+		return -ENOMEM;
 	}
 
 	/* Init work for running the fg algorithm instantly */
@@ -2605,12 +2605,14 @@ free_irq:
 	}
 free_inst_curr_wq:
 	destroy_workqueue(di->fg_wq);
-free_device_info:
-	kfree(di);
-
 	return ret;
 }
 
+static const struct of_device_id ab8500_fg_match[] = {
+	{ .compatible = "stericsson,ab8500-fg", },
+	{ },
+};
+
 static struct platform_driver ab8500_fg_driver = {
 	.probe = ab8500_fg_probe,
 	.remove = __devexit_p(ab8500_fg_remove),
@@ -2619,6 +2621,7 @@ static struct platform_driver ab8500_fg_driver = {
 	.driver = {
 		.name = "ab8500-fg",
 		.owner = THIS_MODULE,
+		.of_match_table = ab8500_fg_match,
 	},
 };
 
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
index 804b88c..88b5cc1 100644
--- a/drivers/power/abx500_chargalg.c
+++ b/drivers/power/abx500_chargalg.c
@@ -231,7 +231,7 @@ struct abx500_chargalg {
 	struct abx500_chargalg_charger_info chg_info;
 	struct abx500_chargalg_battery_data batt_data;
 	struct abx500_chargalg_suspension_status susp_status;
-	struct abx500_chargalg_platform_data *pdata;
+	struct abx500_bmdevs_plat_data *pdata;
 	struct abx500_bm_data *bat;
 	struct power_supply chargalg_psy;
 	struct ux500_charger *ac_chg;
@@ -1802,7 +1802,7 @@ static int __devexit abx500_chargalg_remove(struct platform_device *pdev)
 
 static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
 {
-	struct abx500_bm_plat_data *plat_data;
+	struct abx500_bmdevs_plat_data *plat_data;
 	int ret = 0;
 
 	struct abx500_chargalg *di =
@@ -1812,10 +1812,8 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
 
 	/* get device struct */
 	di->dev = &pdev->dev;
-
 	plat_data = pdev->dev.platform_data;
-	di->pdata = plat_data->chargalg;
-	di->bat = plat_data->battery;
+	di->pdata = plat_data;
 
 	/* chargalg supply */
 	di->chargalg_psy.name = "abx500_chargalg";
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index 1318ca6..bbf3ad6 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -382,39 +382,27 @@ struct abx500_bm_data {
 	int gnd_lift_resistance;
 	const struct abx500_maxim_parameters *maxi;
 	const struct abx500_bm_capacity_levels *cap_levels;
-	const struct abx500_battery_type *bat_type;
+	struct abx500_battery_type *bat_type;
 	const struct abx500_bm_charger_parameters *chg_params;
 	const struct abx500_fg_parameters *fg_params;
 };
 
-struct abx500_chargalg_platform_data {
-	char **supplied_to;
-	size_t num_supplicants;
-};
-
-struct abx500_charger_platform_data {
-	char **supplied_to;
-	size_t num_supplicants;
-	bool autopower_cfg;
-};
+extern struct abx500_bm_data ab8500_bm_data;
 
-struct abx500_btemp_platform_data {
-	char **supplied_to;
-	size_t num_supplicants;
+struct abx500_bmdevs_plat_data {
+	char	**supplied_to;
+	size_t	num_supplicants;
+	bool	autopower_cfg;
 };
 
-struct abx500_fg_platform_data {
-	char **supplied_to;
-	size_t num_supplicants;
+enum {
+	NTC_EXTERNAL = 0,
+	NTC_INTERNAL,
 };
 
-struct abx500_bm_plat_data {
-	struct abx500_bm_data *battery;
-	struct abx500_charger_platform_data *charger;
-	struct abx500_btemp_platform_data *btemp;
-	struct abx500_fg_platform_data *fg;
-	struct abx500_chargalg_platform_data *chargalg;
-};
+int bmdevs_of_probe(struct device *dev,
+		struct device_node *np,
+		struct abx500_bm_data **battery);
 
 int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
 	u8 value);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/4] mfd: ab8500: add devicetree support for btemp
  2012-10-31 15:40 [PATCH 0/4] Implement device tree support for ab8500 BM Devices Rajanikanth H.V
  2012-10-31 15:40 ` [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge Rajanikanth H.V
@ 2012-10-31 15:40 ` Rajanikanth H.V
  2012-10-31 15:40 ` [PATCH 3/4] mfd: ab8500: add devicetree support for charger Rajanikanth H.V
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 23+ messages in thread
From: Rajanikanth H.V @ 2012-10-31 15:40 UTC (permalink / raw)
  To: rob.herring, lee.jones, francescolavra.fl
  Cc: arnd, anton.vorontsov, linus.walleij, linux-arm-kernel,
	linux-kernel, linaro-dev, patches, STEricsson_nomadik_linux,
	rajanikanth.hv

From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>

This patch adds device tree support for
battery-temperature-monitor driver

Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
---
 Documentation/devicetree/bindings/mfd/ab8500.txt   |    6 ++
 .../bindings/power_supply/ab8500/btemp.txt         |   16 +++++
 arch/arm/boot/dts/dbx5x0.dtsi                      |    5 ++
 drivers/mfd/ab8500-core.c                          |    5 ++
 drivers/power/Kconfig                              |    6 --
 drivers/power/ab8500_bmdata.c                      |    4 +-
 drivers/power/ab8500_btemp.c                       |   66 ++++++++++++--------
 7 files changed, 73 insertions(+), 35 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt

diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
index 6ca8d81..f2ee0e7 100644
--- a/Documentation/devicetree/bindings/mfd/ab8500.txt
+++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
@@ -30,6 +30,12 @@ ab8500-fg                : 			: vddadc       : Fuel Gauge
 			 : LOW_BAT_F		:	       : LOW threshold battery voltage
 			 : CC_INT_CALIB		:	       : Coulomb Counter Internal Calibration
 			 : CCEOC		:	       : Coulomb Counter End of Conversion
+ab8500-btemp		 :			: vtvout       : Battery Temperature
+			 : BAT_CTRL_INDB        :              : Battery Removal Indicator
+			 : BTEMP_LOW            :              : Btemp < BtempLow, if battery temperature is lower than -10°C
+			 : BTEMP_LOW_MEDIUM     :              : BtempLow < Btemp < BtempMedium,if battery temperature is between -10 and 0°C
+			 : BTEMP_MEDIUM_HIGH    :	       : BtempMedium < Btemp < BtempHigh,if battery temperature is between 0°C and“MaxTemp
+			 : BTEMP_HIGH           :              : Btemp > BtempHigh, if battery temperature is higher than “MaxTemp
 ab8500-gpadc             : HW_CONV_END          : vddadc       : Analogue to Digital Converter
                            SW_CONV_END          :              :
 ab8500-gpio              :                      :              : GPIO Controller
diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt b/Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt
new file mode 100644
index 0000000..0ba1bcc
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/ab8500/btemp.txt
@@ -0,0 +1,16 @@
+=== AB8500 Battery Temperature Monitor Driver ===
+
+The properties below describes the node for btemp driver.
+
+Required Properties:
+- compatible = Shall be: "stericsson,ab8500-btemp"
+- battery = Shall be battery specific information
+
+	Example:
+	ab8500_btemp {
+		compatible = "stericsson,ab8500-btemp";
+		battery	   = <&ab8500_battery>;
+	};
+
+For information on battery specific node, Ref:
+Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 68317f5..79fdee4 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -362,6 +362,11 @@
 					battery	   = <&ab8500_battery>;
 				};
 
+				ab8500_btemp {
+					compatible = "stericsson,ab8500-btemp";
+					battery	   = <&ab8500_battery>;
+				};
+
 				ab8500_usb {
 					compatible = "stericsson,ab8500-usb";
 					interrupts = < 90 0x4
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 7c3017b..94d45be 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1046,8 +1046,13 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
 	},
 	{
 		.name = "ab8500-btemp",
+		.of_compatible = "stericsson,ab8500-btemp",
 		.num_resources = ARRAY_SIZE(ab8500_btemp_resources),
 		.resources = ab8500_btemp_resources,
+#ifndef CONFIG_OF
+		.platform_data = &ab8500_bm_data,
+		.pdata_size = sizeof(ab8500_bm_data),
+#endif
 	},
 	{
 		.name = "ab8500-fg",
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index c1892f3..1434871 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -304,12 +304,6 @@ config AB8500_BM
 	help
 	  Say Y to include support for AB8500 battery management.
 
-config AB8500_BATTERY_THERM_ON_BATCTRL
-	bool "Thermistor connected on BATCTRL ADC"
-	depends on AB8500_BM
-	help
-	  Say Y to enable battery temperature measurements using
-	  thermistor connected on BATCTRL ADC.
 endif # POWER_SUPPLY
 
 source "drivers/power/avs/Kconfig"
diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c
index fa6ea52..1e3a0e3 100644
--- a/drivers/power/ab8500_bmdata.c
+++ b/drivers/power/ab8500_bmdata.c
@@ -29,7 +29,7 @@ static struct abx500_res_to_temp temp_tbl_A_thermistor[] = {
 	{65, 12500},
 };
 static struct abx500_res_to_temp temp_tbl_B_thermistor[] = {
-	{-5, 165418},
+	{-5, 200000},
 	{ 0, 159024},
 	{ 5, 151921},
 	{10, 144300},
@@ -237,7 +237,7 @@ struct abx500_battery_type bat_type_thermistor[] = {
 },
 {
 	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
-	.resis_high = 165418,
+	.resis_high = 200000,
 	.resis_low = 82869,
 	.battery_resistance = 300,
 	.charge_full_design = 900,
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
index 803870e..a6633b4 100644
--- a/drivers/power/ab8500_btemp.c
+++ b/drivers/power/ab8500_btemp.c
@@ -20,11 +20,13 @@
 #include <linux/power_supply.h>
 #include <linux/completion.h>
 #include <linux/workqueue.h>
-#include <linux/mfd/abx500/ab8500.h>
+#include <linux/jiffies.h>
+#include <linux/of.h>
+#include <linux/mfd/core.h>
 #include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
 #include <linux/mfd/abx500/ab8500-bm.h>
 #include <linux/mfd/abx500/ab8500-gpadc.h>
-#include <linux/jiffies.h>
 
 #define VTVOUT_V			1800
 
@@ -76,7 +78,6 @@ struct ab8500_btemp_ranges {
  * @parent:		Pointer to the struct ab8500
  * @gpadc:		Pointer to the struct gpadc
  * @fg:			Pointer to the struct fg
- * @pdata:		Pointer to the abx500_btemp platform data
  * @bat:		Pointer to the abx500_bm platform data
  * @btemp_psy:		Structure for BTEMP specific battery properties
  * @events:		Structure for information about events triggered
@@ -93,7 +94,6 @@ struct ab8500_btemp {
 	struct ab8500 *parent;
 	struct ab8500_gpadc *gpadc;
 	struct ab8500_fg *fg;
-	struct abx500_bmdevs_plat_data *pdata;
 	struct abx500_bm_data *bat;
 	struct power_supply btemp_psy;
 	struct ab8500_btemp_events events;
@@ -955,48 +955,57 @@ static int __devexit ab8500_btemp_remove(struct platform_device *pdev)
 	flush_scheduled_work();
 	power_supply_unregister(&di->btemp_psy);
 	platform_set_drvdata(pdev, NULL);
-	kfree(di);
 
 	return 0;
 }
 
+static char *supply_interface[] = {
+	"ab8500_chargalg",
+	"ab8500_fg",
+};
+
 static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
 {
-	struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
+	struct device_node *np = pdev->dev.of_node;
 	struct ab8500_btemp *di;
 	int irq, i, ret = 0;
 	u8 val;
 
-	if (!plat_data) {
-		dev_err(&pdev->dev, "No platform data\n");
-		return -EINVAL;
-	}
-
-	di = kzalloc(sizeof(*di), GFP_KERNEL);
-	if (!di)
+	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+	if (!di) {
+		dev_err(&pdev->dev, "%s no mem for ab8500_btemp\n", __func__);
 		return -ENOMEM;
+	}
+	di->bat = pdev->mfd_cell->platform_data;
+	if (!di->bat) {
+		if (np) {
+			ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"failed to get battery information\n");
+				return ret;
+			}
+		} else {
+			dev_err(&pdev->dev, "missing dt node for ab8500_btemp\n");
+			return -EINVAL;
+		}
+	} else {
+		dev_info(&pdev->dev, "falling back to legacy platform data\n");
+	}
 
 	/* get parent data */
 	di->dev = &pdev->dev;
 	di->parent = dev_get_drvdata(pdev->dev.parent);
 	di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
 
-	/* get btemp specific platform data */
-	di->pdata = plat_data;
-	if (!di->pdata) {
-		dev_err(di->dev, "no btemp platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
 	/* BTEMP supply */
 	di->btemp_psy.name = "ab8500_btemp";
 	di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY;
 	di->btemp_psy.properties = ab8500_btemp_props;
 	di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props);
 	di->btemp_psy.get_property = ab8500_btemp_get_property;
-	di->btemp_psy.supplied_to = di->pdata->supplied_to;
-	di->btemp_psy.num_supplicants = di->pdata->num_supplicants;
+	di->btemp_psy.supplied_to = supply_interface;
+	di->btemp_psy.num_supplicants = ARRAY_SIZE(supply_interface);
 	di->btemp_psy.external_power_changed =
 		ab8500_btemp_external_power_changed;
 
@@ -1006,7 +1015,7 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
 		create_singlethread_workqueue("ab8500_btemp_wq");
 	if (di->btemp_wq == NULL) {
 		dev_err(di->dev, "failed to create work queue\n");
-		goto free_device_info;
+		return -ENOMEM;
 	}
 
 	/* Init work for measuring temperature periodically */
@@ -1084,12 +1093,14 @@ free_irq:
 	}
 free_btemp_wq:
 	destroy_workqueue(di->btemp_wq);
-free_device_info:
-	kfree(di);
-
 	return ret;
 }
 
+static const struct of_device_id ab8500_btemp_match[] = {
+	{ .compatible = "stericsson,ab8500-btemp", },
+	{ },
+};
+
 static struct platform_driver ab8500_btemp_driver = {
 	.probe = ab8500_btemp_probe,
 	.remove = __devexit_p(ab8500_btemp_remove),
@@ -1098,6 +1109,7 @@ static struct platform_driver ab8500_btemp_driver = {
 	.driver = {
 		.name = "ab8500-btemp",
 		.owner = THIS_MODULE,
+		.of_match_table = ab8500_btemp_match,
 	},
 };
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 3/4] mfd: ab8500: add devicetree support for charger
  2012-10-31 15:40 [PATCH 0/4] Implement device tree support for ab8500 BM Devices Rajanikanth H.V
  2012-10-31 15:40 ` [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge Rajanikanth H.V
  2012-10-31 15:40 ` [PATCH 2/4] mfd: ab8500: add devicetree support for btemp Rajanikanth H.V
@ 2012-10-31 15:40 ` Rajanikanth H.V
  2012-10-31 15:40 ` [PATCH 4/4] mfd: ab8500: add devicetree support for chargalg Rajanikanth H.V
  2012-11-19  3:46 ` [PATCH 0/4] Implement device tree support for ab8500 BM Devices Anton Vorontsov
  4 siblings, 0 replies; 23+ messages in thread
From: Rajanikanth H.V @ 2012-10-31 15:40 UTC (permalink / raw)
  To: rob.herring, lee.jones, francescolavra.fl
  Cc: arnd, anton.vorontsov, linus.walleij, linux-arm-kernel,
	linux-kernel, linaro-dev, patches, STEricsson_nomadik_linux,
	rajanikanth.hv

From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>

This patch adds device tree support for ab8500-charger
driver

Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
---
 Documentation/devicetree/bindings/mfd/ab8500.txt   |   14 ++++
 .../bindings/power_supply/ab8500/charger.txt       |   25 +++++++
 arch/arm/boot/dts/dbx5x0.dtsi                      |    6 ++
 drivers/mfd/ab8500-core.c                          |    5 ++
 drivers/power/ab8500_charger.c                     |   73 ++++++++++++--------
 5 files changed, 95 insertions(+), 28 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/charger.txt

diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
index f2ee0e7..13b707b 100644
--- a/Documentation/devicetree/bindings/mfd/ab8500.txt
+++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
@@ -36,6 +36,20 @@ ab8500-btemp		 :			: vtvout       : Battery Temperature
 			 : BTEMP_LOW_MEDIUM     :              : BtempLow < Btemp < BtempMedium,if battery temperature is between -10 and 0°C
 			 : BTEMP_MEDIUM_HIGH    :	       : BtempMedium < Btemp < BtempHigh,if battery temperature is between 0°C and“MaxTemp
 			 : BTEMP_HIGH           :              : Btemp > BtempHigh, if battery temperature is higher than “MaxTemp
+ab8500-charger		 :			: vddadc       : Charger interface
+			 : MAIN_CH_UNPLUG_DET	:	       : main charger unplug detection management (not in 8505)
+			 : MAIN_CHARGE_PLUG_DET	:	       : main charger plug detection management (not in 8505)
+			 : MAIN_EXT_CH_NOT_OK	:	       : main charger not OK
+			 : MAIN_CH_TH_PROT_R	:	       : Die temp is above main charger
+			 : MAIN_CH_TH_PROT_F	:	       : Die temp is below main charger
+			 : VBUS_DET_F		:	       : VBUS falling detected
+			 : VBUS_DET_R		:	       : VBUS rising detected
+			 : USB_LINK_STATUS	:	       : USB link status has changed
+			 : USB_CH_TH_PROT_R	:	       : Die temp is above usb charger
+			 : USB_CH_TH_PROT_F	:	       : Die temp is below usb charger
+			 : USB_CHARGER_NOT_OKR	:	       : allowed USB charger not ok detection
+			 : VBUS_OVV		:	       : Overvoltage on Vbus ball detected (USB charge is stopped)
+			 : CH_WD_EXP		:	       : Charger watchdog detected
 ab8500-gpadc             : HW_CONV_END          : vddadc       : Analogue to Digital Converter
                            SW_CONV_END          :              :
 ab8500-gpio              :                      :              : GPIO Controller
diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/charger.txt b/Documentation/devicetree/bindings/power_supply/ab8500/charger.txt
new file mode 100644
index 0000000..6bdbb08
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/ab8500/charger.txt
@@ -0,0 +1,25 @@
+=== AB8500 Charger Driver ===
+
+Required Properties:
+- compatible = Shall be "stericsson,ab8500-charger"
+- battery = Shall be battery specific information
+	Example:
+	ab8500_charger {
+		compatible = "stericsson,ab8500-charger";
+		battery	   = <&ab8500_battery>;
+	};
+
+- vddadc-supply: Supply for USB and Main charger
+	Example:
+	ab8500-charger {
+		vddadc-supply	= <&ab8500_ldo_tvout_reg>;
+	}
+- autopower_cfg:
+	Boolean value depicting the presence of 'automatic poweron after powerloss'
+	Example:
+	ab8500-charger {
+		autopower_cfg;
+	};
+
+For information on battery specific node, Ref:
+Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 79fdee4..b1ecb5d 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -367,6 +367,12 @@
 					battery	   = <&ab8500_battery>;
 				};
 
+				ab8500_charger {
+					compatible	= "stericsson,ab8500-charger";
+					battery		= <&ab8500_battery>;
+					vddadc-supply	= <&ab8500_ldo_tvout_reg>;
+				};
+
 				ab8500_usb {
 					compatible = "stericsson,ab8500-usb";
 					interrupts = < 90 0x4
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 94d45be..c7a120b 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1041,8 +1041,13 @@ static struct mfd_cell __devinitdata abx500_common_devs[] = {
 static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
 	{
 		.name = "ab8500-charger",
+		.of_compatible = "stericsson,ab8500-charger",
 		.num_resources = ARRAY_SIZE(ab8500_charger_resources),
 		.resources = ab8500_charger_resources,
+#ifndef CONFIG_OF
+		.platform_data = &ab8500_bm_data,
+		.pdata_size = sizeof(ab8500_bm_data),
+#endif
 	},
 	{
 		.name = "ab8500-btemp",
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index 78a730c..a140564 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -23,6 +23,8 @@
 #include <linux/err.h>
 #include <linux/workqueue.h>
 #include <linux/kobject.h>
+#include <linux/of.h>
+#include <linux/mfd/core.h>
 #include <linux/mfd/abx500/ab8500.h>
 #include <linux/mfd/abx500.h>
 #include <linux/mfd/abx500/ab8500-bm.h>
@@ -181,9 +183,9 @@ struct ab8500_charger_usb_state {
  * @vbat		Battery voltage
  * @old_vbat		Previously measured battery voltage
  * @autopower		Indicate if we should have automatic pwron after pwrloss
+ * @autopower_cfg	platform specific power config support for "pwron after pwrloss"
  * @parent:		Pointer to the struct ab8500
  * @gpadc:		Pointer to the struct gpadc
- * @pdata:		Pointer to the abx500_charger platform data
  * @bat:		Pointer to the abx500_bm platform data
  * @flags:		Structure for information about events triggered
  * @usb_state:		Structure for usb stack information
@@ -218,9 +220,9 @@ struct ab8500_charger {
 	int vbat;
 	int old_vbat;
 	bool autopower;
+	bool autopower_cfg;
 	struct ab8500 *parent;
 	struct ab8500_gpadc *gpadc;
-	struct abx500_bmdevs_plat_data *pdata;
 	struct abx500_bm_data *bat;
 	struct ab8500_charger_event_flags flags;
 	struct ab8500_charger_usb_state usb_state;
@@ -322,7 +324,7 @@ static void ab8500_power_loss_handling(struct ab8500_charger *di)
 static void ab8500_power_supply_changed(struct ab8500_charger *di,
 					struct power_supply *psy)
 {
-	if (di->pdata->autopower_cfg) {
+	if (di->autopower_cfg) {
 		if (!di->usb.charger_connected &&
 		    !di->ac.charger_connected &&
 		    di->autopower) {
@@ -2526,25 +2528,45 @@ static int __devexit ab8500_charger_remove(struct platform_device *pdev)
 	power_supply_unregister(&di->usb_chg.psy);
 	power_supply_unregister(&di->ac_chg.psy);
 	platform_set_drvdata(pdev, NULL);
-	kfree(di);
 
 	return 0;
 }
 
+static char *supply_interface[] = {
+	"ab8500_chargalg",
+	"ab8500_fg",
+	"ab8500_btemp",
+};
+
 static int __devinit ab8500_charger_probe(struct platform_device *pdev)
 {
-	struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
+	struct device_node *np = pdev->dev.of_node;
 	struct ab8500_charger *di;
 	int irq, i, charger_status, ret = 0;
 
-	if (!plat_data) {
-		dev_err(&pdev->dev, "No platform data\n");
-		return -EINVAL;
-	}
-
-	di = kzalloc(sizeof(*di), GFP_KERNEL);
-	if (!di)
+	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+	if (!di) {
+		dev_err(&pdev->dev, "%s no mem for ab8500_charger\n", __func__);
 		return -ENOMEM;
+	}
+	di->bat = pdev->mfd_cell->platform_data;
+	if (!di->bat) {
+		if (np) {
+			ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"failed to get battery information\n");
+				return ret;
+			}
+			di->autopower_cfg = of_property_read_bool(np, "autopower_cfg");
+		} else {
+			dev_err(&pdev->dev, "missing dt node for ab8500_charger\n");
+			return -EINVAL;
+		}
+	} else {
+		dev_info(&pdev->dev, "falling back to legacy platform data\n");
+		di->autopower_cfg = false;
+	}
 
 	/* get parent data */
 	di->dev = &pdev->dev;
@@ -2554,14 +2576,6 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
 	/* initialize lock */
 	spin_lock_init(&di->usb_state.usb_lock);
 
-	/* get charger specific platform data */
-	di->pdata = plat_data;
-	if (!di->pdata) {
-		dev_err(di->dev, "no charger platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
 	di->autopower = false;
 
 	/* AC supply */
@@ -2571,8 +2585,8 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
 	di->ac_chg.psy.properties = ab8500_charger_ac_props;
 	di->ac_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_ac_props);
 	di->ac_chg.psy.get_property = ab8500_charger_ac_get_property;
-	di->ac_chg.psy.supplied_to = di->pdata->supplied_to;
-	di->ac_chg.psy.num_supplicants = di->pdata->num_supplicants;
+	di->ac_chg.psy.supplied_to = supply_interface;
+	di->ac_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface),
 	/* ux500_charger sub-class */
 	di->ac_chg.ops.enable = &ab8500_charger_ac_en;
 	di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
@@ -2589,8 +2603,8 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
 	di->usb_chg.psy.properties = ab8500_charger_usb_props;
 	di->usb_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_usb_props);
 	di->usb_chg.psy.get_property = ab8500_charger_usb_get_property;
-	di->usb_chg.psy.supplied_to = di->pdata->supplied_to;
-	di->usb_chg.psy.num_supplicants = di->pdata->num_supplicants;
+	di->usb_chg.psy.supplied_to = supply_interface;
+	di->usb_chg.psy.num_supplicants = ARRAY_SIZE(supply_interface),
 	/* ux500_charger sub-class */
 	di->usb_chg.ops.enable = &ab8500_charger_usb_en;
 	di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick;
@@ -2606,7 +2620,7 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
 		create_singlethread_workqueue("ab8500_charger_wq");
 	if (di->charger_wq == NULL) {
 		dev_err(di->dev, "failed to create work queue\n");
-		goto free_device_info;
+		return -ENOMEM;
 	}
 
 	/* Init work for HW failure check */
@@ -2748,12 +2762,14 @@ free_regulator:
 	regulator_put(di->regu);
 free_charger_wq:
 	destroy_workqueue(di->charger_wq);
-free_device_info:
-	kfree(di);
-
 	return ret;
 }
 
+static const struct of_device_id ab8500_charger_match[] = {
+	{ .compatible = "stericsson,ab8500-charger", },
+	{ },
+};
+
 static struct platform_driver ab8500_charger_driver = {
 	.probe = ab8500_charger_probe,
 	.remove = __devexit_p(ab8500_charger_remove),
@@ -2762,6 +2778,7 @@ static struct platform_driver ab8500_charger_driver = {
 	.driver = {
 		.name = "ab8500-charger",
 		.owner = THIS_MODULE,
+		.of_match_table = ab8500_charger_match,
 	},
 };
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 4/4] mfd: ab8500: add devicetree support for chargalg
  2012-10-31 15:40 [PATCH 0/4] Implement device tree support for ab8500 BM Devices Rajanikanth H.V
                   ` (2 preceding siblings ...)
  2012-10-31 15:40 ` [PATCH 3/4] mfd: ab8500: add devicetree support for charger Rajanikanth H.V
@ 2012-10-31 15:40 ` Rajanikanth H.V
  2012-11-19  3:46 ` [PATCH 0/4] Implement device tree support for ab8500 BM Devices Anton Vorontsov
  4 siblings, 0 replies; 23+ messages in thread
From: Rajanikanth H.V @ 2012-10-31 15:40 UTC (permalink / raw)
  To: rob.herring, lee.jones, francescolavra.fl
  Cc: arnd, anton.vorontsov, linus.walleij, linux-arm-kernel,
	linux-kernel, linaro-dev, patches, STEricsson_nomadik_linux,
	rajanikanth.hv

From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>

This patch adds device tree support for charging algorithm
driver

Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
---
 .../bindings/power_supply/ab8500/chargalg.txt      |   16 ++++++
 arch/arm/boot/dts/dbx5x0.dtsi                      |    5 ++
 drivers/mfd/ab8500-core.c                          |    5 ++
 drivers/power/abx500_chargalg.c                    |   54 ++++++++++++++------
 include/linux/mfd/abx500.h                         |    6 ---
 5 files changed, 64 insertions(+), 22 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt

diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt b/Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt
new file mode 100644
index 0000000..ef53283
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/ab8500/chargalg.txt
@@ -0,0 +1,16 @@
+=== AB8500 Charging Algorithm Driver ===
+
+The properties below describes the node for chargalg driver.
+
+Required Properties:
+- compatible = Shall be: "stericsson,ab8500-chargalg"
+- battery = Shall be battery specific information
+
+Example:
+ab8500_chargalg {
+	compatible = "stericsson,ab8500-chargalg";
+	battery	   = <&ab8500_battery>;
+};
+
+For information on battery specific node, Ref:
+Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index b1ecb5d..a678afa 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -373,6 +373,11 @@
 					vddadc-supply	= <&ab8500_ldo_tvout_reg>;
 				};
 
+				ab8500_chargalg {
+					compatible	= "stericsson,ab8500-chargalg";
+					battery		= <&ab8500_battery>;
+				};
+
 				ab8500_usb {
 					compatible = "stericsson,ab8500-usb";
 					interrupts = < 90 0x4
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index c7a120b..5ec70f2 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1071,8 +1071,13 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
 	},
 	{
 		.name = "ab8500-chargalg",
+		.of_compatible = "stericsson,ab8500-chargalg",
 		.num_resources = ARRAY_SIZE(ab8500_chargalg_resources),
 		.resources = ab8500_chargalg_resources,
+#ifndef CONFIG_OF
+		.platform_data = &ab8500_bm_data,
+		.pdata_size = sizeof(ab8500_bm_data),
+#endif
 	},
 };
 
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
index 88b5cc1..c603556 100644
--- a/drivers/power/abx500_chargalg.c
+++ b/drivers/power/abx500_chargalg.c
@@ -21,6 +21,8 @@
 #include <linux/completion.h>
 #include <linux/workqueue.h>
 #include <linux/kobject.h>
+#include <linux/of.h>
+#include <linux/mfd/core.h>
 #include <linux/mfd/abx500.h>
 #include <linux/mfd/abx500/ux500_chargalg.h>
 #include <linux/mfd/abx500/ab8500-bm.h>
@@ -205,7 +207,6 @@ enum maxim_ret {
  * @chg_info:		information about connected charger types
  * @batt_data:		data of the battery
  * @susp_status:	current charger suspension status
- * @pdata:		pointer to the abx500_chargalg platform data
  * @bat:		pointer to the abx500_bm platform data
  * @chargalg_psy:	structure that holds the battery properties exposed by
  *			the charging algorithm
@@ -231,7 +232,6 @@ struct abx500_chargalg {
 	struct abx500_chargalg_charger_info chg_info;
 	struct abx500_chargalg_battery_data batt_data;
 	struct abx500_chargalg_suspension_status susp_status;
-	struct abx500_bmdevs_plat_data *pdata;
 	struct abx500_bm_data *bat;
 	struct power_supply chargalg_psy;
 	struct ux500_charger *ac_chg;
@@ -1795,25 +1795,44 @@ static int __devexit abx500_chargalg_remove(struct platform_device *pdev)
 	flush_scheduled_work();
 	power_supply_unregister(&di->chargalg_psy);
 	platform_set_drvdata(pdev, NULL);
-	kfree(di);
 
 	return 0;
 }
 
+static char *supply_interface[] = {
+	"ab8500_fg",
+};
+
 static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
 {
-	struct abx500_bmdevs_plat_data *plat_data;
+	struct device_node *np = pdev->dev.of_node;
+	struct abx500_chargalg *di;
 	int ret = 0;
 
-	struct abx500_chargalg *di =
-		kzalloc(sizeof(struct abx500_chargalg), GFP_KERNEL);
-	if (!di)
+	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+	if (!di) {
+		dev_err(&pdev->dev, "%s no mem for ab8500_chargalg\n", __func__);
 		return -ENOMEM;
+	}
+	di->bat = pdev->mfd_cell->platform_data;
+	if (!di->bat) {
+		if (np) {
+			ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"failed to get battery information\n");
+				return ret;
+			}
+		} else {
+			dev_err(&pdev->dev, "missing dt node for ab8500_chargalg\n");
+			return -EINVAL;
+		}
+	} else {
+		dev_info(&pdev->dev, "falling back to legacy platform data\n");
+	}
 
 	/* get device struct */
 	di->dev = &pdev->dev;
-	plat_data = pdev->dev.platform_data;
-	di->pdata = plat_data;
 
 	/* chargalg supply */
 	di->chargalg_psy.name = "abx500_chargalg";
@@ -1821,8 +1840,8 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
 	di->chargalg_psy.properties = abx500_chargalg_props;
 	di->chargalg_psy.num_properties = ARRAY_SIZE(abx500_chargalg_props);
 	di->chargalg_psy.get_property = abx500_chargalg_get_property;
-	di->chargalg_psy.supplied_to = di->pdata->supplied_to;
-	di->chargalg_psy.num_supplicants = di->pdata->num_supplicants;
+	di->chargalg_psy.supplied_to = supply_interface;
+	di->chargalg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
 	di->chargalg_psy.external_power_changed =
 		abx500_chargalg_external_power_changed;
 
@@ -1842,7 +1861,7 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
 		create_singlethread_workqueue("abx500_chargalg_wq");
 	if (di->chargalg_wq == NULL) {
 		dev_err(di->dev, "failed to create work queue\n");
-		goto free_device_info;
+		return -ENOMEM;
 	}
 
 	/* Init work for chargalg */
@@ -1883,20 +1902,23 @@ free_psy:
 	power_supply_unregister(&di->chargalg_psy);
 free_chargalg_wq:
 	destroy_workqueue(di->chargalg_wq);
-free_device_info:
-	kfree(di);
-
 	return ret;
 }
 
+static const struct of_device_id ab8500_chargalg_match[] = {
+	{ .compatible = "stericsson,ab8500-chargalg", },
+	{ },
+};
+
 static struct platform_driver abx500_chargalg_driver = {
 	.probe = abx500_chargalg_probe,
 	.remove = __devexit_p(abx500_chargalg_remove),
 	.suspend = abx500_chargalg_suspend,
 	.resume = abx500_chargalg_resume,
 	.driver = {
-		.name = "abx500-chargalg",
+		.name = "ab8500-chargalg",
 		.owner = THIS_MODULE,
+		.of_match_table = ab8500_chargalg_match,
 	},
 };
 
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index bbf3ad6..a14c1a6 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -389,12 +389,6 @@ struct abx500_bm_data {
 
 extern struct abx500_bm_data ab8500_bm_data;
 
-struct abx500_bmdevs_plat_data {
-	char	**supplied_to;
-	size_t	num_supplicants;
-	bool	autopower_cfg;
-};
-
 enum {
 	NTC_EXTERNAL = 0,
 	NTC_INTERNAL,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-10-31 15:40 ` [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge Rajanikanth H.V
@ 2012-11-01 15:15   ` Francesco Lavra
  2012-11-07 18:45     ` Rajanikanth H V
  0 siblings, 1 reply; 23+ messages in thread
From: Francesco Lavra @ 2012-11-01 15:15 UTC (permalink / raw)
  To: Rajanikanth H.V
  Cc: rob.herring, lee.jones, arnd, anton.vorontsov, linus.walleij,
	linux-arm-kernel, linux-kernel, linaro-dev, patches,
	STEricsson_nomadik_linux, rajanikanth.hv

On 10/31/2012 04:40 PM, Rajanikanth H.V wrote:
> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
> 
> - This patch adds device tree support for fuelgauge driver
> - optimize bm devices platform_data usage and of_probe(...)
>   Note: of_probe() routine for battery managed devices is made
>   common across all bm drivers.
> - test status:
>   - interrupt numbers assigned differs between legacy and FDT mode.
> 
> Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
[...]
> +int __devinit
> +bmdevs_of_probe(struct device *dev,
> +		struct device_node *np,
> +		struct abx500_bm_data **battery)
> +{
> +	struct	abx500_battery_type *btype;
> +	struct  device_node *np_bat_supply;
> +	struct	abx500_bm_data *bat;
> +	const char *btech;
> +	char bat_tech[8];
> +	int i, thermistor;
> +
> +	*battery = &ab8500_bm_data;
> +
> +	/* get phandle to 'battery-info' node */
> +	np_bat_supply = of_parse_phandle(np, "battery", 0);
> +	if (!np_bat_supply) {
> +		dev_err(dev, "missing property battery\n");
> +		return -EINVAL;
> +	}
> +	if (of_property_read_bool(np_bat_supply,
> +			"thermistor-on-batctrl"))
> +		thermistor = NTC_INTERNAL;
> +	else
> +		thermistor = NTC_EXTERNAL;
> +
> +	bat = *battery;
> +	if (thermistor == NTC_EXTERNAL) {
> +		bat->n_btypes  = 4;
> +		bat->bat_type  = bat_type_ext_thermistor;
> +		bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
> +	}
> +	btech = of_get_property(np_bat_supply,
> +		"stericsson,battery-type", NULL);
> +	if (!btech) {
> +		dev_warn(dev, "missing property battery-name/type\n");
> +		strcpy(bat_tech, "UNKNOWN");
> +	} else {
> +		strcpy(bat_tech, btech);
> +	}

I don't get the point of declaring the char array and copying the string
in it, when you could simply use just the pointer returned by
of_get_property().
Anyway, if the string property is longer than 8 characters, you are
writing past the size of the destination array.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-11-01 15:15   ` Francesco Lavra
@ 2012-11-07 18:45     ` Rajanikanth H V
  2012-11-10 16:53       ` Francesco Lavra
  0 siblings, 1 reply; 23+ messages in thread
From: Rajanikanth H V @ 2012-11-07 18:45 UTC (permalink / raw)
  To: Francesco Lavra
  Cc: Rajanikanth H.V, rob.herring, lee.jones, arnd, anton.vorontsov,
	linus.walleij, linux-arm-kernel, linux-kernel, linaro-dev,
	patches, STEricsson_nomadik_linux, rajanikanth.hv

On Thu, 1 Nov 2012, Francesco Lavra wrote:
[...]
>> +	btech = of_get_property(np_bat_supply,
>> +		"stericsson,battery-type", NULL);
>> +	if (!btech) {
>> +		dev_warn(dev, "missing property battery-name/type\n");
>> +		strcpy(bat_tech, "UNKNOWN");
>> +	} else {
>> +		strcpy(bat_tech, btech);
>> +	}
>
> I don't get the point of declaring the char array and copying the string
> in it, when you could simply use just the pointer returned by
> of_get_property().

I am considering a corner case where in 'battery-type' property is not
present and battery is connected.In this case i promote battery to
UNKNOWN from null.
FYI: Further, btemp driver will identify the connected battery based on
resistance value and decide to use.
Ref: ab8500_btemp_id(...) ab8500_btemp.c

> Anyway, if the string property is longer than 8 characters, you are
> writing past the size of the destination array.

i believe it is safe as power_supply.h comprises defines having battery
technology type in 4 characters length which is normally the case and
7 chars length being "UNKNOWN" seldom referred


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-11-07 18:45     ` Rajanikanth H V
@ 2012-11-10 16:53       ` Francesco Lavra
  2012-11-15 11:34         ` Rajanikanth HV
  0 siblings, 1 reply; 23+ messages in thread
From: Francesco Lavra @ 2012-11-10 16:53 UTC (permalink / raw)
  To: Rajanikanth H V
  Cc: rob.herring, lee.jones, arnd, anton.vorontsov, linus.walleij,
	linux-arm-kernel, linux-kernel, linaro-dev, patches,
	STEricsson_nomadik_linux, rajanikanth.hv

On 11/07/2012 07:45 PM, Rajanikanth H V wrote:
> On Thu, 1 Nov 2012, Francesco Lavra wrote:
> [...]
>>> +    btech = of_get_property(np_bat_supply,
>>> +        "stericsson,battery-type", NULL);
>>> +    if (!btech) {
>>> +        dev_warn(dev, "missing property battery-name/type\n");
>>> +        strcpy(bat_tech, "UNKNOWN");
>>> +    } else {
>>> +        strcpy(bat_tech, btech);
>>> +    }
>>
>> I don't get the point of declaring the char array and copying the string
>> in it, when you could simply use just the pointer returned by
>> of_get_property().
> 
> I am considering a corner case where in 'battery-type' property is not
> present and battery is connected.In this case i promote battery to
> UNKNOWN from null.

You could achieve the same result without using the char array, with
this assignment:

btech = "UNKNOWN";

> FYI: Further, btemp driver will identify the connected battery based on
> resistance value and decide to use.
> Ref: ab8500_btemp_id(...) ab8500_btemp.c
> 
>> Anyway, if the string property is longer than 8 characters, you are
>> writing past the size of the destination array.
> 
> i believe it is safe as power_supply.h comprises defines having battery
> technology type in 4 characters length which is normally the case and
> 7 chars length being "UNKNOWN" seldom referred

You should be able to handle whatever the device tree contains, and if
it contains unexpected data this is not a good excuse for locking up the
system.

--
Francesco

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-11-10 16:53       ` Francesco Lavra
@ 2012-11-15 11:34         ` Rajanikanth HV
  0 siblings, 0 replies; 23+ messages in thread
From: Rajanikanth HV @ 2012-11-15 11:34 UTC (permalink / raw)
  To: Francesco Lavra
  Cc: Rajanikanth H V, rob.herring, lee.jones, arnd, anton.vorontsov,
	Linus WALLEIJ, linux-arm-kernel, linux-kernel, linaro-dev,
	patches, STEricsson_nomadik_linux



On Saturday 10 November 2012 10:23 PM, Francesco Lavra wrote:
>>> I don't get the point of declaring the char array and copying the string
>>> in it, when you could simply use just the pointer returned by
>>> of_get_property().
>>
>> I am considering a corner case where in 'battery-type' property is not
>> present and battery is connected.In this case i promote battery to
>> UNKNOWN from null.
> 
> You could achieve the same result without using the char array, with
> this assignment:
> 
> btech = "UNKNOWN";
> 
>> FYI: Further, btemp driver will identify the connected battery based on
>> resistance value and decide to use.
>> Ref: ab8500_btemp_id(...) ab8500_btemp.c
>>
>>> Anyway, if the string property is longer than 8 characters, you are
>>> writing past the size of the destination array.
>>
>> i believe it is safe as power_supply.h comprises defines having battery
>> technology type in 4 characters length which is normally the case and
>> 7 chars length being "UNKNOWN" seldom referred
> 
> You should be able to handle whatever the device tree contains, and if
> it contains unexpected data this is not a good excuse for locking up the
> system.
agreed, if we were to go by what device tree contains then explicit
assignment for battery type as "UNKNOWN" is not required, hence only 2
use case persist as :
a) property name with one of the said value be present
	(as per documentation)
b) property name not present

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] Implement device tree support for ab8500 BM Devices
  2012-10-31 15:40 [PATCH 0/4] Implement device tree support for ab8500 BM Devices Rajanikanth H.V
                   ` (3 preceding siblings ...)
  2012-10-31 15:40 ` [PATCH 4/4] mfd: ab8500: add devicetree support for chargalg Rajanikanth H.V
@ 2012-11-19  3:46 ` Anton Vorontsov
  2012-11-19  3:58   ` Rajanikanth HV
  4 siblings, 1 reply; 23+ messages in thread
From: Anton Vorontsov @ 2012-11-19  3:46 UTC (permalink / raw)
  To: Rajanikanth H.V
  Cc: rob.herring, lee.jones, francescolavra.fl, arnd, linus.walleij,
	linux-arm-kernel, linux-kernel, linaro-dev, patches,
	STEricsson_nomadik_linux, rajanikanth.hv, Samuel Ortiz

On Wed, Oct 31, 2012 at 03:40:29PM +0000, Rajanikanth H.V wrote:
> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
> 
> This patch-set adds device tree binding for ab8500 battery-managed
> devices. Removes the redundant platform structure maintained
> across bm devices and implements common DT probe routine across all the
> modules.

Thanks for the patches, Rajanikanth.

The mfd changes seemed very minor, so I impudently applied the patches to
the battery tree. :)

(But I'm bouncing the patches to Samuel and Mark anyway, jfyi.)

p.s.

FWIW, I fixed these warnings.

  CHECK   drivers/power/ab8500_bmdata.c
drivers/power/ab8500_bmdata.c:146:23: warning: symbol 'temp_to_batres_tbl_thermistor' was not declared. Should it be static?
drivers/power/ab8500_bmdata.c:160:23: warning: symbol 'temp_to_batres_tbl_ext_thermistor' was not declared. Should it be static?
drivers/power/ab8500_bmdata.c:171:23: warning: symbol 'temp_to_batres_tbl_9100' was not declared. Should it be static?
drivers/power/ab8500_bmdata.c:181:28: warning: symbol 'bat_type_thermistor' was not declared. Should it be static?
drivers/power/ab8500_bmdata.c:267:28: warning: symbol 'bat_type_ext_thermistor' was not declared. Should it be static?

Plus fixed a few stylistic issues.

Thanks,
Anton.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] Implement device tree support for ab8500 BM Devices
  2012-11-19  3:46 ` [PATCH 0/4] Implement device tree support for ab8500 BM Devices Anton Vorontsov
@ 2012-11-19  3:58   ` Rajanikanth HV
  2012-11-19  4:57     ` Anton Vorontsov
  0 siblings, 1 reply; 23+ messages in thread
From: Rajanikanth HV @ 2012-11-19  3:58 UTC (permalink / raw)
  To: Anton Vorontsov
  Cc: rob.herring, Lee Jones, Francesco Lavra, Arnd Bergmann,
	Linus WALLEIJ, linux-arm-kernel, linux-kernel,
	linaro-dev@lists.linaro.org Devel, Patch Tracking,
	STEricsson_nomadik_linux, Rajanikanth H.V, Samuel Ortiz

> On 19 November 2012 09:16, Anton Vorontsov <anton.vorontsov@linaro.org> wrote:
> (But I'm bouncing the patches to Samuel and Mark anyway, jfyi.)
>
> p.s.
>
> FWIW, I fixed these warnings.
>
>   CHECK   drivers/power/ab8500_bmdata.c
> drivers/power/ab8500_bmdata.c:146:23: warning: symbol 'temp_to_batres_tbl_thermistor' was not declared. Should it be static?
> drivers/power/ab8500_bmdata.c:160:23: warning: symbol 'temp_to_batres_tbl_ext_thermistor' was not declared. Should it be static?
> drivers/power/ab8500_bmdata.c:171:23: warning: symbol 'temp_to_batres_tbl_9100' was not declared. Should it be static?
> drivers/power/ab8500_bmdata.c:181:28: warning: symbol 'bat_type_thermistor' was not declared. Should it be static?
> drivers/power/ab8500_bmdata.c:267:28: warning: symbol 'bat_type_ext_thermistor' was not declared. Should it be static?
>
> Plus fixed a few stylistic issues.

thanks anton for validating my patch, you seems to have older version
of patch set,
i am rebasing  new version of patch set to 3.7-rc5, will communicate asap.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/4] Implement device tree support for ab8500 BM Devices
  2012-11-19  3:58   ` Rajanikanth HV
@ 2012-11-19  4:57     ` Anton Vorontsov
  0 siblings, 0 replies; 23+ messages in thread
From: Anton Vorontsov @ 2012-11-19  4:57 UTC (permalink / raw)
  To: Rajanikanth HV
  Cc: rob.herring, Lee Jones, Francesco Lavra, Arnd Bergmann,
	Linus WALLEIJ, linux-arm-kernel, linux-kernel,
	linaro-dev@lists.linaro.org Devel, Patch Tracking,
	STEricsson_nomadik_linux, Rajanikanth H.V, Samuel Ortiz

On Mon, Nov 19, 2012 at 09:28:59AM +0530, Rajanikanth HV wrote:
> > FWIW, I fixed these warnings.
> >
> >   CHECK   drivers/power/ab8500_bmdata.c
> > drivers/power/ab8500_bmdata.c:146:23: warning: symbol 'temp_to_batres_tbl_thermistor' was not declared. Should it be static?
> > drivers/power/ab8500_bmdata.c:160:23: warning: symbol 'temp_to_batres_tbl_ext_thermistor' was not declared. Should it be static?
> > drivers/power/ab8500_bmdata.c:171:23: warning: symbol 'temp_to_batres_tbl_9100' was not declared. Should it be static?
> > drivers/power/ab8500_bmdata.c:181:28: warning: symbol 'bat_type_thermistor' was not declared. Should it be static?
> > drivers/power/ab8500_bmdata.c:267:28: warning: symbol 'bat_type_ext_thermistor' was not declared. Should it be static?
> >
> > Plus fixed a few stylistic issues.
> 
> thanks anton for validating my patch, you seems to have older version
> of patch set,
> i am rebasing  new version of patch set to 3.7-rc5, will communicate asap.

Can you please rebase the new work on top of current battery tree (i.e. on
top of the patches that you've sent)? Or that would be too much burden?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-11-22 20:08   ` Anton Vorontsov
@ 2012-11-23  9:50     ` Lee Jones
  0 siblings, 0 replies; 23+ messages in thread
From: Lee Jones @ 2012-11-23  9:50 UTC (permalink / raw)
  To: Anton Vorontsov
  Cc: Rajanikanth H.V, rob.herring, robherring2, francescolavra.fl,
	arnd, linus.walleij, linux-arm-kernel, linux-kernel, linaro-dev,
	patches, STEricsson_nomadik_linux, rajanikanth.hv


> On Fri, Nov 23, 2012 at 12:13:44AM +0530, Rajanikanth H.V wrote:
> [...]
> > +/*
> > + * Note that the batres_vs_temp table must be strictly sorted by falling
> > + * temperature values to work.
> > + */
> > +struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {
> 
> It must be static.
> 
> [..]
> > +struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = {
> 
> Ditto.
> 
> > +	{ 60, 300},
> > +	{ 30, 300},
> > +	{ 20, 300},
> > +	{ 10, 300},
> > +	{ 00, 300},
> > +	{-10, 300},
> > +	{-20, 300},
> > +};
> > +
> > +/* battery resistance table for LI ION 9100 battery */
> > +struct batres_vs_temp temp_to_batres_tbl_9100[] = {
> 
> Ditto.
> 
> There are other issues, which I fixed in my tree for the previous series.
> So the previous series already merged, please post patches on top of it.

Ah, I see now. My apologies, I'll re-comment.

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-11-22 18:43 ` [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge Rajanikanth H.V
@ 2012-11-22 20:08   ` Anton Vorontsov
  2012-11-23  9:50     ` Lee Jones
  0 siblings, 1 reply; 23+ messages in thread
From: Anton Vorontsov @ 2012-11-22 20:08 UTC (permalink / raw)
  To: Rajanikanth H.V
  Cc: rob.herring, robherring2, francescolavra.fl, lee.jones, arnd,
	linus.walleij, linux-arm-kernel, linux-kernel, linaro-dev,
	patches, STEricsson_nomadik_linux, rajanikanth.hv

On Fri, Nov 23, 2012 at 12:13:44AM +0530, Rajanikanth H.V wrote:
[...]
> +/*
> + * Note that the batres_vs_temp table must be strictly sorted by falling
> + * temperature values to work.
> + */
> +struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {

It must be static.

[..]
> +struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = {

Ditto.

> +	{ 60, 300},
> +	{ 30, 300},
> +	{ 20, 300},
> +	{ 10, 300},
> +	{ 00, 300},
> +	{-10, 300},
> +	{-20, 300},
> +};
> +
> +/* battery resistance table for LI ION 9100 battery */
> +struct batres_vs_temp temp_to_batres_tbl_9100[] = {

Ditto.

There are other issues, which I fixed in my tree for the previous series.
So the previous series already merged, please post patches on top of it.

Thanks,
Anton.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-11-22 18:43 Rajanikanth H.V
@ 2012-11-22 18:43 ` Rajanikanth H.V
  2012-11-22 20:08   ` Anton Vorontsov
  0 siblings, 1 reply; 23+ messages in thread
From: Rajanikanth H.V @ 2012-11-22 18:43 UTC (permalink / raw)
  To: rob.herring, robherring2, francescolavra.fl, anton.vorontsov
  Cc: lee.jones, arnd, linus.walleij, linux-arm-kernel, linux-kernel,
	linaro-dev, patches, STEricsson_nomadik_linux, rajanikanth.hv,
	Rajanikanth H.V

From: "Rajanikanth H.V" <rajanikanth.hv@linaro.org>

- This patch adds device tree support for fuelgauge driver
- optimize bm devices platform_data usage and of_probe(...)
  Note: of_probe() routine for battery managed devices is made
  common across all bm drivers.
- test status:
  - interrupt numbers assigned differs between legacy and FDT mode.

Signed-off-by: Rajanikanth H.V <rajanikanth.hv@linaro.org>
---
 Documentation/devicetree/bindings/mfd/ab8500.txt   |    7 +-
 .../devicetree/bindings/power_supply/ab8500/fg.txt |   58 +++
 arch/arm/boot/dts/dbx5x0.dtsi                      |   10 +
 drivers/mfd/ab8500-core.c                          |    5 +
 drivers/power/Makefile                             |    2 +-
 drivers/power/ab8500_bmdata.c                      |  514 ++++++++++++++++++++
 drivers/power/ab8500_btemp.c                       |   16 +-
 drivers/power/ab8500_charger.c                     |   16 +-
 drivers/power/ab8500_fg.c                          |   81 +--
 drivers/power/abx500_chargalg.c                    |    7 +-
 include/linux/mfd/abx500.h                         |   36 +-
 11 files changed, 659 insertions(+), 93 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
 create mode 100644 drivers/power/ab8500_bmdata.c

diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
index ce83c8d..6ca8d81 100644
--- a/Documentation/devicetree/bindings/mfd/ab8500.txt
+++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
@@ -24,7 +24,12 @@ ab8500-bm                :                      :              : Battery Manager
 ab8500-btemp             :                      :              : Battery Temperature
 ab8500-charger           :                      :              : Battery Charger
 ab8500-codec             :                      :              : Audio Codec
-ab8500-fg                :                      :              : Fuel Gauge
+ab8500-fg                : 			: vddadc       : Fuel Gauge
+			 : NCONV_ACCU           :	       : Accumulate N Sample Conversion
+			 : BATT_OVV		:	       : Battery Over Voltage
+			 : LOW_BAT_F		:	       : LOW threshold battery voltage
+			 : CC_INT_CALIB		:	       : Coulomb Counter Internal Calibration
+			 : CCEOC		:	       : Coulomb Counter End of Conversion
 ab8500-gpadc             : HW_CONV_END          : vddadc       : Analogue to Digital Converter
                            SW_CONV_END          :              :
 ab8500-gpio              :                      :              : GPIO Controller
diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
new file mode 100644
index 0000000..ccafcb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
@@ -0,0 +1,58 @@
+=== AB8500 Fuel Gauge Driver ===
+
+AB8500 is a mixed signal multimedia and power management
+device comprising: power and energy-management-module,
+wall-charger, usb-charger, audio codec, general purpose adc,
+tvout, clock management and sim card interface.
+
+Fuelgauge support is part of energy-management-modules, other
+components of this module are:
+main-charger, usb-combo-charger and battery-temperature-monitoring.
+
+The properties below describes the node for fuelgauge driver.
+
+Required Properties:
+- compatible = This shall be: "stericsson,ab8500-fg"
+- battery = Shall be battery specific information
+	Example:
+	ab8500_fg {
+		compatible = "stericsson,ab8500-fg";
+		battery	   = <&ab8500_battery>;
+	};
+
+dependent node:
+	ab8500_battery: ab8500_battery {
+	};
+	This node will provide information on 'thermistor interface' and
+	'battery technology type' used.
+
+Properties of this node are:
+thermistor-on-batctrl:
+	A boolean value indicating thermistor interface	to battery
+
+	Note:
+	'btemp' and 'batctrl' are the pins interfaced for battery temperature
+	measurement, 'btemp' signal is used when NTC(negative temperature
+	coefficient) resister is interfaced external to battery whereas
+	'batctrl' pin is used when NTC resister is internal to battery.
+
+	Example:
+	ab8500_battery: ab8500_battery {
+		thermistor-on-batctrl;
+	};
+	indicates: NTC resister is internal to battery, 'batctrl' is used
+		for thermal measurement.
+
+	The absence of property 'thermal-on-batctrl' indicates
+	NTC resister is external to battery and  'btemp' signal is used
+	for thermal measurement.
+
+battery-type:
+	This shall be the battery manufacturing technology type,
+	allowed types are:
+		"UNKNOWN" "NiMH" "LION" "LIPO" "LiFe" "NiCd" "LiMn"
+	Example:
+	ab8500_battery: ab8500_battery {
+		stericsson,battery-type = "LIPO";
+	}
+
diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
index 4b0e0ca..155cf53 100644
--- a/arch/arm/boot/dts/dbx5x0.dtsi
+++ b/arch/arm/boot/dts/dbx5x0.dtsi
@@ -352,6 +352,16 @@
 					vddadc-supply = <&ab8500_ldo_tvout_reg>;
 				};
 
+				ab8500_battery: ab8500_battery {
+					stericsson,battery-type = "LIPO";
+					thermistor-on-batctrl;
+				};
+
+				ab8500-fg {
+					compatible = "stericsson,ab8500-fg";
+					battery	   = <&ab8500_battery>;
+				};
+
 				ab8500-usb {
 					compatible = "stericsson,ab8500-usb";
 					interrupts = < 90 0x4
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 1667c77..7c3017b 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1051,8 +1051,13 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
 	},
 	{
 		.name = "ab8500-fg",
+		.of_compatible = "stericsson,ab8500-fg",
 		.num_resources = ARRAY_SIZE(ab8500_fg_resources),
 		.resources = ab8500_fg_resources,
+#ifndef CONFIG_OF
+		.platform_data = &ab8500_bm_data,
+		.pdata_size = sizeof(ab8500_bm_data),
+#endif
 	},
 	{
 		.name = "ab8500-chargalg",
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b949cf8..9103665 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -37,7 +37,7 @@ obj-$(CONFIG_CHARGER_88PM860X)	+= 88pm860x_charger.o
 obj-$(CONFIG_CHARGER_PCF50633)	+= pcf50633-charger.o
 obj-$(CONFIG_BATTERY_JZ4740)	+= jz4740-battery.o
 obj-$(CONFIG_BATTERY_INTEL_MID)	+= intel_mid_battery.o
-obj-$(CONFIG_AB8500_BM)		+= ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o
+obj-$(CONFIG_AB8500_BM)		+= ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o
 obj-$(CONFIG_CHARGER_ISP1704)	+= isp1704_charger.o
 obj-$(CONFIG_CHARGER_MAX8903)	+= max8903_charger.o
 obj-$(CONFIG_CHARGER_TWL4030)	+= twl4030_charger.o
diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c
new file mode 100644
index 0000000..0366270
--- /dev/null
+++ b/drivers/power/ab8500_bmdata.c
@@ -0,0 +1,514 @@
+#include <linux/export.h>
+#include <linux/power_supply.h>
+#include <linux/of.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-bm.h>
+
+/*
+ * These are the defined batteries that uses a NTC and ID resistor placed
+ * inside of the battery pack.
+ * Note that the res_to_temp table must be strictly sorted by falling resistance
+ * values to work.
+ */
+static struct abx500_res_to_temp temp_tbl_A_thermistor[] = {
+	{-5, 53407},
+	{ 0, 48594},
+	{ 5, 43804},
+	{10, 39188},
+	{15, 34870},
+	{20, 30933},
+	{25, 27422},
+	{30, 24347},
+	{35, 21694},
+	{40, 19431},
+	{45, 17517},
+	{50, 15908},
+	{55, 14561},
+	{60, 13437},
+	{65, 12500},
+};
+static struct abx500_res_to_temp temp_tbl_B_thermistor[] = {
+	{-5, 165418},
+	{ 0, 159024},
+	{ 5, 151921},
+	{10, 144300},
+	{15, 136424},
+	{20, 128565},
+	{25, 120978},
+	{30, 113875},
+	{35, 107397},
+	{40, 101629},
+	{45,  96592},
+	{50,  92253},
+	{55,  88569},
+	{60,  85461},
+	{65,  82869},
+};
+static struct abx500_v_to_cap cap_tbl_A_thermistor[] = {
+	{4171,	100},
+	{4114,	 95},
+	{4009,	 83},
+	{3947,	 74},
+	{3907,	 67},
+	{3863,	 59},
+	{3830,	 56},
+	{3813,	 53},
+	{3791,	 46},
+	{3771,	 33},
+	{3754,	 25},
+	{3735,	 20},
+	{3717,	 17},
+	{3681,	 13},
+	{3664,	  8},
+	{3651,	  6},
+	{3635,	  5},
+	{3560,	  3},
+	{3408,    1},
+	{3247,	  0},
+};
+static struct abx500_v_to_cap cap_tbl_B_thermistor[] = {
+	{4161,	100},
+	{4124,	 98},
+	{4044,	 90},
+	{4003,	 85},
+	{3966,	 80},
+	{3933,	 75},
+	{3888,	 67},
+	{3849,	 60},
+	{3813,	 55},
+	{3787,	 47},
+	{3772,	 30},
+	{3751,	 25},
+	{3718,	 20},
+	{3681,	 16},
+	{3660,	 14},
+	{3589,	 10},
+	{3546,	  7},
+	{3495,	  4},
+	{3404,	  2},
+	{3250,	  0},
+};
+
+static struct abx500_v_to_cap cap_tbl[] = {
+	{4186,	100},
+	{4163,	 99},
+	{4114,	 95},
+	{4068,	 90},
+	{3990,	 80},
+	{3926,	 70},
+	{3898,	 65},
+	{3866,	 60},
+	{3833,	 55},
+	{3812,	 50},
+	{3787,	 40},
+	{3768,	 30},
+	{3747,	 25},
+	{3730,	 20},
+	{3705,	 15},
+	{3699,	 14},
+	{3684,	 12},
+	{3672,	  9},
+	{3657,	  7},
+	{3638,	  6},
+	{3556,	  4},
+	{3424,	  2},
+	{3317,	  1},
+	{3094,	  0},
+};
+
+/*
+ * Note that the res_to_temp table must be strictly sorted by falling
+ * resistance values to work.
+ */
+static struct abx500_res_to_temp temp_tbl[] = {
+	{-5, 214834},
+	{ 0, 162943},
+	{ 5, 124820},
+	{10,  96520},
+	{15,  75306},
+	{20,  59254},
+	{25,  47000},
+	{30,  37566},
+	{35,  30245},
+	{40,  24520},
+	{45,  20010},
+	{50,  16432},
+	{55,  13576},
+	{60,  11280},
+	{65,   9425},
+};
+
+/*
+ * Note that the batres_vs_temp table must be strictly sorted by falling
+ * temperature values to work.
+ */
+struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {
+	{ 40, 120},
+	{ 30, 135},
+	{ 20, 165},
+	{ 10, 230},
+	{ 00, 325},
+	{-10, 445},
+	{-20, 595},
+};
+
+/*
+ * Note that the batres_vs_temp table must be strictly sorted by falling
+ * temperature values to work.
+ */
+struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = {
+	{ 60, 300},
+	{ 30, 300},
+	{ 20, 300},
+	{ 10, 300},
+	{ 00, 300},
+	{-10, 300},
+	{-20, 300},
+};
+
+/* battery resistance table for LI ION 9100 battery */
+struct batres_vs_temp temp_to_batres_tbl_9100[] = {
+	{ 60, 180},
+	{ 30, 180},
+	{ 20, 180},
+	{ 10, 180},
+	{ 00, 180},
+	{-10, 180},
+	{-20, 180},
+};
+
+struct abx500_battery_type bat_type_thermistor[] = {
+[BATTERY_UNKNOWN] = {
+	/* First element always represent the UNKNOWN battery */
+	.name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
+	.resis_high = 0,
+	.resis_low = 0,
+	.battery_resistance = 300,
+	.charge_full_design = 612,
+	.nominal_voltage = 3700,
+	.termination_vol = 4050,
+	.termination_curr = 200,
+	.recharge_vol = 3990,
+	.normal_cur_lvl = 400,
+	.normal_vol_lvl = 4100,
+	.maint_a_cur_lvl = 400,
+	.maint_a_vol_lvl = 4050,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 400,
+	.maint_b_vol_lvl = 4000,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.resis_high = 53407,
+	.resis_low = 12500,
+	.battery_resistance = 300,
+	.charge_full_design = 900,
+	.nominal_voltage = 3600,
+	.termination_vol = 4150,
+	.termination_curr = 80,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_A_thermistor),
+	.r_to_t_tbl = temp_tbl_A_thermistor,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_A_thermistor),
+	.v_to_cap_tbl = cap_tbl_A_thermistor,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+
+},
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.resis_high = 165418,
+	.resis_low = 82869,
+	.battery_resistance = 300,
+	.charge_full_design = 900,
+	.nominal_voltage = 3600,
+	.termination_vol = 4150,
+	.termination_curr = 80,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_B_thermistor),
+	.r_to_t_tbl = temp_tbl_B_thermistor,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_B_thermistor),
+	.v_to_cap_tbl = cap_tbl_B_thermistor,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+};
+
+struct abx500_battery_type bat_type_ext_thermistor[] = {
+[BATTERY_UNKNOWN] = {
+	/* First element always represent the UNKNOWN battery */
+	.name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
+	.resis_high = 0,
+	.resis_low = 0,
+	.battery_resistance = 300,
+	.charge_full_design = 612,
+	.nominal_voltage = 3700,
+	.termination_vol = 4050,
+	.termination_curr = 200,
+	.recharge_vol = 3990,
+	.normal_cur_lvl = 400,
+	.normal_vol_lvl = 4100,
+	.maint_a_cur_lvl = 400,
+	.maint_a_vol_lvl = 4050,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 400,
+	.maint_b_vol_lvl = 4000,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+/*
+ * These are the batteries that doesn't have an internal NTC resistor to measure
+ * its temperature. The temperature in this case is measure with a NTC placed
+ * near the battery but on the PCB.
+ */
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+	.resis_high = 76000,
+	.resis_low = 53000,
+	.battery_resistance = 300,
+	.charge_full_design = 900,
+	.nominal_voltage = 3700,
+	.termination_vol = 4150,
+	.termination_curr = 100,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LION,
+	.resis_high = 30000,
+	.resis_low = 10000,
+	.battery_resistance = 300,
+	.charge_full_design = 950,
+	.nominal_voltage = 3700,
+	.termination_vol = 4150,
+	.termination_curr = 100,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+{
+	.name = POWER_SUPPLY_TECHNOLOGY_LION,
+	.resis_high = 95000,
+	.resis_low = 76001,
+	.battery_resistance = 300,
+	.charge_full_design = 950,
+	.nominal_voltage = 3700,
+	.termination_vol = 4150,
+	.termination_curr = 100,
+	.recharge_vol = 4130,
+	.normal_cur_lvl = 700,
+	.normal_vol_lvl = 4200,
+	.maint_a_cur_lvl = 600,
+	.maint_a_vol_lvl = 4150,
+	.maint_a_chg_timer_h = 60,
+	.maint_b_cur_lvl = 600,
+	.maint_b_vol_lvl = 4100,
+	.maint_b_chg_timer_h = 200,
+	.low_high_cur_lvl = 300,
+	.low_high_vol_lvl = 4000,
+	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+	.r_to_t_tbl = temp_tbl,
+	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+	.v_to_cap_tbl = cap_tbl,
+	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+	.batres_tbl = temp_to_batres_tbl_thermistor,
+},
+};
+
+static const struct abx500_bm_capacity_levels cap_levels = {
+	.critical	= 2,
+	.low		= 10,
+	.normal		= 70,
+	.high		= 95,
+	.full		= 100,
+};
+
+static const struct abx500_fg_parameters fg = {
+	.recovery_sleep_timer = 10,
+	.recovery_total_time = 100,
+	.init_timer = 1,
+	.init_discard_time = 5,
+	.init_total_time = 40,
+	.high_curr_time = 60,
+	.accu_charging = 30,
+	.accu_high_curr = 30,
+	.high_curr_threshold = 50,
+	.lowbat_threshold = 3100,
+	.battok_falling_th_sel0 = 2860,
+	.battok_raising_th_sel1 = 2860,
+	.user_cap_limit = 15,
+	.maint_thres = 97,
+};
+
+static const struct abx500_maxim_parameters maxi_params = {
+	.ena_maxi = true,
+	.chg_curr = 910,
+	.wait_cycles = 10,
+	.charger_curr_step = 100,
+};
+
+static const struct abx500_bm_charger_parameters chg = {
+	.usb_volt_max		= 5500,
+	.usb_curr_max		= 1500,
+	.ac_volt_max		= 7500,
+	.ac_curr_max		= 1500,
+};
+
+struct abx500_bm_data ab8500_bm_data = {
+	.temp_under		= 3,
+	.temp_low		= 8,
+	.temp_high		= 43,
+	.temp_over		= 48,
+	.main_safety_tmr_h	= 4,
+	.temp_interval_chg	= 20,
+	.temp_interval_nochg	= 120,
+	.usb_safety_tmr_h	= 4,
+	.bkup_bat_v		= BUP_VCH_SEL_2P6V,
+	.bkup_bat_i		= BUP_ICH_SEL_150UA,
+	.no_maintenance		= false,
+	.adc_therm		= ABx500_ADC_THERM_BATCTRL,
+	.chg_unknown_bat	= false,
+	.enable_overshoot	= false,
+	.fg_res			= 100,
+	.cap_levels		= &cap_levels,
+	.bat_type		= bat_type_thermistor,
+	.n_btypes		= 3,
+	.batt_id		= 0,
+	.interval_charging	= 5,
+	.interval_not_charging	= 120,
+	.temp_hysteresis	= 3,
+	.gnd_lift_resistance	= 34,
+	.maxi			= &maxi_params,
+	.chg_params		= &chg,
+	.fg_params		= &fg,
+};
+
+int __devinit
+bmdevs_of_probe(struct device *dev,
+		struct device_node *np,
+		struct abx500_bm_data **battery)
+{
+	struct	abx500_battery_type *btype;
+	struct  device_node *np_bat_supply;
+	struct	abx500_bm_data *bat;
+	const char *btech;
+	int i, thermistor;
+
+	*battery = &ab8500_bm_data;
+
+	/* get phandle to 'battery-info' node */
+	np_bat_supply = of_parse_phandle(np, "battery", 0);
+	if (!np_bat_supply) {
+		dev_err(dev, "missing property battery\n");
+		return -EINVAL;
+	}
+	if (of_property_read_bool(np_bat_supply,
+			"thermistor-on-batctrl"))
+		thermistor = NTC_INTERNAL;
+	else
+		thermistor = NTC_EXTERNAL;
+
+	bat = *battery;
+	if (thermistor == NTC_EXTERNAL) {
+		bat->n_btypes  = 4;
+		bat->bat_type  = bat_type_ext_thermistor;
+		bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
+	}
+	btech = of_get_property(np_bat_supply,
+		"stericsson,battery-type", NULL);
+	if (!btech) {
+		dev_warn(dev, "missing property battery-name/type\n");
+		return -EINVAL;
+	}
+	if (strncmp(btech, "LION", 4) == 0) {
+		bat->no_maintenance  = true;
+		bat->chg_unknown_bat = true;
+		bat->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600;
+		bat->bat_type[BATTERY_UNKNOWN].termination_vol    = 4150;
+		bat->bat_type[BATTERY_UNKNOWN].recharge_vol	  = 4130;
+		bat->bat_type[BATTERY_UNKNOWN].normal_cur_lvl	  = 520;
+		bat->bat_type[BATTERY_UNKNOWN].normal_vol_lvl	  = 4200;
+	}
+	/* select the battery resolution table */
+	for (i = 0; i < bat->n_btypes; ++i) {
+		btype = (bat->bat_type + i);
+		if (thermistor == NTC_EXTERNAL) {
+			btype->batres_tbl =
+				temp_to_batres_tbl_ext_thermistor;
+		} else if (strncmp(btech, "LION", 4) == 0) {
+			btype->batres_tbl =
+				temp_to_batres_tbl_9100;
+		} else {
+			btype->batres_tbl =
+				temp_to_batres_tbl_thermistor;
+		}
+	}
+	of_node_put(np_bat_supply);
+	return 0;
+}
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
index e3b6395..abc2abc 100644
--- a/drivers/power/ab8500_btemp.c
+++ b/drivers/power/ab8500_btemp.c
@@ -93,7 +93,7 @@ struct ab8500_btemp {
 	struct ab8500 *parent;
 	struct ab8500_gpadc *gpadc;
 	struct ab8500_fg *fg;
-	struct abx500_btemp_platform_data *pdata;
+	struct abx500_bmdevs_plat_data *pdata;
 	struct abx500_bm_data *bat;
 	struct power_supply btemp_psy;
 	struct ab8500_btemp_events events;
@@ -962,10 +962,10 @@ static int __devexit ab8500_btemp_remove(struct platform_device *pdev)
 
 static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
 {
+	struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
+	struct ab8500_btemp *di;
 	int irq, i, ret = 0;
 	u8 val;
-	struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
-	struct ab8500_btemp *di;
 
 	if (!plat_data) {
 		dev_err(&pdev->dev, "No platform data\n");
@@ -982,21 +982,13 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
 	di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
 
 	/* get btemp specific platform data */
-	di->pdata = plat_data->btemp;
+	di->pdata = plat_data;
 	if (!di->pdata) {
 		dev_err(di->dev, "no btemp platform data supplied\n");
 		ret = -EINVAL;
 		goto free_device_info;
 	}
 
-	/* get battery specific platform data */
-	di->bat = plat_data->battery;
-	if (!di->bat) {
-		dev_err(di->dev, "no battery platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
 	/* BTEMP supply */
 	di->btemp_psy.name = "ab8500_btemp";
 	di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY;
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index 26ff759..723edb4 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -220,7 +220,7 @@ struct ab8500_charger {
 	bool autopower;
 	struct ab8500 *parent;
 	struct ab8500_gpadc *gpadc;
-	struct abx500_charger_platform_data *pdata;
+	struct abx500_bmdevs_plat_data *pdata;
 	struct abx500_bm_data *bat;
 	struct ab8500_charger_event_flags flags;
 	struct ab8500_charger_usb_state usb_state;
@@ -2533,9 +2533,9 @@ static int __devexit ab8500_charger_remove(struct platform_device *pdev)
 
 static int __devinit ab8500_charger_probe(struct platform_device *pdev)
 {
-	int irq, i, charger_status, ret = 0;
-	struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
+	struct abx500_bmdevs_plat_data *plat_data = pdev->dev.platform_data;
 	struct ab8500_charger *di;
+	int irq, i, charger_status, ret = 0;
 
 	if (!plat_data) {
 		dev_err(&pdev->dev, "No platform data\n");
@@ -2555,21 +2555,13 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
 	spin_lock_init(&di->usb_state.usb_lock);
 
 	/* get charger specific platform data */
-	di->pdata = plat_data->charger;
+	di->pdata = plat_data;
 	if (!di->pdata) {
 		dev_err(di->dev, "no charger platform data supplied\n");
 		ret = -EINVAL;
 		goto free_device_info;
 	}
 
-	/* get battery specific platform data */
-	di->bat = plat_data->battery;
-	if (!di->bat) {
-		dev_err(di->dev, "no battery platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
 	di->autopower = false;
 
 	/* AC supply */
diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
index 2db8cc2..20ac3b8 100644
--- a/drivers/power/ab8500_fg.c
+++ b/drivers/power/ab8500_fg.c
@@ -22,15 +22,16 @@
 #include <linux/platform_device.h>
 #include <linux/power_supply.h>
 #include <linux/kobject.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include <linux/mfd/abx500.h>
 #include <linux/slab.h>
-#include <linux/mfd/abx500/ab8500-bm.h>
 #include <linux/delay.h>
-#include <linux/mfd/abx500/ab8500-gpadc.h>
-#include <linux/mfd/abx500.h>
 #include <linux/time.h>
+#include <linux/of.h>
 #include <linux/completion.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-bm.h>
+#include <linux/mfd/abx500/ab8500-gpadc.h>
 
 #define MILLI_TO_MICRO			1000
 #define FG_LSB_IN_MA			1627
@@ -172,7 +173,6 @@ struct inst_curr_result_list {
  * @avg_cap:		Average capacity filter
  * @parent:		Pointer to the struct ab8500
  * @gpadc:		Pointer to the struct gpadc
- * @pdata:		Pointer to the abx500_fg platform data
  * @bat:		Pointer to the abx500_bm platform data
  * @fg_psy:		Structure that holds the FG specific battery properties
  * @fg_wq:		Work queue for running the FG algorithm
@@ -212,7 +212,6 @@ struct ab8500_fg {
 	struct ab8500_fg_avg_cap avg_cap;
 	struct ab8500 *parent;
 	struct ab8500_gpadc *gpadc;
-	struct abx500_fg_platform_data *pdata;
 	struct abx500_bm_data *bat;
 	struct power_supply fg_psy;
 	struct workqueue_struct *fg_wq;
@@ -2429,7 +2428,6 @@ static int __devexit ab8500_fg_remove(struct platform_device *pdev)
 	flush_scheduled_work();
 	power_supply_unregister(&di->fg_psy);
 	platform_set_drvdata(pdev, NULL);
-	kfree(di);
 	return ret;
 }
 
@@ -2442,21 +2440,39 @@ static struct ab8500_fg_interrupts ab8500_fg_irq[] = {
 	{"CCEOC", ab8500_fg_cc_data_end_handler},
 };
 
+static char *supply_interface[] = {
+	"ab8500_chargalg",
+	"ab8500_usb",
+};
+
 static int __devinit ab8500_fg_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
+	struct ab8500_fg *di;
 	int i, irq;
 	int ret = 0;
-	struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
-	struct ab8500_fg *di;
-
-	if (!plat_data) {
-		dev_err(&pdev->dev, "No platform data\n");
-		return -EINVAL;
-	}
 
-	di = kzalloc(sizeof(*di), GFP_KERNEL);
-	if (!di)
+	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
+	if (!di) {
+		dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__);
 		return -ENOMEM;
+	}
+	di->bat = pdev->mfd_cell->platform_data;
+	if (!di->bat) {
+		if (np) {
+			ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"failed to get battery information\n");
+				return ret;
+			}
+		} else {
+			dev_err(&pdev->dev, "missing dt node for ab8500_fg\n");
+			return -EINVAL;
+		}
+	} else {
+		dev_info(&pdev->dev, "falling back to legacy platform data\n");
+	}
 
 	mutex_init(&di->cc_lock);
 
@@ -2465,29 +2481,13 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
 	di->parent = dev_get_drvdata(pdev->dev.parent);
 	di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
 
-	/* get fg specific platform data */
-	di->pdata = plat_data->fg;
-	if (!di->pdata) {
-		dev_err(di->dev, "no fg platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
-	/* get battery specific platform data */
-	di->bat = plat_data->battery;
-	if (!di->bat) {
-		dev_err(di->dev, "no battery platform data supplied\n");
-		ret = -EINVAL;
-		goto free_device_info;
-	}
-
 	di->fg_psy.name = "ab8500_fg";
 	di->fg_psy.type = POWER_SUPPLY_TYPE_BATTERY;
 	di->fg_psy.properties = ab8500_fg_props;
 	di->fg_psy.num_properties = ARRAY_SIZE(ab8500_fg_props);
 	di->fg_psy.get_property = ab8500_fg_get_property;
-	di->fg_psy.supplied_to = di->pdata->supplied_to;
-	di->fg_psy.num_supplicants = di->pdata->num_supplicants;
+	di->fg_psy.supplied_to = supply_interface;
+	di->fg_psy.num_supplicants = ARRAY_SIZE(supply_interface),
 	di->fg_psy.external_power_changed = ab8500_fg_external_power_changed;
 
 	di->bat_cap.max_mah_design = MILLI_TO_MICRO *
@@ -2506,8 +2506,7 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
 	di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq");
 	if (di->fg_wq == NULL) {
 		dev_err(di->dev, "failed to create work queue\n");
-		ret = -ENOMEM;
-		goto free_device_info;
+		return -ENOMEM;
 	}
 
 	/* Init work for running the fg algorithm instantly */
@@ -2606,12 +2605,15 @@ free_irq:
 	}
 free_inst_curr_wq:
 	destroy_workqueue(di->fg_wq);
-free_device_info:
-	kfree(di);
 
 	return ret;
 }
 
+static const struct of_device_id ab8500_fg_match[] = {
+	{ .compatible = "stericsson,ab8500-fg", },
+	{ },
+};
+
 static struct platform_driver ab8500_fg_driver = {
 	.probe = ab8500_fg_probe,
 	.remove = __devexit_p(ab8500_fg_remove),
@@ -2620,6 +2622,7 @@ static struct platform_driver ab8500_fg_driver = {
 	.driver = {
 		.name = "ab8500-fg",
 		.owner = THIS_MODULE,
+		.of_match_table = ab8500_fg_match,
 	},
 };
 
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
index 4d30280..94bf69b 100644
--- a/drivers/power/abx500_chargalg.c
+++ b/drivers/power/abx500_chargalg.c
@@ -231,7 +231,7 @@ struct abx500_chargalg {
 	struct abx500_chargalg_charger_info chg_info;
 	struct abx500_chargalg_battery_data batt_data;
 	struct abx500_chargalg_suspension_status susp_status;
-	struct abx500_chargalg_platform_data *pdata;
+	struct abx500_bmdevs_plat_data *pdata;
 	struct abx500_bm_data *bat;
 	struct power_supply chargalg_psy;
 	struct ux500_charger *ac_chg;
@@ -1802,7 +1802,7 @@ static int __devexit abx500_chargalg_remove(struct platform_device *pdev)
 
 static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
 {
-	struct abx500_bm_plat_data *plat_data;
+	struct abx500_bmdevs_plat_data *plat_data;
 	int ret = 0;
 
 	struct abx500_chargalg *di =
@@ -1814,8 +1814,7 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
 	di->dev = &pdev->dev;
 
 	plat_data = pdev->dev.platform_data;
-	di->pdata = plat_data->chargalg;
-	di->bat = plat_data->battery;
+	di->pdata = plat_data;
 
 	/* chargalg supply */
 	di->chargalg_psy.name = "abx500_chargalg";
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index 5d5298d..33f2c58 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -267,39 +267,27 @@ struct abx500_bm_data {
 	int gnd_lift_resistance;
 	const struct abx500_maxim_parameters *maxi;
 	const struct abx500_bm_capacity_levels *cap_levels;
-	const struct abx500_battery_type *bat_type;
+	struct abx500_battery_type *bat_type;
 	const struct abx500_bm_charger_parameters *chg_params;
 	const struct abx500_fg_parameters *fg_params;
 };
 
-struct abx500_chargalg_platform_data {
-	char **supplied_to;
-	size_t num_supplicants;
-};
-
-struct abx500_charger_platform_data {
-	char **supplied_to;
-	size_t num_supplicants;
-	bool autopower_cfg;
-};
+extern struct abx500_bm_data ab8500_bm_data;
 
-struct abx500_btemp_platform_data {
-	char **supplied_to;
-	size_t num_supplicants;
+struct abx500_bmdevs_plat_data {
+	char	**supplied_to;
+	size_t	num_supplicants;
+	bool	autopower_cfg;
 };
 
-struct abx500_fg_platform_data {
-	char **supplied_to;
-	size_t num_supplicants;
+enum {
+	NTC_EXTERNAL = 0,
+	NTC_INTERNAL,
 };
 
-struct abx500_bm_plat_data {
-	struct abx500_bm_data *battery;
-	struct abx500_charger_platform_data *charger;
-	struct abx500_btemp_platform_data *btemp;
-	struct abx500_fg_platform_data *fg;
-	struct abx500_chargalg_platform_data *chargalg;
-};
+int bmdevs_of_probe(struct device *dev,
+		struct device_node *np,
+		struct abx500_bm_data **battery);
 
 int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
 	u8 value);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-10-27 16:00     ` Rajanikanth HV
@ 2012-10-27 16:18       ` Francesco Lavra
  0 siblings, 0 replies; 23+ messages in thread
From: Francesco Lavra @ 2012-10-27 16:18 UTC (permalink / raw)
  To: Rajanikanth HV
  Cc: Rajanikanth H.V, linaro-dev, linus.walleij, arnd, patches,
	linux-kernel, anton.vorontsov, STEricsson_nomadik_linux,
	linux-arm-kernel

On 10/27/2012 06:00 PM, Rajanikanth HV wrote:
> On 27 October 2012 20:37, Francesco Lavra <francescolavra.fl@gmail.com> wrote:
>> On 10/25/2012 08:30 AM, Rajanikanth H.V wrote:
>>> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
>>> +     bat_tech = of_get_property(np_bat_supply,
>>> +                     "stericsson,battery-type", NULL);
>>> +     if (!bat_tech)
>>> +             dev_warn(dev, "missing property battery-name/type\n");
>>> +
>>> +     if (strncmp(bat_tech, "LION", 4) == 0) {
>>
>> What if bat_tech is NULL?
> It will be UNKNOWN

I wanted to draw your attention to the fact that if bat_tech is NULL you
are passing a NULL pointer to strncmp(), which is not good.
So you should assign a default value to bat_tech in case the battery
type property is not found in the DT, as below:

if (!bat_tech) {
	dev_warn(dev, "missing property battery-name/type\n");
	bat_tech = "UNKNOWN";
}

--
Francesco

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-10-27 15:07   ` Francesco Lavra
@ 2012-10-27 16:00     ` Rajanikanth HV
  2012-10-27 16:18       ` Francesco Lavra
  0 siblings, 1 reply; 23+ messages in thread
From: Rajanikanth HV @ 2012-10-27 16:00 UTC (permalink / raw)
  To: Francesco Lavra
  Cc: Rajanikanth H.V, linaro-dev, linus.walleij, arnd, patches,
	linux-kernel, anton.vorontsov, STEricsson_nomadik_linux,
	linux-arm-kernel

On 27 October 2012 20:37, Francesco Lavra <francescolavra.fl@gmail.com> wrote:
> On 10/25/2012 08:30 AM, Rajanikanth H.V wrote:
>> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
>> +     bat_tech = of_get_property(np_bat_supply,
>> +                     "stericsson,battery-type", NULL);
>> +     if (!bat_tech)
>> +             dev_warn(dev, "missing property battery-name/type\n");
>> +
>> +     if (strncmp(bat_tech, "LION", 4) == 0) {
>
> What if bat_tech is NULL?
It will be UNKNOWN

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
       [not found] ` <1351146654-9110-2-git-send-email-rajanikanth.hv@stericsson.com>
@ 2012-10-27 15:07   ` Francesco Lavra
  2012-10-27 16:00     ` Rajanikanth HV
  0 siblings, 1 reply; 23+ messages in thread
From: Francesco Lavra @ 2012-10-27 15:07 UTC (permalink / raw)
  To: Rajanikanth H.V
  Cc: lee.jones, arnd, anton.vorontsov, linus.walleij,
	linux-arm-kernel, linux-kernel, linaro-dev, patches,
	STEricsson_nomadik_linux

On 10/25/2012 08:30 AM, Rajanikanth H.V wrote:
> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
> 
> - This patch adds device tree support for fuelgauge driver
> - optimize bm devices platform_data usage and of_probe(...)
>   Note: of_probe() routine for battery managed devices is made
>   common across all bm drivers.
> - test status:
>   - interrupt numbers assigned differs between legacy and FDT mode.
> 
> Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
[...]
> diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
> new file mode 100644
> index 0000000..28eaf35
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
> @@ -0,0 +1,58 @@
> +=== AB8500 Fuel Gauge Driver ===
> +
> +AB8500 is a mixed signal multimedia and power management
> +device comprising: power and energy-management-module,
> +wall-charger, usb-charger, audio codec, general purpose adc,
> +tvout, clock management and sim card interface.
> +
> +Fuelgauge support is part of energy-management-modules, other
> +components of this module are:
> +main-charger, usb-combo-charger and battery-temperature-monitoring.
> +
> +The properties below describes the node for fuelgauge driver.
> +
> +Required Properties:
> +- compatible = This shall be: "stericsson,ab8500-fg"
> +- battery = Shall be battery specific information
> +	Example:
> +	ab8500_fg {
> +		compatible = "stericsson,ab8500-fg";
> +		battery	   = <&ab8500_battery>;
> +	};
> +
> +dependent node:
> +	ab8500_battery: ab8500_battery {
> +	};
> +	This node will provide information on 'thermistor interface' and
> +	'battery technology type' used.
> +
> +Properties of this node are:
> +thermistor-on-batctrl:
> +	A boolean value indicating thermistor interface	to battery
> +
> +	Note:
> +	'btemp' and 'batctrl' are the pins interfaced for battery temperature
> +	measurement, 'btemp' signal is used when NTC(negative temperature
> +	coefficient) resister is interfaced external to battery whereas
> +	'batctrl' pin is used when NTC resister is internal to battery.
> +
> +	Example:
> +	ab8500_battery: ab8500_battery {
> +		thermistor-on-batctrl;
> +	};
> +	indiactes: NTC resister is internal to battery, 'batctrl' is used

s/indiactes/indicates

[...]
> +int __devinit
> +bmdevs_of_probe(struct device *dev,
> +		struct device_node *np,
> +		struct abx500_bm_data **battery)
> +{
> +	struct	abx500_battery_type *btype;
> +	struct  device_node *np_bat_supply;
> +	struct	abx500_bm_data *bat;
> +	const char *bat_tech;
> +	int i, thermistor;
> +
> +	*battery = &ab8500_bm_data;
> +
> +	/* get phandle to 'battery-info' node */
> +	np_bat_supply = of_parse_phandle(np, "battery", 0);
> +	if (!np_bat_supply) {
> +		dev_err(dev, "missing property battery\n");
> +		return -EINVAL;
> +	}
> +	if (of_property_read_bool(np_bat_supply,
> +			"thermistor-on-batctrl"))
> +		thermistor = NTC_INTERNAL;
> +	else
> +		thermistor = NTC_EXTERNAL;
> +
> +	bat = *battery;
> +	if (thermistor == NTC_EXTERNAL) {
> +		bat->n_btypes  = 4;
> +		bat->bat_type  = bat_type_ext_thermistor;
> +		bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
> +	}
> +	bat_tech = of_get_property(np_bat_supply,
> +			"stericsson,battery-type", NULL);
> +	if (!bat_tech)
> +		dev_warn(dev, "missing property battery-name/type\n");
> +
> +	if (strncmp(bat_tech, "LION", 4) == 0) {

What if bat_tech is NULL?

[...]
> diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
> index bf02225..e117920 100644
> --- a/drivers/power/ab8500_fg.c
> +++ b/drivers/power/ab8500_fg.c
> @@ -22,15 +22,16 @@
>  #include <linux/platform_device.h>
>  #include <linux/power_supply.h>
>  #include <linux/kobject.h>
> -#include <linux/mfd/abx500/ab8500.h>
> -#include <linux/mfd/abx500.h>
>  #include <linux/slab.h>
> -#include <linux/mfd/abx500/ab8500-bm.h>
>  #include <linux/delay.h>
> -#include <linux/mfd/abx500/ab8500-gpadc.h>
> -#include <linux/mfd/abx500.h>
>  #include <linux/time.h>
> +#include <linux/of.h>
>  #include <linux/completion.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/abx500.h>
> +#include <linux/mfd/abx500/ab8500.h>
> +#include <linux/mfd/abx500/ab8500-bm.h>
> +#include <linux/mfd/abx500/ab8500-gpadc.h>
>  
>  #define MILLI_TO_MICRO			1000
>  #define FG_LSB_IN_MA			1627
> @@ -212,7 +213,6 @@ struct ab8500_fg {
>  	struct ab8500_fg_avg_cap avg_cap;
>  	struct ab8500 *parent;
>  	struct ab8500_gpadc *gpadc;
> -	struct abx500_fg_platform_data *pdata;

pdata should be removed from the description of the struct members as well.

--
Francesco

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
       [not found] ` <1349064513-31301-2-git-send-email-rajanikanth.hv@stericsson.com>
  2012-10-01  9:49   ` Lee Jones
@ 2012-10-06 14:01   ` Francesco Lavra
  1 sibling, 0 replies; 23+ messages in thread
From: Francesco Lavra @ 2012-10-06 14:01 UTC (permalink / raw)
  To: Rajanikanth H.V
  Cc: lee.jones, arnd, anton.vorontsov, linus.walleij,
	linux-arm-kernel, linux-kernel, linaro-dev, patches,
	STEricsson_nomadik_linux

Hi,

On 10/01/2012 06:08 AM, Rajanikanth H.V wrote:
> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
> 
> - This patch adds device tree support for fuelguage driver
> - optimize bm devices platform_data usage and of_probe(...)
>   Note: of_probe() routine for battery managed devices is made
>   common across all bm drivers.
[...]
> +int __devinit
> +bmdevs_of_probe(struct device *dev,
> +		struct device_node *np,
> +		struct abx500_bm_plat_data *pdata)
> +{
> +	int	i, ret = 0, thermistor = NTC_INTERNAL;
> +	const	__be32 *ph;
> +	const	char *bat_tech;
> +	struct	abx500_bm_data		 *bat;
> +	struct	abx500_battery_type	 *btype;
> +	struct  device_node		 *np_bat_supply;
> +	struct  abx500_bmdevs_plat_data  *plat_data = pdata->bmdev_pdata;
> +
> +	/* get phandle to 'supplied-to' node */
> +	ph = of_get_property(np, "supplied-to", &plat_data->num_supplicants);
> +	if (ph == NULL) {
> +		dev_err(dev, "no supplied_to property specified\n");
> +		return -EINVAL;
> +	}
> +	plat_data->num_supplicants /= sizeof(int);
> +	plat_data->supplied_to =
> +		devm_kzalloc(dev, plat_data->num_supplicants *
> +			sizeof(const char *), GFP_KERNEL);
> +	if (plat_data->supplied_to == NULL) {
> +		dev_err(dev, "%s no mem for supplied-to\n", __func__);
> +		return -ENOMEM;
> +	}
> +	for (i = 0; i < plat_data->num_supplicants; ++i) {
> +		np_bat_supply = of_find_node_by_phandle(be32_to_cpup(ph) + i);
> +		if (np_bat_supply == NULL) {
> +			dev_err(dev, "invalid supplied_to property\n");
> +			return -EINVAL;
> +		}
> +		ret = of_property_read_string(np_bat_supply, "interface-name",
> +				(const char **)(plat_data->supplied_to + i));
> +		if (ret < 0) {
> +			of_node_put(np_bat_supply);
> +			dev_err(dev, "supply/interface name not found\n");
> +			return ret;
> +		}

If an error is encountered here, of_node_put() should be called for all
nodes previously referenced with of_find_node_by_phandle (or
of_parse_phandle, as Lee suggested).
Also, if I'm not mistaken we have a leak here, because the refcount of
these nodes is never decremented, not even in the driver remove routine.

[...]
> @@ -2446,18 +2444,47 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
>  {
>  	int i, irq;
>  	int ret = 0;
> -	struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
> +	struct abx500_bm_plat_data *plat_data
> +				= pdev->dev.platform_data;
> +	struct device_node *np	= pdev->dev.of_node;
>  	struct ab8500_fg *di;
>  
> +	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
> +	if (!di) {
> +		dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__);
> +		return -ENOMEM;
> +	}
> +	if (np) {
> +		if (!plat_data) {
> +			plat_data =
> +			devm_kzalloc(&pdev->dev, sizeof(*plat_data),
> +					GFP_KERNEL);
> +			if (!plat_data) {
> +				dev_err(&pdev->dev,
> +					"%s no mem for plat_data\n", __func__);
> +				return -ENOMEM;
> +			}
> +			plat_data->bmdev_pdata = devm_kzalloc(&pdev->dev,
> +				sizeof(*plat_data->bmdev_pdata), GFP_KERNEL);
> +			if (!plat_data->bmdev_pdata) {
> +				dev_err(&pdev->dev,
> +					"%s no mem for pdata->fg\n",
> +					__func__);
> +				return -ENOMEM;
> +			}
> +		}
> +		ret = bmdevs_of_probe(&pdev->dev, np, plat_data);

I think it's better to move allocation of bmdev_pdata and corresponding
error check to bmdevs_of_probe(), because this code is shared by all
battery management drivers.

--
Francesco

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-10-01  9:59     ` Rajanikanth HV
@ 2012-10-01 10:36       ` Lee Jones
  0 siblings, 0 replies; 23+ messages in thread
From: Lee Jones @ 2012-10-01 10:36 UTC (permalink / raw)
  To: Rajanikanth HV
  Cc: francescolavra.fl, arnd, anton.vorontsov, Linus WALLEIJ,
	linux-arm-kernel, linux-kernel, linaro-dev, patches,
	STEricsson_nomadik_linux

> did you have a look at arnd and anton comments regarding
> 'supplied-to' and boolean property

Try to keep your comments inline, situated below the relevant comment.

> >> +     ab8500_battery_info: ab8500_bat_type {
> >> +             battery-type = <2>;
> >> +             thermistor-on-batctrl = <1>;

> > You have this as a bool here, and ...

> >> +     e.g:
> >> +     ab8500_battery_info: ab8500_bat_type {
> >> +             thermistor-on-batctrl;

> > ... a standard property here. I suggest you drop the bool value.

I'm guessing it's just the documentation that needs amending.

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-10-01  9:49   ` Lee Jones
  2012-10-01  9:59     ` Rajanikanth HV
@ 2012-10-01 10:22     ` Lee Jones
  1 sibling, 0 replies; 23+ messages in thread
From: Lee Jones @ 2012-10-01 10:22 UTC (permalink / raw)
  To: Rajanikanth H.V
  Cc: francescolavra.fl, arnd, anton.vorontsov, linus.walleij,
	linux-arm-kernel, linux-kernel, linaro-dev, patches,
	STEricsson_nomadik_linux

Sorry, some mistakes:

> > From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
> > 
> > - This patch adds device tree support for fuelguage driver
> > - optimize bm devices platform_data usage and of_probe(...)
> >   Note: of_probe() routine for battery managed devices is made
> >   common across all bm drivers.

Spelling errors in here.

> > +		dev_err(dev, "invalid battery-info node\n");
> > +		return -EINVAL;
> > +	}
> > +	if (of_property_read_bool(np_bat_supply,
> > +			"thermistor-on-batctrl") == false){
> 
> Replace with: 
>         if (of_get_property(np_bat_supply, "thermistor-on-batctr", NULL))
> 	        np_bat_supply =  true;

This should be: 

         if (of_get_property(np_bat_supply, "thermistor-on-batctr", NULL))
 	        thermistor = NTC_INTERNAL;
         else
                thermistor = NTC_EXTERNAL;

> <remove>
> 
> > +		dev_warn(dev, "missing property thermistor-on-batctrl\n");
> > +		thermistor = NTC_EXTERNAL;
> > +	}
> 
> </remove>

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
  2012-10-01  9:49   ` Lee Jones
@ 2012-10-01  9:59     ` Rajanikanth HV
  2012-10-01 10:36       ` Lee Jones
  2012-10-01 10:22     ` Lee Jones
  1 sibling, 1 reply; 23+ messages in thread
From: Rajanikanth HV @ 2012-10-01  9:59 UTC (permalink / raw)
  To: Lee Jones
  Cc: francescolavra.fl, arnd, anton.vorontsov, Linus WALLEIJ,
	linux-arm-kernel, linux-kernel, linaro-dev, patches,
	STEricsson_nomadik_linux

did you have a look at arnd and anton comments regarding
'supplied-to' and boolean property

On Monday 01 October 2012 03:19 PM, Lee Jones wrote:
> On Mon, 01 Oct 2012, Rajanikanth H.V wrote:
> 
>> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
>>
>> - This patch adds device tree support for fuelguage driver
>> - optimize bm devices platform_data usage and of_probe(...)
>>   Note: of_probe() routine for battery managed devices is made
>>   common across all bm drivers.
>>
>> Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
>> ---
>>  Documentation/devicetree/bindings/mfd/ab8500.txt   |    8 +-
>>  .../devicetree/bindings/power_supply/ab8500/fg.txt |   86 +++
>>  arch/arm/boot/dts/dbx5x0.dtsi                      |   22 +-
>>  drivers/mfd/ab8500-core.c                          |    1 +
>>  drivers/power/Makefile                             |    2 +-
>>  drivers/power/ab8500_bmdata.c                      |  549 ++++++++++++++++++++
>>  drivers/power/ab8500_btemp.c                       |    4 +-
>>  drivers/power/ab8500_charger.c                     |    4 +-
>>  drivers/power/ab8500_fg.c                          |   76 ++-
>>  drivers/power/abx500_chargalg.c                    |    4 +-
>>  include/linux/mfd/abx500.h                         |   37 +-
>>  include/linux/mfd/abx500/ab8500-bm.h               |    7 +
>>  12 files changed, 744 insertions(+), 56 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
>>  create mode 100644 drivers/power/ab8500_bmdata.c
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
>> index ce83c8d..762dc11 100644
>> --- a/Documentation/devicetree/bindings/mfd/ab8500.txt
>> +++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
>> @@ -24,7 +24,13 @@ ab8500-bm                :                      :              : Battery Manager
>>  ab8500-btemp             :                      :              : Battery Temperature
>>  ab8500-charger           :                      :              : Battery Charger
>>  ab8500-codec             :                      :              : Audio Codec
>> -ab8500-fg                :                      :              : Fuel Gauge
>> +ab8500-fg                :                   : vddadc       : Fuel Gauge
>> +                      : NCONV_ACCU           :              : Accumulate N Sample Conversion
>> +                      : BATT_OVV             :              : Battery Over Voltage
>> +                      : LOW_BAT_F            :              : LOW threshold battery voltage
>> +                      : CC_INT_CALIB         :              : Counter Counter Internal Calibration
> 
> I think you mean: Coulomb Counter.
> 
>> +                      : CCEOC                :              : Coulomb Counter End of Conversion
>> +                      :                      :              :
> 
> Random empty entry.
> 
>>  ab8500-gpadc             : HW_CONV_END          : vddadc       : Analogue to Digital Converter
>>                             SW_CONV_END          :              :
>>  ab8500-gpio              :                      :              : GPIO Controller
>> diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
>> new file mode 100644
>> index 0000000..caa33b0
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
>> @@ -0,0 +1,86 @@
>> +=== AB8500 Fuel Gauge Driver ===
>> +
>> +AB8500 is a mixed signal multimedia and power management
>> +device comprising: power and energy-management-module,
>> +wall-charger, usb-charger, audio codec, general purpose adc,
>> +tvout, clock management and sim card interface.
>> +
>> +Fuel-guage support is part of energy-management-module, the other
> 
> Spelling.
> 
>> +components of this module are:
>> +main-charger, usb-combo-charger and Battery temperature monitoring.
>> +
>> +The properties below describes the node for fuel guage driver.
> 
> Spelling.
> 
>> +
>> +Required Properties:
>> +- compatible = "stericsson,ab8500-fg"
>> +- interface-name:
>> +     Name of the controller/driver which is part of energy-management-module
>> +- supplied-to:
> 
> Still not sure about this property, or your justification for use.
> 
>> +     This property shall have dependent nodes which represent other
>> +     energy-management-module.
> 
> Plural?
> 
>> +     This is a logical binding w.r.t power supply events
> 
> Proper English please, no slang.
> 
>> +     across energy-management-module drivers where-in, the
> 
> Ill placed comma?
> 
>> +     runtime battery properties are shared along with uevent
>> +     notification.
> 
> Plural?
> 
>> +     ref: di->fg.external_power_changed =
>> +             ab8500_fg_external_power_changed;
>> +             ab8500_fg.c
>> +
>> +     Need for this property:
>> +             energy-management-module driver updates power-supply properties
>> +             which are subset of events listed in 'enum power_supply_property',
>> +             ref: power_supply.h file
>> +             Event handler invokes power supply change notifier
>> +             which in-turn invokes registered power supply class call-back
>> +             based on the 'supplied-to' string.
>> +             ref:
>> +             power_supply_changed_work(..) ./drivers/power/power_supply_core.c
>> +             di->fg_psy.external_power_changed
>> +
>> +     example:
>> +     ab8500-fg {
>> +             /* dependent energy management modules */
>> +             supplied-to  = <&ab8500_chargalg &ab8500_usb>;
>> +     };
>> +
>> +     ab8500_battery_info: ab8500_bat_type {
>> +             battery-type = <2>;
>> +             thermistor-on-batctrl = <1>;
> 
> You have this as a bool here, and ...
>> +     };
>> +
>> +Other dependent node for fuel-gauge is:
>> +     ab8500_battery_info: ab8500_bat_type {
>> +     };
>> +     This node will provide information on 'thermistor interface' and
>> +     'battery technology type' used.
>> +
>> +Properties of this node are:
>> +thermistor-on-batctrl:
>> +     A boolean value indicating thermistor interface to battery
>> +
>> +     Note:
>> +     'btemp' and 'batctrl' are the pins interfaced for battery temperature
>> +     measurement, 'btemp' signal is used when NTC(negative temperature
>> +     coefficient) resister is interfaced external to battery whereas
>> +     'batctrl' pin is used when NTC resister is internal to battery.
>> +
>> +     e.g:
>> +     ab8500_battery_info: ab8500_bat_type {
>> +             thermistor-on-batctrl;
> 
> ... a standard property here. I suggest you drop the bool value.
> 
>> +     };
>> +     indiactes: NTC resister is internal to battery, 'batctrl' is used
>> +             for thermal measurement.
>> +
>> +     The absence of property 'thermal-on-batctrl' indicates
>> +     NTC resister is external to battery and  'btemp' signal is used
>> +     for thermal measurement.
>> +
>> +battery-type:
>> +     This shall be the battery manufacturing technology type,
>> +     allowed types are:
>> +             "UNKNOWN" "NiMH" "LION" "LIPO" "LiFe" "NiCd" "LiMn"
>> +     e.g:
>> +     ab8500_battery_info: ab8500_bat_type {
>> +             battery-name = "LION";
>> +     }
>> +
>> diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
>> index 748ba7a..bd22c56 100644
>> --- a/arch/arm/boot/dts/dbx5x0.dtsi
>> +++ b/arch/arm/boot/dts/dbx5x0.dtsi
>> @@ -352,8 +352,28 @@
>>                                       vddadc-supply = <&ab8500_ldo_tvout_reg>;
>>                               };
>>
>> -                             ab8500-usb {
>> +                             ab8500_battery_info: ab8500_bat_type {
>> +                                     battery-name = "LION";
> 
> All new properties have to be documented.
> 
> Vendor specific properties should be prepended with the vendor name, so
> either write a generic binding document for all to use or prefix with
> 'stericsson,".
> 
>> +                                     thermistor-on-batctrl;
>> +                             };
>> +
>> +                             ab8500_chargalg: ab8500_chalg {
>> +                                     compatible     = "stericsson,ab8500-chargalg";
>> +                                     interface-name = "ab8500_chargalg";
> 
> Same with all of your new properties (I'll stop mentioning them now).
> 
>> +                                     battery-info   = <&ab8500_battery_info>;
>> +                                     supplied-to    = <&ab8500_fuel_gauge>;
> 
> Weren't you going to reverse this logic to be more inline with how
> the reset of Device Tree works?
> 
>> +                             };
>> +
>> +                             ab8500_fuel_gauge: ab8500_fg {
>> +                                     compatible     = "stericsson,ab8500-fg";
>> +                                     interface-name = "ab8500_fg";
>> +                                     battery-info   = <&ab8500_battery_info>;
>> +                                     supplied-to    = <&ab8500_chargalg &ab8500_usb>;
> 
> As above.
> 
>> +                             };
>> +
>> +                             ab8500_usb: ab8500_usb_if {
> 
> What does 'if' mean?
> 
>>                                       compatible = "stericsson,ab8500-usb";
>> +                                     interface-name = "ab8500_usb";
> 
> Why is this required?
> 
>>                                       interrupts = < 90 0x4
>>                                                      96 0x4
>>                                                      14 0x4
>> diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
>> index 1667c77..6c3d7c2 100644
>> --- a/drivers/mfd/ab8500-core.c
>> +++ b/drivers/mfd/ab8500-core.c
>> @@ -1051,6 +1051,7 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
>>       },
>>       {
>>               .name = "ab8500-fg",
>> +             .of_compatible = "stericsson,ab8500-fg",
>>               .num_resources = ARRAY_SIZE(ab8500_fg_resources),
>>               .resources = ab8500_fg_resources,
>>       },
>> diff --git a/drivers/power/Makefile b/drivers/power/Makefile
>> index ee58afb..2c58d4e 100644
>> --- a/drivers/power/Makefile
>> +++ b/drivers/power/Makefile
>> @@ -34,7 +34,7 @@ obj-$(CONFIG_BATTERY_S3C_ADC)       += s3c_adc_battery.o
>>  obj-$(CONFIG_CHARGER_PCF50633)       += pcf50633-charger.o
>>  obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
>>  obj-$(CONFIG_BATTERY_INTEL_MID)      += intel_mid_battery.o
>> -obj-$(CONFIG_AB8500_BM)              += ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o
>> +obj-$(CONFIG_AB8500_BM)              += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o
>>  obj-$(CONFIG_CHARGER_ISP1704)        += isp1704_charger.o
>>  obj-$(CONFIG_CHARGER_MAX8903)        += max8903_charger.o
>>  obj-$(CONFIG_CHARGER_TWL4030)        += twl4030_charger.o
>> diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c
>> new file mode 100644
>> index 0000000..d0def3b
>> --- /dev/null
>> +++ b/drivers/power/ab8500_bmdata.c
>> @@ -0,0 +1,549 @@
>> +#include <linux/export.h>
>> +#include <linux/power_supply.h>
>> +#include <linux/of.h>
>> +#include <linux/mfd/abx500.h>
>> +#include <linux/mfd/abx500/ab8500.h>
>> +#include <linux/mfd/abx500/ab8500-bm.h>
>> +
>> +/*
>> + * These are the defined batteries that uses a NTC and ID resistor placed
>> + * inside of the battery pack.
>> + * Note that the res_to_temp table must be strictly sorted by falling resistance
>> + * values to work.
>> + */
>> +static struct abx500_res_to_temp temp_tbl_A_thermistor[] = {
>> +     {-5, 53407},
>> +     { 0, 48594},
>> +     { 5, 43804},
>> +     {10, 39188},
>> +     {15, 34870},
>> +     {20, 30933},
>> +     {25, 27422},
>> +     {30, 24347},
>> +     {35, 21694},
>> +     {40, 19431},
>> +     {45, 17517},
>> +     {50, 15908},
>> +     {55, 14561},
>> +     {60, 13437},
>> +     {65, 12500},
>> +};
>> +static struct abx500_res_to_temp temp_tbl_B_thermistor[] = {
>> +     {-5, 165418},
>> +     { 0, 159024},
>> +     { 5, 151921},
>> +     {10, 144300},
>> +     {15, 136424},
>> +     {20, 128565},
>> +     {25, 120978},
>> +     {30, 113875},
>> +     {35, 107397},
>> +     {40, 101629},
>> +     {45,  96592},
>> +     {50,  92253},
>> +     {55,  88569},
>> +     {60,  85461},
>> +     {65,  82869},
>> +};
>> +static struct abx500_v_to_cap cap_tbl_A_thermistor[] = {
>> +     {4171,  100},
>> +     {4114,   95},
>> +     {4009,   83},
>> +     {3947,   74},
>> +     {3907,   67},
>> +     {3863,   59},
>> +     {3830,   56},
>> +     {3813,   53},
>> +     {3791,   46},
>> +     {3771,   33},
>> +     {3754,   25},
>> +     {3735,   20},
>> +     {3717,   17},
>> +     {3681,   13},
>> +     {3664,    8},
>> +     {3651,    6},
>> +     {3635,    5},
>> +     {3560,    3},
>> +     {3408,    1},
>> +     {3247,    0},
>> +};
>> +static struct abx500_v_to_cap cap_tbl_B_thermistor[] = {
>> +     {4161,  100},
>> +     {4124,   98},
>> +     {4044,   90},
>> +     {4003,   85},
>> +     {3966,   80},
>> +     {3933,   75},
>> +     {3888,   67},
>> +     {3849,   60},
>> +     {3813,   55},
>> +     {3787,   47},
>> +     {3772,   30},
>> +     {3751,   25},
>> +     {3718,   20},
>> +     {3681,   16},
>> +     {3660,   14},
>> +     {3589,   10},
>> +     {3546,    7},
>> +     {3495,    4},
>> +     {3404,    2},
>> +     {3250,    0},
>> +};
>> +
>> +static struct abx500_v_to_cap cap_tbl[] = {
>> +     {4186,  100},
>> +     {4163,   99},
>> +     {4114,   95},
>> +     {4068,   90},
>> +     {3990,   80},
>> +     {3926,   70},
>> +     {3898,   65},
>> +     {3866,   60},
>> +     {3833,   55},
>> +     {3812,   50},
>> +     {3787,   40},
>> +     {3768,   30},
>> +     {3747,   25},
>> +     {3730,   20},
>> +     {3705,   15},
>> +     {3699,   14},
>> +     {3684,   12},
>> +     {3672,    9},
>> +     {3657,    7},
>> +     {3638,    6},
>> +     {3556,    4},
>> +     {3424,    2},
>> +     {3317,    1},
>> +     {3094,    0},
>> +};
>> +
>> +/*
>> + * Note that the res_to_temp table must be strictly sorted by falling
>> + * resistance values to work.
>> + */
>> +static struct abx500_res_to_temp temp_tbl[] = {
>> +     {-5, 214834},
>> +     { 0, 162943},
>> +     { 5, 124820},
>> +     {10,  96520},
>> +     {15,  75306},
>> +     {20,  59254},
>> +     {25,  47000},
>> +     {30,  37566},
>> +     {35,  30245},
>> +     {40,  24520},
>> +     {45,  20010},
>> +     {50,  16432},
>> +     {55,  13576},
>> +     {60,  11280},
>> +     {65,   9425},
>> +};
>> +
>> +/*
>> + * Note that the batres_vs_temp table must be strictly sorted by falling
>> + * temperature values to work.
>> + */
>> +struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {
>> +     { 40, 120},
>> +     { 30, 135},
>> +     { 20, 165},
>> +     { 10, 230},
>> +     { 00, 325},
>> +     {-10, 445},
>> +     {-20, 595},
>> +};
>> +
>> +/*
>> + * Note that the batres_vs_temp table must be strictly sorted by falling
>> + * temperature values to work.
>> + */
>> +struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = {
>> +     { 60, 300},
>> +     { 30, 300},
>> +     { 20, 300},
>> +     { 10, 300},
>> +     { 00, 300},
>> +     {-10, 300},
>> +     {-20, 300},
>> +};
>> +
>> +/* battery resistance table for LI ION 9100 battery */
>> +struct batres_vs_temp temp_to_batres_tbl_9100[] = {
>> +     { 60, 180},
>> +     { 30, 180},
>> +     { 20, 180},
>> +     { 10, 180},
>> +     { 00, 180},
>> +     {-10, 180},
>> +     {-20, 180},
>> +};
>> +
>> +struct abx500_battery_type bat_type_thermistor[] = {
>> +[BATTERY_UNKNOWN] = {
>> +     /* First element always represent the UNKNOWN battery */
>> +     .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
>> +     .resis_high = 0,
>> +     .resis_low = 0,
>> +     .battery_resistance = 300,
>> +     .charge_full_design = 612,
>> +     .nominal_voltage = 3700,
>> +     .termination_vol = 4050,
>> +     .termination_curr = 200,
>> +     .recharge_vol = 3990,
>> +     .normal_cur_lvl = 400,
>> +     .normal_vol_lvl = 4100,
>> +     .maint_a_cur_lvl = 400,
>> +     .maint_a_vol_lvl = 4050,
>> +     .maint_a_chg_timer_h = 60,
>> +     .maint_b_cur_lvl = 400,
>> +     .maint_b_vol_lvl = 4000,
>> +     .maint_b_chg_timer_h = 200,
>> +     .low_high_cur_lvl = 300,
>> +     .low_high_vol_lvl = 4000,
>> +     .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
>> +     .r_to_t_tbl = temp_tbl,
>> +     .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
>> +     .v_to_cap_tbl = cap_tbl,
>> +     .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
>> +     .batres_tbl = temp_to_batres_tbl_thermistor,
>> +},
>> +{
>> +     .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
>> +     .resis_high = 53407,
>> +     .resis_low = 12500,
>> +     .battery_resistance = 300,
>> +     .charge_full_design = 900,
>> +     .nominal_voltage = 3600,
>> +     .termination_vol = 4150,
>> +     .termination_curr = 80,
>> +     .recharge_vol = 4130,
>> +     .normal_cur_lvl = 700,
>> +     .normal_vol_lvl = 4200,
>> +     .maint_a_cur_lvl = 600,
>> +     .maint_a_vol_lvl = 4150,
>> +     .maint_a_chg_timer_h = 60,
>> +     .maint_b_cur_lvl = 600,
>> +     .maint_b_vol_lvl = 4100,
>> +     .maint_b_chg_timer_h = 200,
>> +     .low_high_cur_lvl = 300,
>> +     .low_high_vol_lvl = 4000,
>> +     .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_A_thermistor),
>> +     .r_to_t_tbl = temp_tbl_A_thermistor,
>> +     .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_A_thermistor),
>> +     .v_to_cap_tbl = cap_tbl_A_thermistor,
>> +     .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
>> +     .batres_tbl = temp_to_batres_tbl_thermistor,
>> +
>> +},
>> +{
>> +     .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
>> +     .resis_high = 165418,
>> +     .resis_low = 82869,
>> +     .battery_resistance = 300,
>> +     .charge_full_design = 900,
>> +     .nominal_voltage = 3600,
>> +     .termination_vol = 4150,
>> +     .termination_curr = 80,
>> +     .recharge_vol = 4130,
>> +     .normal_cur_lvl = 700,
>> +     .normal_vol_lvl = 4200,
>> +     .maint_a_cur_lvl = 600,
>> +     .maint_a_vol_lvl = 4150,
>> +     .maint_a_chg_timer_h = 60,
>> +     .maint_b_cur_lvl = 600,
>> +     .maint_b_vol_lvl = 4100,
>> +     .maint_b_chg_timer_h = 200,
>> +     .low_high_cur_lvl = 300,
>> +     .low_high_vol_lvl = 4000,
>> +     .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_B_thermistor),
>> +     .r_to_t_tbl = temp_tbl_B_thermistor,
>> +     .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_B_thermistor),
>> +     .v_to_cap_tbl = cap_tbl_B_thermistor,
>> +     .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
>> +     .batres_tbl = temp_to_batres_tbl_thermistor,
>> +},
>> +};
>> +
>> +struct abx500_battery_type bat_type_ext_thermistor[] = {
>> +[BATTERY_UNKNOWN] = {
>> +     /* First element always represent the UNKNOWN battery */
>> +     .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
>> +     .resis_high = 0,
>> +     .resis_low = 0,
>> +     .battery_resistance = 300,
>> +     .charge_full_design = 612,
>> +     .nominal_voltage = 3700,
>> +     .termination_vol = 4050,
>> +     .termination_curr = 200,
>> +     .recharge_vol = 3990,
>> +     .normal_cur_lvl = 400,
>> +     .normal_vol_lvl = 4100,
>> +     .maint_a_cur_lvl = 400,
>> +     .maint_a_vol_lvl = 4050,
>> +     .maint_a_chg_timer_h = 60,
>> +     .maint_b_cur_lvl = 400,
>> +     .maint_b_vol_lvl = 4000,
>> +     .maint_b_chg_timer_h = 200,
>> +     .low_high_cur_lvl = 300,
>> +     .low_high_vol_lvl = 4000,
>> +     .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
>> +     .r_to_t_tbl = temp_tbl,
>> +     .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
>> +     .v_to_cap_tbl = cap_tbl,
>> +     .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
>> +     .batres_tbl = temp_to_batres_tbl_thermistor,
>> +},
>> +/*
>> + * These are the batteries that doesn't have an internal NTC resistor to measure
>> + * its temperature. The temperature in this case is measure with a NTC placed
>> + * near the battery but on the PCB.
>> + */
>> +{
>> +     .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
>> +     .resis_high = 76000,
>> +     .resis_low = 53000,
>> +     .battery_resistance = 300,
>> +     .charge_full_design = 900,
>> +     .nominal_voltage = 3700,
>> +     .termination_vol = 4150,
>> +     .termination_curr = 100,
>> +     .recharge_vol = 4130,
>> +     .normal_cur_lvl = 700,
>> +     .normal_vol_lvl = 4200,
>> +     .maint_a_cur_lvl = 600,
>> +     .maint_a_vol_lvl = 4150,
>> +     .maint_a_chg_timer_h = 60,
>> +     .maint_b_cur_lvl = 600,
>> +     .maint_b_vol_lvl = 4100,
>> +     .maint_b_chg_timer_h = 200,
>> +     .low_high_cur_lvl = 300,
>> +     .low_high_vol_lvl = 4000,
>> +     .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
>> +     .r_to_t_tbl = temp_tbl,
>> +     .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
>> +     .v_to_cap_tbl = cap_tbl,
>> +     .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
>> +     .batres_tbl = temp_to_batres_tbl_thermistor,
>> +},
>> +{
>> +     .name = POWER_SUPPLY_TECHNOLOGY_LION,
>> +     .resis_high = 30000,
>> +     .resis_low = 10000,
>> +     .battery_resistance = 300,
>> +     .charge_full_design = 950,
>> +     .nominal_voltage = 3700,
>> +     .termination_vol = 4150,
>> +     .termination_curr = 100,
>> +     .recharge_vol = 4130,
>> +     .normal_cur_lvl = 700,
>> +     .normal_vol_lvl = 4200,
>> +     .maint_a_cur_lvl = 600,
>> +     .maint_a_vol_lvl = 4150,
>> +     .maint_a_chg_timer_h = 60,
>> +     .maint_b_cur_lvl = 600,
>> +     .maint_b_vol_lvl = 4100,
>> +     .maint_b_chg_timer_h = 200,
>> +     .low_high_cur_lvl = 300,
>> +     .low_high_vol_lvl = 4000,
>> +     .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
>> +     .r_to_t_tbl = temp_tbl,
>> +     .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
>> +     .v_to_cap_tbl = cap_tbl,
>> +     .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
>> +     .batres_tbl = temp_to_batres_tbl_thermistor,
>> +},
>> +{
>> +     .name = POWER_SUPPLY_TECHNOLOGY_LION,
>> +     .resis_high = 95000,
>> +     .resis_low = 76001,
>> +     .battery_resistance = 300,
>> +     .charge_full_design = 950,
>> +     .nominal_voltage = 3700,
>> +     .termination_vol = 4150,
>> +     .termination_curr = 100,
>> +     .recharge_vol = 4130,
>> +     .normal_cur_lvl = 700,
>> +     .normal_vol_lvl = 4200,
>> +     .maint_a_cur_lvl = 600,
>> +     .maint_a_vol_lvl = 4150,
>> +     .maint_a_chg_timer_h = 60,
>> +     .maint_b_cur_lvl = 600,
>> +     .maint_b_vol_lvl = 4100,
>> +     .maint_b_chg_timer_h = 200,
>> +     .low_high_cur_lvl = 300,
>> +     .low_high_vol_lvl = 4000,
>> +     .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
>> +     .r_to_t_tbl = temp_tbl,
>> +     .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
>> +     .v_to_cap_tbl = cap_tbl,
>> +     .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
>> +     .batres_tbl = temp_to_batres_tbl_thermistor,
>> +},
>> +};
>> +
>> +static const struct abx500_bm_capacity_levels cap_levels = {
>> +     .critical       = 2,
>> +     .low            = 10,
>> +     .normal         = 70,
>> +     .high           = 95,
>> +     .full           = 100,
>> +};
>> +
>> +static const struct abx500_fg_parameters fg = {
>> +     .recovery_sleep_timer = 10,
>> +     .recovery_total_time = 100,
>> +     .init_timer = 1,
>> +     .init_discard_time = 5,
>> +     .init_total_time = 40,
>> +     .high_curr_time = 60,
>> +     .accu_charging = 30,
>> +     .accu_high_curr = 30,
>> +     .high_curr_threshold = 50,
>> +     .lowbat_threshold = 3100,
>> +     .battok_falling_th_sel0 = 2860,
>> +     .battok_raising_th_sel1 = 2860,
>> +     .user_cap_limit = 15,
>> +     .maint_thres = 97,
>> +};
>> +
>> +static const struct abx500_maxim_parameters maxi_params = {
>> +     .ena_maxi = true,
>> +     .chg_curr = 910,
>> +     .wait_cycles = 10,
>> +     .charger_curr_step = 100,
>> +};
>> +
>> +static const struct abx500_bm_charger_parameters chg = {
>> +     .usb_volt_max           = 5500,
>> +     .usb_curr_max           = 1500,
>> +     .ac_volt_max            = 7500,
>> +     .ac_curr_max            = 1500,
>> +};
>> +
>> +struct abx500_bm_data ab8500_bm_data = {
>> +     .temp_under             = 3,
>> +     .temp_low               = 8,
>> +     .temp_high              = 43,
>> +     .temp_over              = 48,
>> +     .main_safety_tmr_h      = 4,
>> +     .temp_interval_chg      = 20,
>> +     .temp_interval_nochg    = 120,
>> +     .usb_safety_tmr_h       = 4,
>> +     .bkup_bat_v             = BUP_VCH_SEL_2P6V,
>> +     .bkup_bat_i             = BUP_ICH_SEL_150UA,
>> +     .no_maintenance         = false,
>> +     .adc_therm              = ABx500_ADC_THERM_BATCTRL,
>> +     .chg_unknown_bat        = false,
>> +     .enable_overshoot       = false,
>> +     .fg_res                 = 100,
>> +     .cap_levels             = &cap_levels,
>> +     .bat_type               = bat_type_thermistor,
>> +     .n_btypes               = 3,
>> +     .batt_id                = 0,
>> +     .interval_charging      = 5,
>> +     .interval_not_charging  = 120,
>> +     .temp_hysteresis        = 3,
>> +     .gnd_lift_resistance    = 34,
>> +     .maxi                   = &maxi_params,
>> +     .chg_params             = &chg,
>> +     .fg_params              = &fg,
>> +};
>> +
>> +int __devinit
>> +bmdevs_of_probe(struct device *dev,
>> +             struct device_node *np,
>> +             struct abx500_bm_plat_data *pdata)
>> +{
>> +     int     i, ret = 0, thermistor = NTC_INTERNAL;
>> +     const   __be32 *ph;
>> +     const   char *bat_tech;
>> +     struct  abx500_bm_data           *bat;
>> +     struct  abx500_battery_type      *btype;
>> +     struct  device_node              *np_bat_supply;
>> +     struct  abx500_bmdevs_plat_data  *plat_data = pdata->bmdev_pdata;
> 
> <nit>
> 
> This spacing is uncharacteristic of Linux drivers.
> 
> Usually, struct declarations come first.
> 
> </nit>
> 
>> +     /* get phandle to 'supplied-to' node */
> 
> I thought you were going to reverse this?
> 
>> +     ph = of_get_property(np, "supplied-to", &plat_data->num_supplicants);
>> +     if (ph == NULL) {
> 
> if (!ph) {
> 
>> +             dev_err(dev, "no supplied_to property specified\n");
>> +             return -EINVAL;
>> +     }
>> +     plat_data->num_supplicants /= sizeof(int);
>> +     plat_data->supplied_to =
>> +             devm_kzalloc(dev, plat_data->num_supplicants *
>> +                     sizeof(const char *), GFP_KERNEL);
>> +     if (plat_data->supplied_to == NULL) {
>> +             dev_err(dev, "%s no mem for supplied-to\n", __func__);
>> +             return -ENOMEM;
>> +     }
>> +     for (i = 0; i < plat_data->num_supplicants; ++i) {
>> +             np_bat_supply = of_find_node_by_phandle(be32_to_cpup(ph) + i);
> 
> Use: of_parse_phandle(np, "supplied-to", i) instead.
> 
>> +             if (np_bat_supply == NULL) {
> 
> if (!np_bat_supply) {
> 
>> +                     dev_err(dev, "invalid supplied_to property\n");
>> +                     return -EINVAL;
>> +             }
>> +             ret = of_property_read_string(np_bat_supply, "interface-name",
>> +                             (const char **)(plat_data->supplied_to + i));
>> +             if (ret < 0) {
>> +                     of_node_put(np_bat_supply);
>> +                     dev_err(dev, "supply/interface name not found\n");
>> +                     return ret;
>> +             }
>> +             dev_dbg(dev, "%s power supply interface_name:%s\n",
>> +                     __func__, *(plat_data->supplied_to + i));
>> +     }
> 
> <remove>
> 
>> +     /* get phandle to 'battery-info' node */
>> +     ph = of_get_property(np, "battery-info", NULL);
>> +     if (ph == NULL) {
>> +             dev_err(dev, "missing property battery-info\n");
>> +             return -EINVAL;
>> +     }
>> +     np_bat_supply = of_find_node_by_phandle(be32_to_cpup(ph));
> 
> </remove>
> 
> ... and replace with: np_bat_supply = of_parse_phandle(np, "battery-info", 0) instead.
> 
>> +     if (np_bat_supply == NULL) {
> 
> if (!np_bat_supply) {
> 
> I'll not mention this again.
> 
>> +             dev_err(dev, "invalid battery-info node\n");
>> +             return -EINVAL;
>> +     }
>> +     if (of_property_read_bool(np_bat_supply,
>> +                     "thermistor-on-batctrl") == false){
> 
> Replace with:
>         if (of_get_property(np_bat_supply, "thermistor-on-batctr", NULL))
>                 np_bat_supply =  true;
> 
> <remove>
> 
>> +             dev_warn(dev, "missing property thermistor-on-batctrl\n");
>> +             thermistor = NTC_EXTERNAL;
>> +     }
> 
> </remove>
> 
>> +     pdata->battery = &ab8500_bm_data;
>> +     bat = pdata->battery;
> 
> Why not: bat = &ab8500_bm_data
> 
> Or just use ab8500_bm_data in its own right?
> 
>> +     if (thermistor == NTC_EXTERNAL) {
>> +             bat->n_btypes  = 4;
>> +             bat->bat_type  = bat_type_ext_thermistor;
>> +             bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
>> +     }
>> +     ret = of_property_read_string(np_bat_supply, "battery-name", &bat_tech);
>> +     if (ret < 0) {
>> +             dev_warn(dev, "missing property battery-name/type\n");
>> +             bat_tech = "UNKNOWN";
>> +     }
>> +     of_node_put(np_bat_supply);
>> +     if (strcmp(bat_tech, "LION") == 0) {
>> +             bat->no_maintenance  = true;
>> +             bat->chg_unknown_bat = true;
>> +             bat->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600;
>> +             bat->bat_type[BATTERY_UNKNOWN].termination_vol    = 4150;
>> +             bat->bat_type[BATTERY_UNKNOWN].recharge_vol       = 4130;
>> +             bat->bat_type[BATTERY_UNKNOWN].normal_cur_lvl     = 520;
>> +             bat->bat_type[BATTERY_UNKNOWN].normal_vol_lvl     = 4200;
>> +     }
>> +     /* select the battery resolution table */
>> +     for (i = 0; i < bat->n_btypes; ++i) {
>> +             btype = (bat->bat_type + i);
>> +             if (thermistor == NTC_EXTERNAL) {
>> +                     btype->batres_tbl =
>> +                             temp_to_batres_tbl_ext_thermistor;
>> +             } else if (strcmp(bat_tech, "LION") == 0) {
> 
> Isn't strncmp safer, since you know the size of the comparison?
> 
>> +                     btype->batres_tbl =
>> +                             temp_to_batres_tbl_9100;
>> +             } else {
>> +                     btype->batres_tbl =
>> +                             temp_to_batres_tbl_thermistor;
>> +             }
>> +     }
>> +     return 0;
>> +}
>> +EXPORT_SYMBOL(bmdevs_of_probe);
> 
> Why are you exporting?
> 
>> diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
>> index bba3cca..8e427e7 100644
>> --- a/drivers/power/ab8500_btemp.c
>> +++ b/drivers/power/ab8500_btemp.c
>> @@ -93,7 +93,7 @@ struct ab8500_btemp {
>>       struct ab8500 *parent;
>>       struct ab8500_gpadc *gpadc;
>>       struct ab8500_fg *fg;
>> -     struct abx500_btemp_platform_data *pdata;
>> +     struct abx500_bmdevs_plat_data *pdata;
>>       struct abx500_bm_data *bat;
>>       struct power_supply btemp_psy;
>>       struct ab8500_btemp_events events;
>> @@ -982,7 +982,7 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
>>       di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
>>
>>       /* get btemp specific platform data */
>> -     di->pdata = plat_data->btemp;
>> +     di->pdata = plat_data->bmdev_pdata;
>>       if (!di->pdata) {
>>               dev_err(di->dev, "no btemp platform data supplied\n");
>>               ret = -EINVAL;
>> diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
>> index d4f0c98..5ff0d83 100644
>> --- a/drivers/power/ab8500_charger.c
>> +++ b/drivers/power/ab8500_charger.c
>> @@ -220,7 +220,7 @@ struct ab8500_charger {
>>       bool autopower;
>>       struct ab8500 *parent;
>>       struct ab8500_gpadc *gpadc;
>> -     struct abx500_charger_platform_data *pdata;
>> +     struct abx500_bmdevs_plat_data *pdata;
>>       struct abx500_bm_data *bat;
>>       struct ab8500_charger_event_flags flags;
>>       struct ab8500_charger_usb_state usb_state;
>> @@ -2555,7 +2555,7 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
>>       spin_lock_init(&di->usb_state.usb_lock);
>>
>>       /* get charger specific platform data */
>> -     di->pdata = plat_data->charger;
>> +     di->pdata = plat_data->bmdev_pdata;
>>       if (!di->pdata) {
>>               dev_err(di->dev, "no charger platform data supplied\n");
>>               ret = -EINVAL;
>> diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
>> index bf02225..96741b8 100644
>> --- a/drivers/power/ab8500_fg.c
>> +++ b/drivers/power/ab8500_fg.c
>> @@ -22,15 +22,14 @@
>>  #include <linux/platform_device.h>
>>  #include <linux/power_supply.h>
>>  #include <linux/kobject.h>
>> -#include <linux/mfd/abx500/ab8500.h>
>> -#include <linux/mfd/abx500.h>
>>  #include <linux/slab.h>
>> -#include <linux/mfd/abx500/ab8500-bm.h>
>>  #include <linux/delay.h>
>> -#include <linux/mfd/abx500/ab8500-gpadc.h>
>> -#include <linux/mfd/abx500.h>
>>  #include <linux/time.h>
>>  #include <linux/completion.h>
>> +#include <linux/mfd/abx500.h>
>> +#include <linux/mfd/abx500/ab8500.h>
>> +#include <linux/mfd/abx500/ab8500-bm.h>
>> +#include <linux/mfd/abx500/ab8500-gpadc.h>
>>
>>  #define MILLI_TO_MICRO                       1000
>>  #define FG_LSB_IN_MA                 1627
>> @@ -212,7 +211,7 @@ struct ab8500_fg {
>>       struct ab8500_fg_avg_cap avg_cap;
>>       struct ab8500 *parent;
>>       struct ab8500_gpadc *gpadc;
>> -     struct abx500_fg_platform_data *pdata;
>> +     struct abx500_bmdevs_plat_data *pdata;
>>       struct abx500_bm_data *bat;
>>       struct power_supply fg_psy;
>>       struct workqueue_struct *fg_wq;
>> @@ -544,14 +543,14 @@ cc_err:
>>               ret = abx500_set_register_interruptible(di->dev,
>>                       AB8500_GAS_GAUGE, AB8500_GASG_CC_NCOV_ACCU,
>>                       SEC_TO_SAMPLE(10));
>> -             if (ret)
>> +             if (ret < 0)
> 
> I don't 'think' this change is required. abx500_set_register_interruptible
> will only return !0 on error.
> 
>>                       goto fail;
>>
>>               /* Start the CC */
>>               ret = abx500_set_register_interruptible(di->dev, AB8500_RTC,
>>                       AB8500_RTC_CC_CONF_REG,
>>                       (CC_DEEP_SLEEP_ENA | CC_PWR_UP_ENA));
>> -             if (ret)
>> +             if (ret < 0)
>>                       goto fail;
>>       } else {
>>               di->turn_off_fg = false;
>> @@ -2429,7 +2428,6 @@ static int __devexit ab8500_fg_remove(struct platform_device *pdev)
>>       flush_scheduled_work();
>>       power_supply_unregister(&di->fg_psy);
>>       platform_set_drvdata(pdev, NULL);
>> -     kfree(di);
>>       return ret;
>>  }
>>
>> @@ -2446,18 +2444,47 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
>>  {
>>       int i, irq;
>>       int ret = 0;
>> -     struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
>> +     struct abx500_bm_plat_data *plat_data
>> +                             = pdev->dev.platform_data;
>> +     struct device_node *np  = pdev->dev.of_node;
>>       struct ab8500_fg *di;
>>
>> +     di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
>> +     if (!di) {
>> +             dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__);
>> +             return -ENOMEM;
>> +     }
>> +     if (np) {
>> +             if (!plat_data) {
> 
> Change these around.
> 
> if (!plat_data) {
>         if (np) {
>                 <snip>
>         } else {
>                 <ERROR>
>         }
> }
> 
>> +                     plat_data =
>> +                     devm_kzalloc(&pdev->dev, sizeof(*plat_data),
>> +                                     GFP_KERNEL);
>> +                     if (!plat_data) {
>> +                             dev_err(&pdev->dev,
>> +                                     "%s no mem for plat_data\n", __func__);
>> +                             return -ENOMEM;
>> +                     }
>> +                     plat_data->bmdev_pdata = devm_kzalloc(&pdev->dev,
>> +                             sizeof(*plat_data->bmdev_pdata), GFP_KERNEL);
>> +                     if (!plat_data->bmdev_pdata) {
>> +                             dev_err(&pdev->dev,
>> +                                     "%s no mem for pdata->fg\n",
>> +                                     __func__);
>> +                             return -ENOMEM;
>> +                     }
>> +             }
>> +             ret = bmdevs_of_probe(&pdev->dev, np, plat_data);
>> +             if (ret < 0) {
>> +                     dev_err(&pdev->dev, "failed to get platform data\n");
>> +                     return ret;
>> +             }
>> +     }
> 
> <remove>
> 
>>       if (!plat_data) {
>> -             dev_err(&pdev->dev, "No platform data\n");
>> +             dev_err(&pdev->dev,
>> +                     "%s no fg platform data found\n", __func__);
>>               return -EINVAL;
>>       }
> </remove>
> 
>> -     di = kzalloc(sizeof(*di), GFP_KERNEL);
>> -     if (!di)
>> -             return -ENOMEM;
>> -
>>       mutex_init(&di->cc_lock);
>>
>>       /* get parent data */
>> @@ -2466,19 +2493,17 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
>>       di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
>>
>>       /* get fg specific platform data */
>> -     di->pdata = plat_data->fg;
>> +     di->pdata = plat_data->bmdev_pdata;
>>       if (!di->pdata) {
>>               dev_err(di->dev, "no fg platform data supplied\n");
>> -             ret = -EINVAL;
>> -             goto free_device_info;
>> +             return -EINVAL;
>>       }
>>
>>       /* get battery specific platform data */
>>       di->bat = plat_data->battery;
>>       if (!di->bat) {
>>               dev_err(di->dev, "no battery platform data supplied\n");
>> -             ret = -EINVAL;
>> -             goto free_device_info;
>> +             return -EINVAL;
>>       }
>>
>>       di->fg_psy.name = "ab8500_fg";
>> @@ -2506,7 +2531,7 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
>>       di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq");
>>       if (di->fg_wq == NULL) {
>>               dev_err(di->dev, "failed to create work queue\n");
>> -             goto free_device_info;
>> +             return -ENOMEM;
>>       }
>>
>>       /* Init work for running the fg algorithm instantly */
>> @@ -2605,12 +2630,14 @@ free_irq:
>>       }
>>  free_inst_curr_wq:
>>       destroy_workqueue(di->fg_wq);
>> -free_device_info:
>> -     kfree(di);
>> -
>>       return ret;
>>  }
>>
>> +static const struct of_device_id ab8500_fg_match[] = {
>> +     {.compatible = "stericsson,ab8500-fg",},
> 
> <nit>
> 
> Spaces:
> 
> { .compatible = "stericsson,ab8500-fg", },
> 
> </nit>
> 
>> +     {},
>> +};
>> +
>>  static struct platform_driver ab8500_fg_driver = {
>>       .probe = ab8500_fg_probe,
>>       .remove = __devexit_p(ab8500_fg_remove),
>> @@ -2619,6 +2646,7 @@ static struct platform_driver ab8500_fg_driver = {
>>       .driver = {
>>               .name = "ab8500-fg",
>>               .owner = THIS_MODULE,
>> +             .of_match_table = ab8500_fg_match,
>>       },
>>  };
>>
>> diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
>> index 804b88c..ba548e4 100644
>> --- a/drivers/power/abx500_chargalg.c
>> +++ b/drivers/power/abx500_chargalg.c
>> @@ -231,7 +231,7 @@ struct abx500_chargalg {
>>       struct abx500_chargalg_charger_info chg_info;
>>       struct abx500_chargalg_battery_data batt_data;
>>       struct abx500_chargalg_suspension_status susp_status;
>> -     struct abx500_chargalg_platform_data *pdata;
>> +     struct abx500_bmdevs_plat_data *pdata;
>>       struct abx500_bm_data *bat;
>>       struct power_supply chargalg_psy;
>>       struct ux500_charger *ac_chg;
>> @@ -1814,7 +1814,7 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
>>       di->dev = &pdev->dev;
>>
>>       plat_data = pdev->dev.platform_data;
>> -     di->pdata = plat_data->chargalg;
>> +     di->pdata = plat_data->bmdev_pdata;
>>       di->bat = plat_data->battery;
>>
>>       /* chargalg supply */
>> diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
>> index 1318ca6..286f8ac 100644
>> --- a/include/linux/mfd/abx500.h
>> +++ b/include/linux/mfd/abx500.h
>> @@ -382,39 +382,30 @@ struct abx500_bm_data {
>>       int gnd_lift_resistance;
>>       const struct abx500_maxim_parameters *maxi;
>>       const struct abx500_bm_capacity_levels *cap_levels;
>> -     const struct abx500_battery_type *bat_type;
>> +     struct abx500_battery_type *bat_type;
>>       const struct abx500_bm_charger_parameters *chg_params;
>>       const struct abx500_fg_parameters *fg_params;
>>  };
>>
>> -struct abx500_chargalg_platform_data {
>> -     char **supplied_to;
>> -     size_t num_supplicants;
>> +struct abx500_bmdevs_plat_data {
>> +     char    **supplied_to;
>> +     size_t  num_supplicants;
>> +     bool    autopower_cfg;
>>  };
>>
>> -struct abx500_charger_platform_data {
>> -     char **supplied_to;
>> -     size_t num_supplicants;
>> -     bool autopower_cfg;
>> -};
>> -
>> -struct abx500_btemp_platform_data {
>> -     char **supplied_to;
>> -     size_t num_supplicants;
>> +struct abx500_bm_plat_data {
>> +     struct abx500_bm_data *battery;
>> +     struct abx500_bmdevs_plat_data *bmdev_pdata;
>>  };
>>
>> -struct abx500_fg_platform_data {
>> -     char **supplied_to;
>> -     size_t num_supplicants;
>> +enum {
>> +     NTC_EXTERNAL = 0,
>> +     NTC_INTERNAL,
>>  };
>>
>> -struct abx500_bm_plat_data {
>> -     struct abx500_bm_data *battery;
>> -     struct abx500_charger_platform_data *charger;
>> -     struct abx500_btemp_platform_data *btemp;
>> -     struct abx500_fg_platform_data *fg;
>> -     struct abx500_chargalg_platform_data *chargalg;
>> -};
>> +int bmdevs_of_probe(struct device *dev,
>> +             struct device_node *np,
>> +             struct abx500_bm_plat_data *pdata);
>>
>>  int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
>>       u8 value);
>> diff --git a/include/linux/mfd/abx500/ab8500-bm.h b/include/linux/mfd/abx500/ab8500-bm.h
>> index 44310c9..d15b7f1 100644
>> --- a/include/linux/mfd/abx500/ab8500-bm.h
>> +++ b/include/linux/mfd/abx500/ab8500-bm.h
>> @@ -422,6 +422,13 @@ struct ab8500_chargalg_platform_data {
>>  struct ab8500_btemp;
>>  struct ab8500_gpadc;
>>  struct ab8500_fg;
>> +
>> +extern struct abx500_bm_data ab8500_bm_data;
>> +extern struct abx500_battery_type bat_type_ext_thermistor[];
>> +extern struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[];
>> +extern struct batres_vs_temp temp_to_batres_tbl_9100[];
>> +extern struct batres_vs_temp temp_to_batres_tbl_thermistor[];
>> +
>>  #ifdef CONFIG_AB8500_BM
>>  void ab8500_fg_reinit(void);
>>  void ab8500_charger_usb_state_changed(u8 bm_usb_state, u16 mA);
>> --
>> 1.7.9.5
>>
> 
> --
> Lee Jones
> Linaro ST-Ericsson Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
> 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge
       [not found] ` <1349064513-31301-2-git-send-email-rajanikanth.hv@stericsson.com>
@ 2012-10-01  9:49   ` Lee Jones
  2012-10-01  9:59     ` Rajanikanth HV
  2012-10-01 10:22     ` Lee Jones
  2012-10-06 14:01   ` Francesco Lavra
  1 sibling, 2 replies; 23+ messages in thread
From: Lee Jones @ 2012-10-01  9:49 UTC (permalink / raw)
  To: Rajanikanth H.V
  Cc: francescolavra.fl, arnd, anton.vorontsov, linus.walleij,
	linux-arm-kernel, linux-kernel, linaro-dev, patches,
	STEricsson_nomadik_linux

On Mon, 01 Oct 2012, Rajanikanth H.V wrote:

> From: "Rajanikanth H.V" <rajanikanth.hv@stericsson.com>
> 
> - This patch adds device tree support for fuelguage driver
> - optimize bm devices platform_data usage and of_probe(...)
>   Note: of_probe() routine for battery managed devices is made
>   common across all bm drivers.
> 
> Signed-off-by: Rajanikanth H.V <rajanikanth.hv@stericsson.com>
> ---
>  Documentation/devicetree/bindings/mfd/ab8500.txt   |    8 +-
>  .../devicetree/bindings/power_supply/ab8500/fg.txt |   86 +++
>  arch/arm/boot/dts/dbx5x0.dtsi                      |   22 +-
>  drivers/mfd/ab8500-core.c                          |    1 +
>  drivers/power/Makefile                             |    2 +-
>  drivers/power/ab8500_bmdata.c                      |  549 ++++++++++++++++++++
>  drivers/power/ab8500_btemp.c                       |    4 +-
>  drivers/power/ab8500_charger.c                     |    4 +-
>  drivers/power/ab8500_fg.c                          |   76 ++-
>  drivers/power/abx500_chargalg.c                    |    4 +-
>  include/linux/mfd/abx500.h                         |   37 +-
>  include/linux/mfd/abx500/ab8500-bm.h               |    7 +
>  12 files changed, 744 insertions(+), 56 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
>  create mode 100644 drivers/power/ab8500_bmdata.c
> 
> diff --git a/Documentation/devicetree/bindings/mfd/ab8500.txt b/Documentation/devicetree/bindings/mfd/ab8500.txt
> index ce83c8d..762dc11 100644
> --- a/Documentation/devicetree/bindings/mfd/ab8500.txt
> +++ b/Documentation/devicetree/bindings/mfd/ab8500.txt
> @@ -24,7 +24,13 @@ ab8500-bm                :                      :              : Battery Manager
>  ab8500-btemp             :                      :              : Battery Temperature
>  ab8500-charger           :                      :              : Battery Charger
>  ab8500-codec             :                      :              : Audio Codec
> -ab8500-fg                :                      :              : Fuel Gauge
> +ab8500-fg                : 			: vddadc       : Fuel Gauge
> +			 : NCONV_ACCU           :	       : Accumulate N Sample Conversion
> +			 : BATT_OVV		:	       : Battery Over Voltage
> +			 : LOW_BAT_F		:	       : LOW threshold battery voltage
> +			 : CC_INT_CALIB		:	       : Counter Counter Internal Calibration

I think you mean: Coulomb Counter.

> +			 : CCEOC		:	       : Coulomb Counter End of Conversion
> +			 :			:	       :

Random empty entry.

>  ab8500-gpadc             : HW_CONV_END          : vddadc       : Analogue to Digital Converter
>                             SW_CONV_END          :              :
>  ab8500-gpio              :                      :              : GPIO Controller
> diff --git a/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
> new file mode 100644
> index 0000000..caa33b0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power_supply/ab8500/fg.txt
> @@ -0,0 +1,86 @@
> +=== AB8500 Fuel Gauge Driver ===
> +
> +AB8500 is a mixed signal multimedia and power management
> +device comprising: power and energy-management-module,
> +wall-charger, usb-charger, audio codec, general purpose adc,
> +tvout, clock management and sim card interface.
> +
> +Fuel-guage support is part of energy-management-module, the other

Spelling.

> +components of this module are:
> +main-charger, usb-combo-charger and Battery temperature monitoring.
> +
> +The properties below describes the node for fuel guage driver.

Spelling.

> +
> +Required Properties:
> +- compatible = "stericsson,ab8500-fg"
> +- interface-name:
> +	Name of the controller/driver which is part of energy-management-module
> +- supplied-to:

Still not sure about this property, or your justification for use.

> +	This property shall have dependent nodes which represent other
> +	energy-management-module.

Plural?

> +	This is a logical binding w.r.t power supply events

Proper English please, no slang.

> +	across energy-management-module drivers where-in, the

Ill placed comma?

> +	runtime battery properties are shared along with uevent
> +	notification.

Plural?

> +	ref: di->fg.external_power_changed =
> +		ab8500_fg_external_power_changed;
> +		ab8500_fg.c
> +
> +	Need for this property:
> +		energy-management-module driver updates power-supply properties
> +		which are subset of events listed in 'enum power_supply_property',
> +		ref: power_supply.h file
> +		Event handler invokes power supply change notifier
> +		which in-turn invokes registered power supply class call-back
> +		based on the 'supplied-to' string.
> +		ref:
> +		power_supply_changed_work(..) ./drivers/power/power_supply_core.c
> +		di->fg_psy.external_power_changed
> +
> +	example:
> +	ab8500-fg {
> +		/* dependent energy management modules */
> +		supplied-to  = <&ab8500_chargalg &ab8500_usb>;
> +	};
> +
> +	ab8500_battery_info: ab8500_bat_type {
> +		battery-type = <2>;
> +		thermistor-on-batctrl = <1>;

You have this as a bool here, and ...
> +	};
> +
> +Other dependent node for fuel-gauge is:
> +	ab8500_battery_info: ab8500_bat_type {
> +	};
> +	This node will provide information on 'thermistor interface' and
> +	'battery technology type' used.
> +
> +Properties of this node are:
> +thermistor-on-batctrl:
> +	A boolean value indicating thermistor interface	to battery
> +
> +	Note:
> +	'btemp' and 'batctrl' are the pins interfaced for battery temperature
> +	measurement, 'btemp' signal is used when NTC(negative temperature
> +	coefficient) resister is interfaced external to battery whereas
> +	'batctrl' pin is used when NTC resister is internal to battery.
> +
> +	e.g:
> +	ab8500_battery_info: ab8500_bat_type {
> +		thermistor-on-batctrl;

... a standard property here. I suggest you drop the bool value.

> +	};
> +	indiactes: NTC resister is internal to battery, 'batctrl' is used
> +		for thermal measurement.
> +
> +	The absence of property 'thermal-on-batctrl' indicates
> +	NTC resister is external to battery and  'btemp' signal is used
> +	for thermal measurement.
> +
> +battery-type:
> +	This shall be the battery manufacturing technology type,
> +	allowed types are:
> +		"UNKNOWN" "NiMH" "LION" "LIPO" "LiFe" "NiCd" "LiMn"
> +	e.g:
> +	ab8500_battery_info: ab8500_bat_type {
> +		battery-name = "LION";
> +	}
> +
> diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi
> index 748ba7a..bd22c56 100644
> --- a/arch/arm/boot/dts/dbx5x0.dtsi
> +++ b/arch/arm/boot/dts/dbx5x0.dtsi
> @@ -352,8 +352,28 @@
>  					vddadc-supply = <&ab8500_ldo_tvout_reg>;
>  				};
>  
> -				ab8500-usb {
> +				ab8500_battery_info: ab8500_bat_type {
> +					battery-name = "LION";

All new properties have to be documented.

Vendor specific properties should be prepended with the vendor name, so
either write a generic binding document for all to use or prefix with
'stericsson,".

> +					thermistor-on-batctrl;
> +				};
> +
> +				ab8500_chargalg: ab8500_chalg {
> +					compatible     = "stericsson,ab8500-chargalg";
> +					interface-name = "ab8500_chargalg";

Same with all of your new properties (I'll stop mentioning them now).

> +					battery-info   = <&ab8500_battery_info>;
> +					supplied-to    = <&ab8500_fuel_gauge>;

Weren't you going to reverse this logic to be more inline with how
the reset of Device Tree works?

> +				};
> +
> +				ab8500_fuel_gauge: ab8500_fg {
> +					compatible     = "stericsson,ab8500-fg";
> +					interface-name = "ab8500_fg";
> +					battery-info   = <&ab8500_battery_info>;
> +					supplied-to    = <&ab8500_chargalg &ab8500_usb>;

As above.

> +				};
> +
> +				ab8500_usb: ab8500_usb_if {

What does 'if' mean?

>  					compatible = "stericsson,ab8500-usb";
> +					interface-name = "ab8500_usb";

Why is this required?

>  					interrupts = < 90 0x4
>  						       96 0x4
>  						       14 0x4
> diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
> index 1667c77..6c3d7c2 100644
> --- a/drivers/mfd/ab8500-core.c
> +++ b/drivers/mfd/ab8500-core.c
> @@ -1051,6 +1051,7 @@ static struct mfd_cell __devinitdata ab8500_bm_devs[] = {
>  	},
>  	{
>  		.name = "ab8500-fg",
> +		.of_compatible = "stericsson,ab8500-fg",
>  		.num_resources = ARRAY_SIZE(ab8500_fg_resources),
>  		.resources = ab8500_fg_resources,
>  	},
> diff --git a/drivers/power/Makefile b/drivers/power/Makefile
> index ee58afb..2c58d4e 100644
> --- a/drivers/power/Makefile
> +++ b/drivers/power/Makefile
> @@ -34,7 +34,7 @@ obj-$(CONFIG_BATTERY_S3C_ADC)	+= s3c_adc_battery.o
>  obj-$(CONFIG_CHARGER_PCF50633)	+= pcf50633-charger.o
>  obj-$(CONFIG_BATTERY_JZ4740)	+= jz4740-battery.o
>  obj-$(CONFIG_BATTERY_INTEL_MID)	+= intel_mid_battery.o
> -obj-$(CONFIG_AB8500_BM)		+= ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o
> +obj-$(CONFIG_AB8500_BM)		+= ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o
>  obj-$(CONFIG_CHARGER_ISP1704)	+= isp1704_charger.o
>  obj-$(CONFIG_CHARGER_MAX8903)	+= max8903_charger.o
>  obj-$(CONFIG_CHARGER_TWL4030)	+= twl4030_charger.o
> diff --git a/drivers/power/ab8500_bmdata.c b/drivers/power/ab8500_bmdata.c
> new file mode 100644
> index 0000000..d0def3b
> --- /dev/null
> +++ b/drivers/power/ab8500_bmdata.c
> @@ -0,0 +1,549 @@
> +#include <linux/export.h>
> +#include <linux/power_supply.h>
> +#include <linux/of.h>
> +#include <linux/mfd/abx500.h>
> +#include <linux/mfd/abx500/ab8500.h>
> +#include <linux/mfd/abx500/ab8500-bm.h>
> +
> +/*
> + * These are the defined batteries that uses a NTC and ID resistor placed
> + * inside of the battery pack.
> + * Note that the res_to_temp table must be strictly sorted by falling resistance
> + * values to work.
> + */
> +static struct abx500_res_to_temp temp_tbl_A_thermistor[] = {
> +	{-5, 53407},
> +	{ 0, 48594},
> +	{ 5, 43804},
> +	{10, 39188},
> +	{15, 34870},
> +	{20, 30933},
> +	{25, 27422},
> +	{30, 24347},
> +	{35, 21694},
> +	{40, 19431},
> +	{45, 17517},
> +	{50, 15908},
> +	{55, 14561},
> +	{60, 13437},
> +	{65, 12500},
> +};
> +static struct abx500_res_to_temp temp_tbl_B_thermistor[] = {
> +	{-5, 165418},
> +	{ 0, 159024},
> +	{ 5, 151921},
> +	{10, 144300},
> +	{15, 136424},
> +	{20, 128565},
> +	{25, 120978},
> +	{30, 113875},
> +	{35, 107397},
> +	{40, 101629},
> +	{45,  96592},
> +	{50,  92253},
> +	{55,  88569},
> +	{60,  85461},
> +	{65,  82869},
> +};
> +static struct abx500_v_to_cap cap_tbl_A_thermistor[] = {
> +	{4171,	100},
> +	{4114,	 95},
> +	{4009,	 83},
> +	{3947,	 74},
> +	{3907,	 67},
> +	{3863,	 59},
> +	{3830,	 56},
> +	{3813,	 53},
> +	{3791,	 46},
> +	{3771,	 33},
> +	{3754,	 25},
> +	{3735,	 20},
> +	{3717,	 17},
> +	{3681,	 13},
> +	{3664,	  8},
> +	{3651,	  6},
> +	{3635,	  5},
> +	{3560,	  3},
> +	{3408,    1},
> +	{3247,	  0},
> +};
> +static struct abx500_v_to_cap cap_tbl_B_thermistor[] = {
> +	{4161,	100},
> +	{4124,	 98},
> +	{4044,	 90},
> +	{4003,	 85},
> +	{3966,	 80},
> +	{3933,	 75},
> +	{3888,	 67},
> +	{3849,	 60},
> +	{3813,	 55},
> +	{3787,	 47},
> +	{3772,	 30},
> +	{3751,	 25},
> +	{3718,	 20},
> +	{3681,	 16},
> +	{3660,	 14},
> +	{3589,	 10},
> +	{3546,	  7},
> +	{3495,	  4},
> +	{3404,	  2},
> +	{3250,	  0},
> +};
> +
> +static struct abx500_v_to_cap cap_tbl[] = {
> +	{4186,	100},
> +	{4163,	 99},
> +	{4114,	 95},
> +	{4068,	 90},
> +	{3990,	 80},
> +	{3926,	 70},
> +	{3898,	 65},
> +	{3866,	 60},
> +	{3833,	 55},
> +	{3812,	 50},
> +	{3787,	 40},
> +	{3768,	 30},
> +	{3747,	 25},
> +	{3730,	 20},
> +	{3705,	 15},
> +	{3699,	 14},
> +	{3684,	 12},
> +	{3672,	  9},
> +	{3657,	  7},
> +	{3638,	  6},
> +	{3556,	  4},
> +	{3424,	  2},
> +	{3317,	  1},
> +	{3094,	  0},
> +};
> +
> +/*
> + * Note that the res_to_temp table must be strictly sorted by falling
> + * resistance values to work.
> + */
> +static struct abx500_res_to_temp temp_tbl[] = {
> +	{-5, 214834},
> +	{ 0, 162943},
> +	{ 5, 124820},
> +	{10,  96520},
> +	{15,  75306},
> +	{20,  59254},
> +	{25,  47000},
> +	{30,  37566},
> +	{35,  30245},
> +	{40,  24520},
> +	{45,  20010},
> +	{50,  16432},
> +	{55,  13576},
> +	{60,  11280},
> +	{65,   9425},
> +};
> +
> +/*
> + * Note that the batres_vs_temp table must be strictly sorted by falling
> + * temperature values to work.
> + */
> +struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {
> +	{ 40, 120},
> +	{ 30, 135},
> +	{ 20, 165},
> +	{ 10, 230},
> +	{ 00, 325},
> +	{-10, 445},
> +	{-20, 595},
> +};
> +
> +/*
> + * Note that the batres_vs_temp table must be strictly sorted by falling
> + * temperature values to work.
> + */
> +struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = {
> +	{ 60, 300},
> +	{ 30, 300},
> +	{ 20, 300},
> +	{ 10, 300},
> +	{ 00, 300},
> +	{-10, 300},
> +	{-20, 300},
> +};
> +
> +/* battery resistance table for LI ION 9100 battery */
> +struct batres_vs_temp temp_to_batres_tbl_9100[] = {
> +	{ 60, 180},
> +	{ 30, 180},
> +	{ 20, 180},
> +	{ 10, 180},
> +	{ 00, 180},
> +	{-10, 180},
> +	{-20, 180},
> +};
> +
> +struct abx500_battery_type bat_type_thermistor[] = {
> +[BATTERY_UNKNOWN] = {
> +	/* First element always represent the UNKNOWN battery */
> +	.name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
> +	.resis_high = 0,
> +	.resis_low = 0,
> +	.battery_resistance = 300,
> +	.charge_full_design = 612,
> +	.nominal_voltage = 3700,
> +	.termination_vol = 4050,
> +	.termination_curr = 200,
> +	.recharge_vol = 3990,
> +	.normal_cur_lvl = 400,
> +	.normal_vol_lvl = 4100,
> +	.maint_a_cur_lvl = 400,
> +	.maint_a_vol_lvl = 4050,
> +	.maint_a_chg_timer_h = 60,
> +	.maint_b_cur_lvl = 400,
> +	.maint_b_vol_lvl = 4000,
> +	.maint_b_chg_timer_h = 200,
> +	.low_high_cur_lvl = 300,
> +	.low_high_vol_lvl = 4000,
> +	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
> +	.r_to_t_tbl = temp_tbl,
> +	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
> +	.v_to_cap_tbl = cap_tbl,
> +	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
> +	.batres_tbl = temp_to_batres_tbl_thermistor,
> +},
> +{
> +	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
> +	.resis_high = 53407,
> +	.resis_low = 12500,
> +	.battery_resistance = 300,
> +	.charge_full_design = 900,
> +	.nominal_voltage = 3600,
> +	.termination_vol = 4150,
> +	.termination_curr = 80,
> +	.recharge_vol = 4130,
> +	.normal_cur_lvl = 700,
> +	.normal_vol_lvl = 4200,
> +	.maint_a_cur_lvl = 600,
> +	.maint_a_vol_lvl = 4150,
> +	.maint_a_chg_timer_h = 60,
> +	.maint_b_cur_lvl = 600,
> +	.maint_b_vol_lvl = 4100,
> +	.maint_b_chg_timer_h = 200,
> +	.low_high_cur_lvl = 300,
> +	.low_high_vol_lvl = 4000,
> +	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_A_thermistor),
> +	.r_to_t_tbl = temp_tbl_A_thermistor,
> +	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_A_thermistor),
> +	.v_to_cap_tbl = cap_tbl_A_thermistor,
> +	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
> +	.batres_tbl = temp_to_batres_tbl_thermistor,
> +
> +},
> +{
> +	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
> +	.resis_high = 165418,
> +	.resis_low = 82869,
> +	.battery_resistance = 300,
> +	.charge_full_design = 900,
> +	.nominal_voltage = 3600,
> +	.termination_vol = 4150,
> +	.termination_curr = 80,
> +	.recharge_vol = 4130,
> +	.normal_cur_lvl = 700,
> +	.normal_vol_lvl = 4200,
> +	.maint_a_cur_lvl = 600,
> +	.maint_a_vol_lvl = 4150,
> +	.maint_a_chg_timer_h = 60,
> +	.maint_b_cur_lvl = 600,
> +	.maint_b_vol_lvl = 4100,
> +	.maint_b_chg_timer_h = 200,
> +	.low_high_cur_lvl = 300,
> +	.low_high_vol_lvl = 4000,
> +	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl_B_thermistor),
> +	.r_to_t_tbl = temp_tbl_B_thermistor,
> +	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_B_thermistor),
> +	.v_to_cap_tbl = cap_tbl_B_thermistor,
> +	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
> +	.batres_tbl = temp_to_batres_tbl_thermistor,
> +},
> +};
> +
> +struct abx500_battery_type bat_type_ext_thermistor[] = {
> +[BATTERY_UNKNOWN] = {
> +	/* First element always represent the UNKNOWN battery */
> +	.name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
> +	.resis_high = 0,
> +	.resis_low = 0,
> +	.battery_resistance = 300,
> +	.charge_full_design = 612,
> +	.nominal_voltage = 3700,
> +	.termination_vol = 4050,
> +	.termination_curr = 200,
> +	.recharge_vol = 3990,
> +	.normal_cur_lvl = 400,
> +	.normal_vol_lvl = 4100,
> +	.maint_a_cur_lvl = 400,
> +	.maint_a_vol_lvl = 4050,
> +	.maint_a_chg_timer_h = 60,
> +	.maint_b_cur_lvl = 400,
> +	.maint_b_vol_lvl = 4000,
> +	.maint_b_chg_timer_h = 200,
> +	.low_high_cur_lvl = 300,
> +	.low_high_vol_lvl = 4000,
> +	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
> +	.r_to_t_tbl = temp_tbl,
> +	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
> +	.v_to_cap_tbl = cap_tbl,
> +	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
> +	.batres_tbl = temp_to_batres_tbl_thermistor,
> +},
> +/*
> + * These are the batteries that doesn't have an internal NTC resistor to measure
> + * its temperature. The temperature in this case is measure with a NTC placed
> + * near the battery but on the PCB.
> + */
> +{
> +	.name = POWER_SUPPLY_TECHNOLOGY_LIPO,
> +	.resis_high = 76000,
> +	.resis_low = 53000,
> +	.battery_resistance = 300,
> +	.charge_full_design = 900,
> +	.nominal_voltage = 3700,
> +	.termination_vol = 4150,
> +	.termination_curr = 100,
> +	.recharge_vol = 4130,
> +	.normal_cur_lvl = 700,
> +	.normal_vol_lvl = 4200,
> +	.maint_a_cur_lvl = 600,
> +	.maint_a_vol_lvl = 4150,
> +	.maint_a_chg_timer_h = 60,
> +	.maint_b_cur_lvl = 600,
> +	.maint_b_vol_lvl = 4100,
> +	.maint_b_chg_timer_h = 200,
> +	.low_high_cur_lvl = 300,
> +	.low_high_vol_lvl = 4000,
> +	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
> +	.r_to_t_tbl = temp_tbl,
> +	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
> +	.v_to_cap_tbl = cap_tbl,
> +	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
> +	.batres_tbl = temp_to_batres_tbl_thermistor,
> +},
> +{
> +	.name = POWER_SUPPLY_TECHNOLOGY_LION,
> +	.resis_high = 30000,
> +	.resis_low = 10000,
> +	.battery_resistance = 300,
> +	.charge_full_design = 950,
> +	.nominal_voltage = 3700,
> +	.termination_vol = 4150,
> +	.termination_curr = 100,
> +	.recharge_vol = 4130,
> +	.normal_cur_lvl = 700,
> +	.normal_vol_lvl = 4200,
> +	.maint_a_cur_lvl = 600,
> +	.maint_a_vol_lvl = 4150,
> +	.maint_a_chg_timer_h = 60,
> +	.maint_b_cur_lvl = 600,
> +	.maint_b_vol_lvl = 4100,
> +	.maint_b_chg_timer_h = 200,
> +	.low_high_cur_lvl = 300,
> +	.low_high_vol_lvl = 4000,
> +	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
> +	.r_to_t_tbl = temp_tbl,
> +	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
> +	.v_to_cap_tbl = cap_tbl,
> +	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
> +	.batres_tbl = temp_to_batres_tbl_thermistor,
> +},
> +{
> +	.name = POWER_SUPPLY_TECHNOLOGY_LION,
> +	.resis_high = 95000,
> +	.resis_low = 76001,
> +	.battery_resistance = 300,
> +	.charge_full_design = 950,
> +	.nominal_voltage = 3700,
> +	.termination_vol = 4150,
> +	.termination_curr = 100,
> +	.recharge_vol = 4130,
> +	.normal_cur_lvl = 700,
> +	.normal_vol_lvl = 4200,
> +	.maint_a_cur_lvl = 600,
> +	.maint_a_vol_lvl = 4150,
> +	.maint_a_chg_timer_h = 60,
> +	.maint_b_cur_lvl = 600,
> +	.maint_b_vol_lvl = 4100,
> +	.maint_b_chg_timer_h = 200,
> +	.low_high_cur_lvl = 300,
> +	.low_high_vol_lvl = 4000,
> +	.n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
> +	.r_to_t_tbl = temp_tbl,
> +	.n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
> +	.v_to_cap_tbl = cap_tbl,
> +	.n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
> +	.batres_tbl = temp_to_batres_tbl_thermistor,
> +},
> +};
> +
> +static const struct abx500_bm_capacity_levels cap_levels = {
> +	.critical	= 2,
> +	.low		= 10,
> +	.normal		= 70,
> +	.high		= 95,
> +	.full		= 100,
> +};
> +
> +static const struct abx500_fg_parameters fg = {
> +	.recovery_sleep_timer = 10,
> +	.recovery_total_time = 100,
> +	.init_timer = 1,
> +	.init_discard_time = 5,
> +	.init_total_time = 40,
> +	.high_curr_time = 60,
> +	.accu_charging = 30,
> +	.accu_high_curr = 30,
> +	.high_curr_threshold = 50,
> +	.lowbat_threshold = 3100,
> +	.battok_falling_th_sel0 = 2860,
> +	.battok_raising_th_sel1 = 2860,
> +	.user_cap_limit = 15,
> +	.maint_thres = 97,
> +};
> +
> +static const struct abx500_maxim_parameters maxi_params = {
> +	.ena_maxi = true,
> +	.chg_curr = 910,
> +	.wait_cycles = 10,
> +	.charger_curr_step = 100,
> +};
> +
> +static const struct abx500_bm_charger_parameters chg = {
> +	.usb_volt_max		= 5500,
> +	.usb_curr_max		= 1500,
> +	.ac_volt_max		= 7500,
> +	.ac_curr_max		= 1500,
> +};
> +
> +struct abx500_bm_data ab8500_bm_data = {
> +	.temp_under		= 3,
> +	.temp_low		= 8,
> +	.temp_high		= 43,
> +	.temp_over		= 48,
> +	.main_safety_tmr_h	= 4,
> +	.temp_interval_chg	= 20,
> +	.temp_interval_nochg	= 120,
> +	.usb_safety_tmr_h	= 4,
> +	.bkup_bat_v		= BUP_VCH_SEL_2P6V,
> +	.bkup_bat_i		= BUP_ICH_SEL_150UA,
> +	.no_maintenance		= false,
> +	.adc_therm		= ABx500_ADC_THERM_BATCTRL,
> +	.chg_unknown_bat	= false,
> +	.enable_overshoot	= false,
> +	.fg_res			= 100,
> +	.cap_levels		= &cap_levels,
> +	.bat_type		= bat_type_thermistor,
> +	.n_btypes		= 3,
> +	.batt_id		= 0,
> +	.interval_charging	= 5,
> +	.interval_not_charging	= 120,
> +	.temp_hysteresis	= 3,
> +	.gnd_lift_resistance	= 34,
> +	.maxi			= &maxi_params,
> +	.chg_params		= &chg,
> +	.fg_params		= &fg,
> +};
> +
> +int __devinit
> +bmdevs_of_probe(struct device *dev,
> +		struct device_node *np,
> +		struct abx500_bm_plat_data *pdata)
> +{
> +	int	i, ret = 0, thermistor = NTC_INTERNAL;
> +	const	__be32 *ph;
> +	const	char *bat_tech;
> +	struct	abx500_bm_data		 *bat;
> +	struct	abx500_battery_type	 *btype;
> +	struct  device_node		 *np_bat_supply;
> +	struct  abx500_bmdevs_plat_data  *plat_data = pdata->bmdev_pdata;

<nit> 

This spacing is uncharacteristic of Linux drivers. 

Usually, struct declarations come first.

</nit>

> +	/* get phandle to 'supplied-to' node */

I thought you were going to reverse this?

> +	ph = of_get_property(np, "supplied-to", &plat_data->num_supplicants);
> +	if (ph == NULL) {

if (!ph) {

> +		dev_err(dev, "no supplied_to property specified\n");
> +		return -EINVAL;
> +	}
> +	plat_data->num_supplicants /= sizeof(int);
> +	plat_data->supplied_to =
> +		devm_kzalloc(dev, plat_data->num_supplicants *
> +			sizeof(const char *), GFP_KERNEL);
> +	if (plat_data->supplied_to == NULL) {
> +		dev_err(dev, "%s no mem for supplied-to\n", __func__);
> +		return -ENOMEM;
> +	}
> +	for (i = 0; i < plat_data->num_supplicants; ++i) {
> +		np_bat_supply = of_find_node_by_phandle(be32_to_cpup(ph) + i);

Use: of_parse_phandle(np, "supplied-to", i) instead.

> +		if (np_bat_supply == NULL) {

if (!np_bat_supply) {

> +			dev_err(dev, "invalid supplied_to property\n");
> +			return -EINVAL;
> +		}
> +		ret = of_property_read_string(np_bat_supply, "interface-name",
> +				(const char **)(plat_data->supplied_to + i));
> +		if (ret < 0) {
> +			of_node_put(np_bat_supply);
> +			dev_err(dev, "supply/interface name not found\n");
> +			return ret;
> +		}
> +		dev_dbg(dev, "%s power supply interface_name:%s\n",
> +			__func__, *(plat_data->supplied_to + i));
> +	}

<remove>

> +	/* get phandle to 'battery-info' node */
> +	ph = of_get_property(np, "battery-info", NULL);
> +	if (ph == NULL) {
> +		dev_err(dev, "missing property battery-info\n");
> +		return -EINVAL;
> +	}
> +	np_bat_supply = of_find_node_by_phandle(be32_to_cpup(ph));

</remove>

... and replace with: np_bat_supply = of_parse_phandle(np, "battery-info", 0) instead.

> +	if (np_bat_supply == NULL) {

if (!np_bat_supply) {

I'll not mention this again.

> +		dev_err(dev, "invalid battery-info node\n");
> +		return -EINVAL;
> +	}
> +	if (of_property_read_bool(np_bat_supply,
> +			"thermistor-on-batctrl") == false){

Replace with: 
        if (of_get_property(np_bat_supply, "thermistor-on-batctr", NULL))
	        np_bat_supply =  true;

<remove>

> +		dev_warn(dev, "missing property thermistor-on-batctrl\n");
> +		thermistor = NTC_EXTERNAL;
> +	}

</remove>

> +	pdata->battery = &ab8500_bm_data;
> +	bat = pdata->battery;

Why not: bat = &ab8500_bm_data

Or just use ab8500_bm_data in its own right?

> +	if (thermistor == NTC_EXTERNAL) {
> +		bat->n_btypes  = 4;
> +		bat->bat_type  = bat_type_ext_thermistor;
> +		bat->adc_therm = ABx500_ADC_THERM_BATTEMP;
> +	}
> +	ret = of_property_read_string(np_bat_supply, "battery-name", &bat_tech);
> +	if (ret < 0) {
> +		dev_warn(dev, "missing property battery-name/type\n");
> +		bat_tech = "UNKNOWN";
> +	}
> +	of_node_put(np_bat_supply);
> +	if (strcmp(bat_tech, "LION") == 0) {
> +		bat->no_maintenance  = true;
> +		bat->chg_unknown_bat = true;
> +		bat->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600;
> +		bat->bat_type[BATTERY_UNKNOWN].termination_vol    = 4150;
> +		bat->bat_type[BATTERY_UNKNOWN].recharge_vol	  = 4130;
> +		bat->bat_type[BATTERY_UNKNOWN].normal_cur_lvl	  = 520;
> +		bat->bat_type[BATTERY_UNKNOWN].normal_vol_lvl	  = 4200;
> +	}
> +	/* select the battery resolution table */
> +	for (i = 0; i < bat->n_btypes; ++i) {
> +		btype = (bat->bat_type + i);
> +		if (thermistor == NTC_EXTERNAL) {
> +			btype->batres_tbl =
> +				temp_to_batres_tbl_ext_thermistor;
> +		} else if (strcmp(bat_tech, "LION") == 0) {

Isn't strncmp safer, since you know the size of the comparison?

> +			btype->batres_tbl =
> +				temp_to_batres_tbl_9100;
> +		} else {
> +			btype->batres_tbl =
> +				temp_to_batres_tbl_thermistor;
> +		}
> +	}
> +	return 0;
> +}
> +EXPORT_SYMBOL(bmdevs_of_probe);

Why are you exporting?

> diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
> index bba3cca..8e427e7 100644
> --- a/drivers/power/ab8500_btemp.c
> +++ b/drivers/power/ab8500_btemp.c
> @@ -93,7 +93,7 @@ struct ab8500_btemp {
>  	struct ab8500 *parent;
>  	struct ab8500_gpadc *gpadc;
>  	struct ab8500_fg *fg;
> -	struct abx500_btemp_platform_data *pdata;
> +	struct abx500_bmdevs_plat_data *pdata;
>  	struct abx500_bm_data *bat;
>  	struct power_supply btemp_psy;
>  	struct ab8500_btemp_events events;
> @@ -982,7 +982,7 @@ static int __devinit ab8500_btemp_probe(struct platform_device *pdev)
>  	di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
>  
>  	/* get btemp specific platform data */
> -	di->pdata = plat_data->btemp;
> +	di->pdata = plat_data->bmdev_pdata;
>  	if (!di->pdata) {
>  		dev_err(di->dev, "no btemp platform data supplied\n");
>  		ret = -EINVAL;
> diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
> index d4f0c98..5ff0d83 100644
> --- a/drivers/power/ab8500_charger.c
> +++ b/drivers/power/ab8500_charger.c
> @@ -220,7 +220,7 @@ struct ab8500_charger {
>  	bool autopower;
>  	struct ab8500 *parent;
>  	struct ab8500_gpadc *gpadc;
> -	struct abx500_charger_platform_data *pdata;
> +	struct abx500_bmdevs_plat_data *pdata;
>  	struct abx500_bm_data *bat;
>  	struct ab8500_charger_event_flags flags;
>  	struct ab8500_charger_usb_state usb_state;
> @@ -2555,7 +2555,7 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)
>  	spin_lock_init(&di->usb_state.usb_lock);
>  
>  	/* get charger specific platform data */
> -	di->pdata = plat_data->charger;
> +	di->pdata = plat_data->bmdev_pdata;
>  	if (!di->pdata) {
>  		dev_err(di->dev, "no charger platform data supplied\n");
>  		ret = -EINVAL;
> diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c
> index bf02225..96741b8 100644
> --- a/drivers/power/ab8500_fg.c
> +++ b/drivers/power/ab8500_fg.c
> @@ -22,15 +22,14 @@
>  #include <linux/platform_device.h>
>  #include <linux/power_supply.h>
>  #include <linux/kobject.h>
> -#include <linux/mfd/abx500/ab8500.h>
> -#include <linux/mfd/abx500.h>
>  #include <linux/slab.h>
> -#include <linux/mfd/abx500/ab8500-bm.h>
>  #include <linux/delay.h>
> -#include <linux/mfd/abx500/ab8500-gpadc.h>
> -#include <linux/mfd/abx500.h>
>  #include <linux/time.h>
>  #include <linux/completion.h>
> +#include <linux/mfd/abx500.h>
> +#include <linux/mfd/abx500/ab8500.h>
> +#include <linux/mfd/abx500/ab8500-bm.h>
> +#include <linux/mfd/abx500/ab8500-gpadc.h>
>  
>  #define MILLI_TO_MICRO			1000
>  #define FG_LSB_IN_MA			1627
> @@ -212,7 +211,7 @@ struct ab8500_fg {
>  	struct ab8500_fg_avg_cap avg_cap;
>  	struct ab8500 *parent;
>  	struct ab8500_gpadc *gpadc;
> -	struct abx500_fg_platform_data *pdata;
> +	struct abx500_bmdevs_plat_data *pdata;
>  	struct abx500_bm_data *bat;
>  	struct power_supply fg_psy;
>  	struct workqueue_struct *fg_wq;
> @@ -544,14 +543,14 @@ cc_err:
>  		ret = abx500_set_register_interruptible(di->dev,
>  			AB8500_GAS_GAUGE, AB8500_GASG_CC_NCOV_ACCU,
>  			SEC_TO_SAMPLE(10));
> -		if (ret)
> +		if (ret < 0)

I don't 'think' this change is required. abx500_set_register_interruptible
will only return !0 on error.

>  			goto fail;
>  
>  		/* Start the CC */
>  		ret = abx500_set_register_interruptible(di->dev, AB8500_RTC,
>  			AB8500_RTC_CC_CONF_REG,
>  			(CC_DEEP_SLEEP_ENA | CC_PWR_UP_ENA));
> -		if (ret)
> +		if (ret < 0)
>  			goto fail;
>  	} else {
>  		di->turn_off_fg = false;
> @@ -2429,7 +2428,6 @@ static int __devexit ab8500_fg_remove(struct platform_device *pdev)
>  	flush_scheduled_work();
>  	power_supply_unregister(&di->fg_psy);
>  	platform_set_drvdata(pdev, NULL);
> -	kfree(di);
>  	return ret;
>  }
>  
> @@ -2446,18 +2444,47 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
>  {
>  	int i, irq;
>  	int ret = 0;
> -	struct abx500_bm_plat_data *plat_data = pdev->dev.platform_data;
> +	struct abx500_bm_plat_data *plat_data
> +				= pdev->dev.platform_data;
> +	struct device_node *np	= pdev->dev.of_node;
>  	struct ab8500_fg *di;
>  
> +	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
> +	if (!di) {
> +		dev_err(&pdev->dev, "%s no mem for ab8500_fg\n", __func__);
> +		return -ENOMEM;
> +	}
> +	if (np) {
> +		if (!plat_data) {

Change these around.

if (!plat_data) {
        if (np) {
                <snip>
        } else {
                <ERROR>
        }
}

> +			plat_data =
> +			devm_kzalloc(&pdev->dev, sizeof(*plat_data),
> +					GFP_KERNEL);
> +			if (!plat_data) {
> +				dev_err(&pdev->dev,
> +					"%s no mem for plat_data\n", __func__);
> +				return -ENOMEM;
> +			}
> +			plat_data->bmdev_pdata = devm_kzalloc(&pdev->dev,
> +				sizeof(*plat_data->bmdev_pdata), GFP_KERNEL);
> +			if (!plat_data->bmdev_pdata) {
> +				dev_err(&pdev->dev,
> +					"%s no mem for pdata->fg\n",
> +					__func__);
> +				return -ENOMEM;
> +			}
> +		}
> +		ret = bmdevs_of_probe(&pdev->dev, np, plat_data);
> +		if (ret < 0) {
> +			dev_err(&pdev->dev, "failed to get platform data\n");
> +			return ret;
> +		}
> +	}

<remove>

>  	if (!plat_data) {
> -		dev_err(&pdev->dev, "No platform data\n");
> +		dev_err(&pdev->dev,
> +			"%s no fg platform data found\n", __func__);
>  		return -EINVAL;
>  	}
</remove>

> -	di = kzalloc(sizeof(*di), GFP_KERNEL);
> -	if (!di)
> -		return -ENOMEM;
> -
>  	mutex_init(&di->cc_lock);
>  
>  	/* get parent data */
> @@ -2466,19 +2493,17 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
>  	di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
>  
>  	/* get fg specific platform data */
> -	di->pdata = plat_data->fg;
> +	di->pdata = plat_data->bmdev_pdata;
>  	if (!di->pdata) {
>  		dev_err(di->dev, "no fg platform data supplied\n");
> -		ret = -EINVAL;
> -		goto free_device_info;
> +		return -EINVAL;
>  	}
>  
>  	/* get battery specific platform data */
>  	di->bat = plat_data->battery;
>  	if (!di->bat) {
>  		dev_err(di->dev, "no battery platform data supplied\n");
> -		ret = -EINVAL;
> -		goto free_device_info;
> +		return -EINVAL;
>  	}
>  
>  	di->fg_psy.name = "ab8500_fg";
> @@ -2506,7 +2531,7 @@ static int __devinit ab8500_fg_probe(struct platform_device *pdev)
>  	di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq");
>  	if (di->fg_wq == NULL) {
>  		dev_err(di->dev, "failed to create work queue\n");
> -		goto free_device_info;
> +		return -ENOMEM;
>  	}
>  
>  	/* Init work for running the fg algorithm instantly */
> @@ -2605,12 +2630,14 @@ free_irq:
>  	}
>  free_inst_curr_wq:
>  	destroy_workqueue(di->fg_wq);
> -free_device_info:
> -	kfree(di);
> -
>  	return ret;
>  }
>  
> +static const struct of_device_id ab8500_fg_match[] = {
> +	{.compatible = "stericsson,ab8500-fg",},

<nit>

Spaces:

{ .compatible = "stericsson,ab8500-fg", },

</nit>

> +	{},
> +};
> +
>  static struct platform_driver ab8500_fg_driver = {
>  	.probe = ab8500_fg_probe,
>  	.remove = __devexit_p(ab8500_fg_remove),
> @@ -2619,6 +2646,7 @@ static struct platform_driver ab8500_fg_driver = {
>  	.driver = {
>  		.name = "ab8500-fg",
>  		.owner = THIS_MODULE,
> +		.of_match_table = ab8500_fg_match,
>  	},
>  };
>  
> diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
> index 804b88c..ba548e4 100644
> --- a/drivers/power/abx500_chargalg.c
> +++ b/drivers/power/abx500_chargalg.c
> @@ -231,7 +231,7 @@ struct abx500_chargalg {
>  	struct abx500_chargalg_charger_info chg_info;
>  	struct abx500_chargalg_battery_data batt_data;
>  	struct abx500_chargalg_suspension_status susp_status;
> -	struct abx500_chargalg_platform_data *pdata;
> +	struct abx500_bmdevs_plat_data *pdata;
>  	struct abx500_bm_data *bat;
>  	struct power_supply chargalg_psy;
>  	struct ux500_charger *ac_chg;
> @@ -1814,7 +1814,7 @@ static int __devinit abx500_chargalg_probe(struct platform_device *pdev)
>  	di->dev = &pdev->dev;
>  
>  	plat_data = pdev->dev.platform_data;
> -	di->pdata = plat_data->chargalg;
> +	di->pdata = plat_data->bmdev_pdata;
>  	di->bat = plat_data->battery;
>  
>  	/* chargalg supply */
> diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
> index 1318ca6..286f8ac 100644
> --- a/include/linux/mfd/abx500.h
> +++ b/include/linux/mfd/abx500.h
> @@ -382,39 +382,30 @@ struct abx500_bm_data {
>  	int gnd_lift_resistance;
>  	const struct abx500_maxim_parameters *maxi;
>  	const struct abx500_bm_capacity_levels *cap_levels;
> -	const struct abx500_battery_type *bat_type;
> +	struct abx500_battery_type *bat_type;
>  	const struct abx500_bm_charger_parameters *chg_params;
>  	const struct abx500_fg_parameters *fg_params;
>  };
>  
> -struct abx500_chargalg_platform_data {
> -	char **supplied_to;
> -	size_t num_supplicants;
> +struct abx500_bmdevs_plat_data {
> +	char	**supplied_to;
> +	size_t	num_supplicants;
> +	bool	autopower_cfg;
>  };
>  
> -struct abx500_charger_platform_data {
> -	char **supplied_to;
> -	size_t num_supplicants;
> -	bool autopower_cfg;
> -};
> -
> -struct abx500_btemp_platform_data {
> -	char **supplied_to;
> -	size_t num_supplicants;
> +struct abx500_bm_plat_data {
> +	struct abx500_bm_data *battery;
> +	struct abx500_bmdevs_plat_data *bmdev_pdata;
>  };
>  
> -struct abx500_fg_platform_data {
> -	char **supplied_to;
> -	size_t num_supplicants;
> +enum {
> +	NTC_EXTERNAL = 0,
> +	NTC_INTERNAL,
>  };
>  
> -struct abx500_bm_plat_data {
> -	struct abx500_bm_data *battery;
> -	struct abx500_charger_platform_data *charger;
> -	struct abx500_btemp_platform_data *btemp;
> -	struct abx500_fg_platform_data *fg;
> -	struct abx500_chargalg_platform_data *chargalg;
> -};
> +int bmdevs_of_probe(struct device *dev,
> +		struct device_node *np,
> +		struct abx500_bm_plat_data *pdata);
>  
>  int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
>  	u8 value);
> diff --git a/include/linux/mfd/abx500/ab8500-bm.h b/include/linux/mfd/abx500/ab8500-bm.h
> index 44310c9..d15b7f1 100644
> --- a/include/linux/mfd/abx500/ab8500-bm.h
> +++ b/include/linux/mfd/abx500/ab8500-bm.h
> @@ -422,6 +422,13 @@ struct ab8500_chargalg_platform_data {
>  struct ab8500_btemp;
>  struct ab8500_gpadc;
>  struct ab8500_fg;
> +
> +extern struct abx500_bm_data ab8500_bm_data;
> +extern struct abx500_battery_type bat_type_ext_thermistor[];
> +extern struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[];
> +extern struct batres_vs_temp temp_to_batres_tbl_9100[];
> +extern struct batres_vs_temp temp_to_batres_tbl_thermistor[];
> +
>  #ifdef CONFIG_AB8500_BM
>  void ab8500_fg_reinit(void);
>  void ab8500_charger_usb_state_changed(u8 bm_usb_state, u16 mA);
> -- 
> 1.7.9.5
> 

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2012-11-23  9:50 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-31 15:40 [PATCH 0/4] Implement device tree support for ab8500 BM Devices Rajanikanth H.V
2012-10-31 15:40 ` [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge Rajanikanth H.V
2012-11-01 15:15   ` Francesco Lavra
2012-11-07 18:45     ` Rajanikanth H V
2012-11-10 16:53       ` Francesco Lavra
2012-11-15 11:34         ` Rajanikanth HV
2012-10-31 15:40 ` [PATCH 2/4] mfd: ab8500: add devicetree support for btemp Rajanikanth H.V
2012-10-31 15:40 ` [PATCH 3/4] mfd: ab8500: add devicetree support for charger Rajanikanth H.V
2012-10-31 15:40 ` [PATCH 4/4] mfd: ab8500: add devicetree support for chargalg Rajanikanth H.V
2012-11-19  3:46 ` [PATCH 0/4] Implement device tree support for ab8500 BM Devices Anton Vorontsov
2012-11-19  3:58   ` Rajanikanth HV
2012-11-19  4:57     ` Anton Vorontsov
  -- strict thread matches above, loose matches on Subject: below --
2012-11-22 18:43 Rajanikanth H.V
2012-11-22 18:43 ` [PATCH 1/4] mfd: ab8500: add devicetree support for fuelgauge Rajanikanth H.V
2012-11-22 20:08   ` Anton Vorontsov
2012-11-23  9:50     ` Lee Jones
     [not found] <1351146654-9110-1-git-send-email-rajanikanth.hv@stericsson.com>
     [not found] ` <1351146654-9110-2-git-send-email-rajanikanth.hv@stericsson.com>
2012-10-27 15:07   ` Francesco Lavra
2012-10-27 16:00     ` Rajanikanth HV
2012-10-27 16:18       ` Francesco Lavra
     [not found] <1349064513-31301-1-git-send-email-rajanikanth.hv@stericsson.com>
     [not found] ` <1349064513-31301-2-git-send-email-rajanikanth.hv@stericsson.com>
2012-10-01  9:49   ` Lee Jones
2012-10-01  9:59     ` Rajanikanth HV
2012-10-01 10:36       ` Lee Jones
2012-10-01 10:22     ` Lee Jones
2012-10-06 14:01   ` Francesco Lavra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).