Commit b24ca57e authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.infradead.org/battery-2.6

* git://git.infradead.org/battery-2.6: (68 commits)
  power_supply: Mark da9052 driver as broken
  power_supply: Drop usage of nowarn variant of sysfs_create_link()
  s3c_adc_battery: Average over more than one adc sample
  power_supply: Add DA9052 battery driver
  isp1704_charger: Fix missing check
  jz4740-battery: Fix signedness bug
  power_supply: Assume mains power by default
  sbs-battery: Fix devicetree match table
  ARM: rx51: Add bq27200 i2c board info
  sbs-battery: Change power supply name
  devicetree-bindings: Propagate bq20z75->sbs rename to dt bindings
  devicetree-bindings: Add vendor entry for Smart Battery Systems
  sbs-battery: Rename internals to new name
  bq20z75: Rename to sbs-battery
  wm97xx_battery: Use DEFINE_MUTEX() for work_lock
  max8997_charger: Remove duplicate module.h
  lp8727_charger: Some minor fixes for the header
  lp8727_charger: Add header file
  power_supply: Convert drivers/power/* to use module_platform_driver()
  power_supply: Add "unknown" in power supply type
  ...
parents 6296e5d3 913272b3
OLPC battery
~~~~~~~~~~~~
Required properties:
- compatible : "olpc,xo1-battery"
SBS sbs-battery
~~~~~~~~~~
Required properties :
- compatible : "sbs,sbs-battery"
Optional properties :
- sbs,i2c-retry-count : The number of times to retry i2c transactions on i2c
IO failure.
- sbs,poll-retry-count : The number of times to try looking for new status
after an external change notification.
- sbs,battery-detect-gpios : The gpio which signals battery detection and
a flag specifying its polarity.
Example:
bq20z75@b {
compatible = "sbs,sbs-battery";
reg = < 0xb >;
sbs,i2c-retry-count = <2>;
sbs,poll-retry-count = <10>;
sbs,battery-detect-gpios = <&gpio-controller 122 1>;
}
......@@ -34,6 +34,7 @@ powervr Imagination Technologies
qcom Qualcomm, Inc.
ramtron Ramtron International
samsung Samsung Semiconductor
sbs Smart Battery System
schindler Schindler
sil Silicon Image
simtek
......
Charger Manager
(C) 2011 MyungJoo Ham <myungjoo.ham@samsung.com>, GPL
Charger Manager provides in-kernel battery charger management that
requires temperature monitoring during suspend-to-RAM state
and where each battery may have multiple chargers attached and the userland
wants to look at the aggregated information of the multiple chargers.
Charger Manager is a platform_driver with power-supply-class entries.
An instance of Charger Manager (a platform-device created with Charger-Manager)
represents an independent battery with chargers. If there are multiple
batteries with their own chargers acting independently in a system,
the system may need multiple instances of Charger Manager.
1. Introduction
===============
Charger Manager supports the following:
* Support for multiple chargers (e.g., a device with USB, AC, and solar panels)
A system may have multiple chargers (or power sources) and some of
they may be activated at the same time. Each charger may have its
own power-supply-class and each power-supply-class can provide
different information about the battery status. This framework
aggregates charger-related information from multiple sources and
shows combined information as a single power-supply-class.
* Support for in suspend-to-RAM polling (with suspend_again callback)
While the battery is being charged and the system is in suspend-to-RAM,
we may need to monitor the battery health by looking at the ambient or
battery temperature. We can accomplish this by waking up the system
periodically. However, such a method wakes up devices unncessary for
monitoring the battery health and tasks, and user processes that are
supposed to be kept suspended. That, in turn, incurs unnecessary power
consumption and slow down charging process. Or even, such peak power
consumption can stop chargers in the middle of charging
(external power input < device power consumption), which not
only affects the charging time, but the lifespan of the battery.
Charger Manager provides a function "cm_suspend_again" that can be
used as suspend_again callback of platform_suspend_ops. If the platform
requires tasks other than cm_suspend_again, it may implement its own
suspend_again callback that calls cm_suspend_again in the middle.
Normally, the platform will need to resume and suspend some devices
that are used by Charger Manager.
2. Global Charger-Manager Data related with suspend_again
========================================================
In order to setup Charger Manager with suspend-again feature
(in-suspend monitoring), the user should provide charger_global_desc
with setup_charger_manager(struct charger_global_desc *).
This charger_global_desc data for in-suspend monitoring is global
as the name suggests. Thus, the user needs to provide only once even
if there are multiple batteries. If there are multiple batteries, the
multiple instances of Charger Manager share the same charger_global_desc
and it will manage in-suspend monitoring for all instances of Charger Manager.
The user needs to provide all the two entries properly in order to activate
in-suspend monitoring:
struct charger_global_desc {
char *rtc_name;
: The name of rtc (e.g., "rtc0") used to wakeup the system from
suspend for Charger Manager. The alarm interrupt (AIE) of the rtc
should be able to wake up the system from suspend. Charger Manager
saves and restores the alarm value and use the previously-defined
alarm if it is going to go off earlier than Charger Manager so that
Charger Manager does not interfere with previously-defined alarms.
bool (*rtc_only_wakeup)(void);
: This callback should let CM know whether
the wakeup-from-suspend is caused only by the alarm of "rtc" in the
same struct. If there is any other wakeup source triggered the
wakeup, it should return false. If the "rtc" is the only wakeup
reason, it should return true.
};
3. How to setup suspend_again
=============================
Charger Manager provides a function "extern bool cm_suspend_again(void)".
When cm_suspend_again is called, it monitors every battery. The suspend_ops
callback of the system's platform_suspend_ops can call cm_suspend_again
function to know whether Charger Manager wants to suspend again or not.
If there are no other devices or tasks that want to use suspend_again
feature, the platform_suspend_ops may directly refer to cm_suspend_again
for its suspend_again callback.
The cm_suspend_again() returns true (meaning "I want to suspend again")
if the system was woken up by Charger Manager and the polling
(in-suspend monitoring) results in "normal".
4. Charger-Manager Data (struct charger_desc)
=============================================
For each battery charged independently from other batteries (if a series of
batteries are charged by a single charger, they are counted as one independent
battery), an instance of Charger Manager is attached to it.
struct charger_desc {
char *psy_name;
: The power-supply-class name of the battery. Default is
"battery" if psy_name is NULL. Users can access the psy entries
at "/sys/class/power_supply/[psy_name]/".
enum polling_modes polling_mode;
: CM_POLL_DISABLE: do not poll this battery.
CM_POLL_ALWAYS: always poll this battery.
CM_POLL_EXTERNAL_POWER_ONLY: poll this battery if and only if
an external power source is attached.
CM_POLL_CHARGING_ONLY: poll this battery if and only if the
battery is being charged.
unsigned int fullbatt_uV;
: If specified with a non-zero value, Charger Manager assumes
that the battery is full (capacity = 100) if the battery is not being
charged and the battery voltage is equal to or greater than
fullbatt_uV.
unsigned int polling_interval_ms;
: Required polling interval in ms. Charger Manager will poll
this battery every polling_interval_ms or more frequently.
enum data_source battery_present;
CM_FUEL_GAUGE: get battery presence information from fuel gauge.
CM_CHARGER_STAT: get battery presence from chargers.
char **psy_charger_stat;
: An array ending with NULL that has power-supply-class names of
chargers. Each power-supply-class should provide "PRESENT" (if
battery_present is "CM_CHARGER_STAT"), "ONLINE" (shows whether an
external power source is attached or not), and "STATUS" (shows whether
the battery is {"FULL" or not FULL} or {"FULL", "Charging",
"Discharging", "NotCharging"}).
int num_charger_regulators;
struct regulator_bulk_data *charger_regulators;
: Regulators representing the chargers in the form for
regulator framework's bulk functions.
char *psy_fuel_gauge;
: Power-supply-class name of the fuel gauge.
int (*temperature_out_of_range)(int *mC);
bool measure_battery_temp;
: This callback returns 0 if the temperature is safe for charging,
a positive number if it is too hot to charge, and a negative number
if it is too cold to charge. With the variable mC, the callback returns
the temperature in 1/1000 of centigrade.
The source of temperature can be battery or ambient one according to
the value of measure_battery_temp.
};
5. Other Considerations
=======================
At the charger/battery-related events such as battery-pulled-out,
charger-pulled-out, charger-inserted, DCIN-over/under-voltage, charger-stopped,
and others critical to chargers, the system should be configured to wake up.
At least the following should wake up the system from a suspend:
a) charger-on/off b) external-power-in/out c) battery-in/out (while charging)
It is usually accomplished by configuring the PMIC as a wakeup source.
......@@ -944,6 +944,9 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
.platform_data = &rx51_lp5523_platform_data,
},
#endif
{
I2C_BOARD_INFO("bq27200", 0x55),
},
{
I2C_BOARD_INFO("tpa6130a2", 0x60),
.platform_data = &rx51_tpa6130a2_data,
......
......@@ -49,12 +49,14 @@ static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 };
static enum power_supply_property wacom_battery_props[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_CAPACITY
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_SCOPE,
};
static enum power_supply_property wacom_ac_props[] = {
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_ONLINE
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_SCOPE,
};
static int wacom_battery_get_property(struct power_supply *psy,
......@@ -70,6 +72,9 @@ static int wacom_battery_get_property(struct power_supply *psy,
case POWER_SUPPLY_PROP_PRESENT:
val->intval = 1;
break;
case POWER_SUPPLY_PROP_SCOPE:
val->intval = POWER_SUPPLY_SCOPE_DEVICE;
break;
case POWER_SUPPLY_PROP_CAPACITY:
/* show 100% battery capacity when charging */
if (power_state == 0)
......@@ -101,6 +106,9 @@ static int wacom_ac_get_property(struct power_supply *psy,
else
val->intval = 0;
break;
case POWER_SUPPLY_PROP_SCOPE:
val->intval = POWER_SUPPLY_SCOPE_DEVICE;
break;
default:
ret = -EINVAL;
break;
......@@ -523,6 +531,8 @@ static int wacom_probe(struct hid_device *hdev,
wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
wdata->battery.use_for_apm = 0;
power_supply_powers(&wdata->battery, &hdev->dev);
ret = power_supply_register(&hdev->dev, &wdata->battery);
if (ret) {
hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
......@@ -537,6 +547,8 @@ static int wacom_probe(struct hid_device *hdev,
wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
wdata->ac.use_for_apm = 0;
power_supply_powers(&wdata->battery, &hdev->dev);
ret = power_supply_register(&hdev->dev, &wdata->ac);
if (ret) {
hid_warn(hdev,
......
......@@ -52,7 +52,8 @@ static __u16 wiiproto_keymap[] = {
};
static enum power_supply_property wiimote_battery_props[] = {
POWER_SUPPLY_PROP_CAPACITY
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_SCOPE,
};
static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
......@@ -402,6 +403,11 @@ static int wiimote_battery_get_property(struct power_supply *psy,
int ret = 0, state;
unsigned long flags;
if (psp == POWER_SUPPLY_PROP_SCOPE) {
val->intval = POWER_SUPPLY_SCOPE_DEVICE;
return 0;
}
ret = wiimote_cmd_acquire(wdata);
if (ret)
return ret;
......@@ -1220,6 +1226,8 @@ static int wiimote_hid_probe(struct hid_device *hdev,
wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
wdata->battery.use_for_apm = 0;
power_supply_powers(&wdata->battery, &hdev->dev);
ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
if (ret) {
hid_err(hdev, "Cannot register battery device\n");
......
......@@ -210,21 +210,6 @@ static struct max8925_irq_data max8925_irqs[] = {
.mask_reg = MAX8925_CHG_IRQ1_MASK,
.offs = 1 << 2,
},
[MAX8925_IRQ_VCHG_USB_OVP] = {
.reg = MAX8925_CHG_IRQ1,
.mask_reg = MAX8925_CHG_IRQ1_MASK,
.offs = 1 << 3,
},
[MAX8925_IRQ_VCHG_USB_F] = {
.reg = MAX8925_CHG_IRQ1,
.mask_reg = MAX8925_CHG_IRQ1_MASK,
.offs = 1 << 4,
},
[MAX8925_IRQ_VCHG_USB_R] = {
.reg = MAX8925_CHG_IRQ1,
.mask_reg = MAX8925_CHG_IRQ1_MASK,
.offs = 1 << 5,
},
[MAX8925_IRQ_VCHG_THM_OK_R] = {
.reg = MAX8925_CHG_IRQ2,
.mask_reg = MAX8925_CHG_IRQ2_MASK,
......
......@@ -116,12 +116,12 @@ config BATTERY_WM97XX
help
Say Y to enable support for battery measured by WM97xx aux port.
config BATTERY_BQ20Z75
tristate "TI BQ20z75 gas gauge"
config BATTERY_SBS
tristate "SBS Compliant gas gauge"
depends on I2C
help
Say Y to include support for TI BQ20z75 SBS-compliant
gas gauge and protection IC.
Say Y to include support for SBS battery driver for SBS-compliant
gas gauges.
config BATTERY_BQ27x00
tristate "BQ27x00 battery driver"
......@@ -150,6 +150,14 @@ config BATTERY_DA9030
Say Y here to enable support for batteries charger integrated into
DA9030 PMIC.
config BATTERY_DA9052
tristate "Dialog DA9052 Battery"
depends on PMIC_DA9052
depends on BROKEN
help
Say Y here to enable support for batteries charger integrated into
DA9052 PMIC.
config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C
......@@ -226,6 +234,12 @@ config CHARGER_TWL4030
help
Say Y here to enable support for TWL4030 Battery Charge Interface.
config CHARGER_LP8727
tristate "National Semiconductor LP8727 charger driver"
depends on I2C
help
Say Y here to enable support for LP8727 Charger Driver.
config CHARGER_GPIO
tristate "GPIO charger"
depends on GPIOLIB
......@@ -236,6 +250,16 @@ config CHARGER_GPIO
This driver can be build as a module. If so, the module will be
called gpio-charger.
config CHARGER_MANAGER
bool "Battery charger manager for multiple chargers"
depends on REGULATOR && RTC_CLASS
help
Say Y to enable charger-manager support, which allows multiple
chargers attached to a battery and multiple batteries attached to a
system. The charger-manager also can monitor charging status in
runtime and in suspend-to-RAM by waking up the system periodically
with help of suspend_again support.
config CHARGER_MAX8997
tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
depends on MFD_MAX8997 && REGULATOR_MAX8997
......
......@@ -22,9 +22,10 @@ obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_COLLIE) += collie_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
obj-$(CONFIG_BATTERY_BQ20Z75) += bq20z75.o
obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o
obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
......@@ -35,6 +36,8 @@ obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
This diff is collapsed.
This diff is collapsed.
......@@ -146,7 +146,7 @@ static void collie_bat_external_power_changed(struct power_supply *psy)
static irqreturn_t collie_bat_gpio_isr(int irq, void *data)
{
pr_info("collie_bat_gpio irq: %d\n", gpio_get_value(irq_to_gpio(irq)));
pr_info("collie_bat_gpio irq\n");
schedule_work(&bat_work);
return IRQ_HANDLED;
}
......@@ -277,18 +277,13 @@ static struct collie_bat collie_bat_bu = {
.adc_temp_divider = -1,
};
static struct {
int gpio;
char *name;
bool output;
int value;
} gpios[] = {
{ COLLIE_GPIO_CO, "main battery full", 0, 0 },
{ COLLIE_GPIO_MAIN_BAT_LOW, "main battery low", 0, 0 },
{ COLLIE_GPIO_CHARGE_ON, "main charge on", 1, 0 },
{ COLLIE_GPIO_MBAT_ON, "main battery", 1, 0 },
{ COLLIE_GPIO_TMP_ON, "main battery temp", 1, 0 },
{ COLLIE_GPIO_BBAT_ON, "backup battery", 1, 0 },
static struct gpio collie_batt_gpios[] = {
{ COLLIE_GPIO_CO, GPIOF_IN, "main battery full" },
{ COLLIE_GPIO_MAIN_BAT_LOW, GPIOF_IN, "main battery low" },
{ COLLIE_GPIO_CHARGE_ON, GPIOF_OUT_INIT_LOW, "main charge on" },
{ COLLIE_GPIO_MBAT_ON, GPIOF_OUT_INIT_LOW, "main battery" },
{ COLLIE_GPIO_TMP_ON, GPIOF_OUT_INIT_LOW, "main battery temp" },
{ COLLIE_GPIO_BBAT_ON, GPIOF_OUT_INIT_LOW, "backup battery" },
};
#ifdef CONFIG_PM
......@@ -313,29 +308,16 @@ static int collie_bat_resume(struct ucb1x00_dev *dev)
static int __devinit collie_bat_probe(struct ucb1x00_dev *dev)
{
int ret;
int i;
if (!machine_is_collie())
return -ENODEV;
ucb = dev->ucb;
for (i = 0; i < ARRAY_SIZE(gpios); i++) {
ret = gpio_request(gpios[i].gpio, gpios[i].name);
if (ret) {
i--;
goto err_gpio;
}
if (gpios[i].output)
ret = gpio_direction_output(gpios[i].gpio,
gpios[i].value);
else
ret = gpio_direction_input(gpios[i].gpio);
if (ret)
goto err_gpio;
}
ret = gpio_request_array(collie_batt_gpios,
ARRAY_SIZE(collie_batt_gpios));
if (ret)
return ret;
mutex_init(&collie_bat_main.work_lock);
......@@ -363,19 +345,12 @@ static int __devinit collie_bat_probe(struct ucb1x00_dev *dev)
/* see comment in collie_bat_remove */
cancel_work_sync(&bat_work);
i--;
err_gpio:
for (; i >= 0; i--)
gpio_free(gpios[i].gpio);
gpio_free_array(collie_batt_gpios, ARRAY_SIZE(collie_batt_gpios));
return ret;
}
static void __devexit collie_bat_remove(struct ucb1x00_dev *dev)
{
int i;
free_irq(gpio_to_irq(COLLIE_GPIO_CO), &collie_bat_main);
power_supply_unregister(&collie_bat_bu.psy);
......@@ -387,9 +362,7 @@ static void __devexit collie_bat_remove(struct ucb1x00_dev *dev)
* unregistered now.
*/
cancel_work_sync(&bat_work);
for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--)
gpio_free(gpios[i].gpio);
gpio_free_array(collie_batt_gpios, ARRAY_SIZE(collie_batt_gpios));
}
static struct ucb1x00_driver collie_bat_driver = {
......
......@@ -588,18 +588,7 @@ static struct platform_driver da903x_battery_driver = {
.remove = da9030_battery_remove,
};
static int da903x_battery_init(void)
{
return platform_driver_register(&da903x_battery_driver);
}
static void da903x_battery_exit(void)
{
platform_driver_unregister(&da903x_battery_driver);
}
module_init(da903x_battery_init);
module_exit(da903x_battery_exit);
module_platform_driver(da903x_battery_driver);
MODULE_DESCRIPTION("DA9030 battery charger driver");
MODULE_AUTHOR("Mike Rapoport, CompuLab");
......
This diff is collapsed.
......@@ -95,7 +95,11 @@ static int rated_capacities[] = {
2880, /* Samsung */
2880, /* BYD */
2880, /* Lishen */
2880 /* NEC */
2880, /* NEC */
#ifdef CONFIG_MACH_H4700
0,
3600, /* HP iPAQ hx4700 3.7V 3600mAh (359114-001) */
#endif
};
/* array is level at temps 0°C, 10°C, 20°C, 30°C, 40°C
......@@ -637,18 +641,7 @@ static struct platform_driver ds2760_battery_driver = {
.resume = ds2760_battery_resume,
};
static int __init ds2760_battery_init(void)
{
return platform_driver_register(&ds2760_battery_driver);
}
static void __exit ds2760_battery_exit(void)
{
platform_driver_unregister(&ds2760_battery_driver);
}
module_init(ds2760_battery_init);
module_exit(ds2760_battery_exit);
module_platform_driver(ds2760_battery_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
......
......@@ -841,29 +841,17 @@ static int __devexit ds2780_battery_remove(struct platform_device *pdev)
return 0;
}
MODULE_ALIAS("platform:ds2780-battery");
static struct platform_driver ds2780_battery_driver = {
.driver = {
.name = "ds2780-battery",
},
.probe = ds2780_battery_probe,
.remove = ds2780_battery_remove,
.remove = __devexit_p(ds2780_battery_remove),
};
static int __init ds2780_battery_init(void)
{
return platform_driver_register(&ds2780_battery_driver);
}
static void __exit ds2780_battery_exit(void)
{
platform_driver_unregister(&ds2780_battery_driver);
}
module_init(ds2780_battery_init);
module_exit(ds2780_battery_exit);
module_platform_driver(ds2780_battery_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>");
MODULE_DESCRIPTION("Maxim/Dallas DS2780 Stand-Alone Fuel Gauage IC driver");
MODULE_ALIAS("platform:ds2780-battery");
......@@ -185,17 +185,7 @@ static struct platform_driver gpio_charger_driver = {
},
};
static int __init gpio_charger_init(void)
{
return platform_driver_register(&gpio_charger_driver);
}
module_init(gpio_charger_init);
static void __exit gpio_charger_exit(void)
{
platform_driver_unregister(&gpio_charger_driver);
}
module_exit(gpio_charger_exit);
module_platform_driver(gpio_charger_driver);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Driver for chargers which report their online status through a GPIO");
......
......@@ -779,18 +779,7 @@ static struct platform_driver platform_pmic_battery_driver = {
.remove = __devexit_p(platform_pmic_battery_remove),
};
static int __init platform_pmic_battery_module_init(void)
{
return platform_driver_register(&platform_pmic_battery_driver);
}
static void __exit platform_pmic_battery_module_exit(void)
{
platform_driver_unregister(&platform_pmic_battery_driver);
}
module_init(platform_pmic_battery_module_init);
module_exit(platform_pmic_battery_module_exit);
module_platform_driver(platform_pmic_battery_driver);
MODULE_AUTHOR("Nithish Mahalingam <nithish.mahalingam@intel.com>");
MODULE_DESCRIPTION("Intel Moorestown PMIC Battery Driver");
......
......@@ -79,7 +79,7 @@ static void isp1704_charger_set_power(struct isp1704_charger *isp, bool on)
{
struct isp1704_charger_data *board = isp->dev->platform_data;
if (board->set_power)
if (board && board->set_power)
board->set_power(on);
}
......@@ -494,17 +494,7 @@ static struct platform_driver isp1704_charger_driver = {
.remove = __devexit_p(isp1704_charger_remove),
};
static int __init isp1704_charger_init(void)
{
return platform_driver_register(&isp1704_charger_driver);
}
module_init(isp1704_charger_init);
static void __exit isp1704_charger_exit(void)
{
platform_driver_unregister(&isp1704_charger_driver);
}
module_exit(isp1704_charger_exit);
module_platform_driver(isp1704_charger_driver);
MODULE_ALIAS("platform:isp1704_charger");
MODULE_AUTHOR("Nokia Corporation");
......
......@@ -67,7 +67,7 @@ static irqreturn_t jz_battery_irq_handler(int irq, void *devid)
static long jz_battery_read_voltage(struct jz_battery *battery)
{
unsigned long t;
long t;
unsigned long val;
long voltage;
......@@ -441,17 +441,7 @@ static struct platform_driver jz_battery_driver = {
},
};
static int __init jz_battery_init(void)
{
return platform_driver_register(&jz_battery_driver);
}
module_init(jz_battery_init);
static void __exit jz_battery_exit(void)
{
platform_driver_unregister(&jz_battery_driver);
}
module_exit(jz_battery_exit);
module_platform_driver(jz_battery_driver);
MODULE_ALIAS("platform:jz4740-battery");
MODULE_LICENSE("GPL");
......
This diff is collapsed.
......@@ -85,55 +85,79 @@ static int max17042_get_property(struct power_supply *psy,
{
struct max17042_chip *chip = container_of(psy,
struct max17042_chip, battery);
int ret;
switch (psp) {
case POWER_SUPPLY_PROP_PRESENT:
val->intval = max17042_read_reg(chip->client,
MAX17042_STATUS);
if (val->intval & MAX17042_STATUS_BattAbsent)
ret = max17042_read_reg(chip->client, MAX17042_STATUS);
if (ret < 0)
return ret;
if (ret & MAX17042_STATUS_BattAbsent)
val->intval = 0;
else
val->intval = 1;
break;
case POWER_SUPPLY_PROP_CYCLE_COUNT:
val->intval = max17042_read_reg(chip->client,
MAX17042_Cycles);
ret = max17042_read_reg(chip->client, MAX17042_Cycles);
if (ret < 0)
return ret;
val->intval = ret;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
val->intval = max17042_read_reg(chip->client,
MAX17042_MinMaxVolt);
val->intval >>= 8;
ret = max17042_read_reg(chip->client, MAX17042_MinMaxVolt);
if (ret < 0)
return ret;
val->intval = ret >> 8;
val->intval *= 20000; /* Units of LSB = 20mV */
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
val->intval = max17042_read_reg(chip->client,
MAX17042_V_empty);
val->intval >>= 7;
ret = max17042_read_reg(chip->client, MAX17042_V_empty);
if (ret < 0)
return ret;
val->intval = ret >> 7;
val->intval *= 10000; /* Units of LSB = 10mV */
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = max17042_read_reg(chip->client,
MAX17042_VCELL) * 83; /* 1000 / 12 = 83 */
ret = max17042_read_reg(chip->client, MAX17042_VCELL);
if (ret < 0)
return ret;
val->intval = ret * 625 / 8;
break;
case POWER_SUPPLY_PROP_VOLTAGE_AVG:
val->intval = max17042_read_reg(chip->client,
MAX17042_AvgVCELL) * 83;
ret = max17042_read_reg(chip->client, MAX17042_AvgVCELL);
if (ret < 0)
return ret;
val->intval = ret * 625 / 8;
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = max17042_read_reg(chip->client,
MAX17042_SOC) / 256;
ret = max17042_read_reg(chip->client, MAX17042_SOC);
if (ret < 0)
return ret;
val->intval = ret >> 8;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
val->intval = max17042_read_reg(chip->client,
MAX17042_RepSOC);
if ((val->intval / 256) >= MAX17042_BATTERY_FULL)
ret = max17042_read_reg(chip->client, MAX17042_RepSOC);
if (ret < 0)
return ret;
if ((ret >> 8) >= MAX17042_BATTERY_FULL)
val->intval = 1;
else if (val->intval >= 0)
else if (ret >= 0)
val->intval = 0;
break;
case POWER_SUPPLY_PROP_TEMP:
val->intval = max17042_read_reg(chip->client,
MAX17042_TEMP);
ret = max17042_read_reg(chip->client, MAX17042_TEMP);
if (ret < 0)
return ret;
val->intval = ret;
/* The value is signed. */
if (val->intval & 0x8000) {
val->intval = (0x7fff & ~val->intval) + 1;
......@@ -145,24 +169,30 @@ static int max17042_get_property(struct power_supply *psy,
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
if (chip->pdata->enable_current_sense) {
val->intval = max17042_read_reg(chip->client,
MAX17042_Current);
ret = max17042_read_reg(chip->client, MAX17042_Current);
if (ret < 0)
return ret;
val->intval = ret;
if (val->intval & 0x8000) {
/* Negative */
val->intval = ~val->intval & 0x7fff;
val->intval++;
val->intval *= -1;
}
val->intval >>= 4;
val->intval *= 1000000 * 25 / chip->pdata->r_sns;
val->intval *= 1562500 / chip->pdata->r_sns;
} else {
return -EINVAL;
}
break;
case POWER_SUPPLY_PROP_CURRENT_AVG:
if (chip->pdata->enable_current_sense) {
val->intval = max17042_read_reg(chip->client,
MAX17042_AvgCurrent);
ret = max17042_read_reg(chip->client,
MAX17042_AvgCurrent);
if (ret < 0)
return ret;
val->intval = ret;
if (val->intval & 0x8000) {
/* Negative */
val->intval = ~val->intval & 0x7fff;
......@@ -210,6 +240,9 @@ static int __devinit max17042_probe(struct i2c_client *client,
if (!chip->pdata->enable_current_sense)
chip->battery.num_properties -= 2;
if (chip->pdata->r_sns == 0)
chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
ret = power_supply_register(&client->dev, &chip->battery);
if (ret) {
dev_err(&client->dev, "failed: power supply register\n");
......@@ -226,9 +259,6 @@ static int __devinit max17042_probe(struct i2c_client *client,
max17042_write_reg(client, MAX17042_CGAIN, 0x0000);
max17042_write_reg(client, MAX17042_MiscCFG, 0x0003);
max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
} else {
if (chip->pdata->r_sns == 0)
chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
}
return 0;
......
......@@ -374,19 +374,9 @@ static struct platform_driver max8903_driver = {
},
};
static int __init max8903_init(void)
{
return platform_driver_register(&max8903_driver);
}
module_init(max8903_init);
static void __exit max8903_exit(void)
{
platform_driver_unregister(&max8903_driver);
}
module_exit(max8903_exit);
module_platform_driver(max8903_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MAX8903 Charger Driver");
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
MODULE_ALIAS("max8903-charger");
MODULE_ALIAS("platform:max8903-charger");
......@@ -78,6 +78,8 @@ struct max8925_power_info {
unsigned batt_detect:1; /* detecing MB by ID pin */
unsigned topoff_threshold:2;
unsigned fast_charge:3;
unsigned no_temp_support:1;
unsigned no_insert_detect:1;
int (*set_charger) (int);
};
......@@ -116,17 +118,7 @@ static irqreturn_t max8925_charger_handler(int irq, void *data)
case MAX8925_IRQ_VCHG_DC_F:
info->ac_online = 0;
__set_charger(info, 0);
dev_dbg(chip->dev, "Adapter is removal\n");
break;
case MAX8925_IRQ_VCHG_USB_R:
info->usb_online = 1;
__set_charger(info, 1);
dev_dbg(chip->dev, "USB inserted\n");
break;
case MAX8925_IRQ_VCHG_USB_F:
info->usb_online = 0;
__set_charger(info, 0);
dev_dbg(chip->dev, "USB is removal\n");
dev_dbg(chip->dev, "Adapter removed\n");
break;
case MAX8925_IRQ_VCHG_THM_OK_F:
/* Battery is not ready yet */
......@@ -168,27 +160,33 @@ static irqreturn_t max8925_charger_handler(int irq, void *data)
static int start_measure(struct max8925_power_info *info, int type)
{
unsigned char buf[2] = {0, 0};
int meas_cmd;
int meas_reg = 0, ret;
switch (type) {
case MEASURE_VCHG:
meas_cmd = MAX8925_CMD_VCHG;
meas_reg = MAX8925_ADC_VCHG;
break;
case MEASURE_VBBATT:
meas_cmd = MAX8925_CMD_VBBATT;
meas_reg = MAX8925_ADC_VBBATT;
break;
case MEASURE_VMBATT:
meas_cmd = MAX8925_CMD_VMBATT;
meas_reg = MAX8925_ADC_VMBATT;
break;
case MEASURE_ISNS:
meas_cmd = MAX8925_CMD_ISNS;
meas_reg = MAX8925_ADC_ISNS;
break;
default:
return -EINVAL;
}
max8925_reg_write(info->adc, meas_cmd, 0);
max8925_bulk_read(info->adc, meas_reg, 2, buf);
ret = (buf[0] << 4) | (buf[1] >> 4);
ret = ((buf[0]<<8) | buf[1]) >> 4;
return ret;
}
......@@ -208,7 +206,7 @@ static int max8925_ac_get_prop(struct power_supply *psy,
if (info->ac_online) {
ret = start_measure(info, MEASURE_VCHG);
if (ret >= 0) {
val->intval = ret << 1; /* unit is mV */
val->intval = ret * 2000; /* unit is uV */
goto out;
}
}
......@@ -242,7 +240,7 @@ static int max8925_usb_get_prop(struct power_supply *psy,
if (info->usb_online) {
ret = start_measure(info, MEASURE_VCHG);
if (ret >= 0) {
val->intval = ret << 1; /* unit is mV */
val->intval = ret * 2000; /* unit is uV */
goto out;
}
}
......@@ -266,7 +264,6 @@ static int max8925_bat_get_prop(struct power_supply *psy,
union power_supply_propval *val)
{
struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
long long int tmp = 0;
int ret = 0;
switch (psp) {
......@@ -277,7 +274,7 @@ static int max8925_bat_get_prop(struct power_supply *psy,
if (info->bat_online) {
ret = start_measure(info, MEASURE_VMBATT);
if (ret >= 0) {
val->intval = ret << 1; /* unit is mV */
val->intval = ret * 2000; /* unit is uV */
ret = 0;
break;
}
......@@ -288,8 +285,8 @@ static int max8925_bat_get_prop(struct power_supply *psy,
if (info->bat_online) {
ret = start_measure(info, MEASURE_ISNS);
if (ret >= 0) {
tmp = (long long int)ret * 6250 / 4096 - 3125;
ret = (int)tmp;
/* assume r_sns is 0.02 */
ret = ((ret * 6250) - 3125) /* uA */;
val->intval = 0;
if (ret > 0)
val->intval = ret; /* unit is mA */
......@@ -365,13 +362,14 @@ static __devinit int max8925_init_charger(struct max8925_chip *chip,
int ret;
REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_OVP, "usb-ovp");
REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_F, "usb-remove");
REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_R, "usb-insert");
REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
if (!info->no_insert_detect) {
REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
}
if (!info->no_temp_support) {
REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
}
REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
......@@ -379,9 +377,15 @@ static __devinit int max8925_init_charger(struct max8925_chip *chip,
REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");
info->ac_online = 0;
info->usb_online = 0;
info->bat_online = 0;
/* check for power - can miss interrupt at boot time */
if (start_measure(info, MEASURE_VCHG) * 2000 > 500000)
info->ac_online = 1;
else
info->ac_online = 0;
ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
if (ret >= 0) {
/*
......@@ -449,6 +453,8 @@ static __devinit int max8925_power_probe(struct platform_device *pdev)
info->ac.properties = max8925_ac_props;
info->ac.num_properties = ARRAY_SIZE(max8925_ac_props);
info->ac.get_property = max8925_ac_get_prop;
info->ac.supplied_to = pdata->supplied_to;
info->ac.num_supplicants = pdata->num_supplicants;
ret = power_supply_register(&pdev->dev, &info->ac);
if (ret)
goto out;
......@@ -459,6 +465,9 @@ static __devinit int max8925_power_probe(struct platform_device *pdev)
info->usb.properties = max8925_usb_props;
info->usb.num_properties = ARRAY_SIZE(max8925_usb_props);
info->usb.get_property = max8925_usb_get_prop;
info->usb.supplied_to = pdata->supplied_to;
info->usb.num_supplicants = pdata->num_supplicants;
ret = power_supply_register(&pdev->dev, &info->usb);
if (ret)
goto out_usb;
......@@ -478,6 +487,8 @@ static __devinit int max8925_power_probe(struct platform_device *pdev)
info->topoff_threshold = pdata->topoff_threshold;
info->fast_charge = pdata->fast_charge;
info->set_charger = pdata->set_charger;
info->no_temp_support = pdata->no_temp_support;
info->no_insert_detect = pdata->no_insert_detect;
max8925_init_charger(chip, info);
return 0;
......@@ -512,17 +523,7 @@ static struct platform_driver max8925_power_driver = {
},
};
static int __init max8925_power_init(void)
{
return platform_driver_register(&max8925_power_driver);
}
module_init(max8925_power_init);
static void __exit max8925_power_exit(void)
{
platform_driver_unregister(&max8925_power_driver);
}
module_exit(max8925_power_exit);
module_platform_driver(max8925_power_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Power supply driver for MAX8925");
......
......@@ -19,7 +19,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/module.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/slab.h>
......@@ -98,7 +97,7 @@ static __devinit int max8997_battery_probe(struct platform_device *pdev)
return -EINVAL;
if (pdata->eoc_mA) {
u8 val = (pdata->eoc_mA - 50) / 10;
int val = (pdata->eoc_mA - 50) / 10;
if (val < 0)
val = 0;
if (val > 0xf)
......@@ -179,6 +178,7 @@ static int __devexit max8997_battery_remove(struct platform_device *pdev)
static const struct platform_device_id max8997_battery_id[] = {
{ "max8997-battery", 0 },
{ }
};
static struct platform_driver max8997_battery_driver = {
......
......@@ -154,6 +154,7 @@ static __devinit int max8998_battery_probe(struct platform_device *pdev)
case 0:
dev_dbg(max8998->dev,
"Full Timeout not set: leave it unchanged.\n");
break;
default:
dev_err(max8998->dev, "Invalid Full Timeout value\n");
ret = -EINVAL;
......@@ -190,6 +191,7 @@ static int __devexit max8998_battery_remove(struct platform_device *pdev)
static const struct platform_device_id max8998_battery_id[] = {
{ "max8998-battery", TYPE_MAX8998 },
{ }
};
static struct platform_driver max8998_battery_driver = {
......@@ -202,17 +204,7 @@ static struct platform_driver max8998_battery_driver = {
.id_table = max8998_battery_id,
};
static int __init max8998_battery_init(void)
{
return platform_driver_register(&max8998_battery_driver);
}
module_init(max8998_battery_init);
static void __exit max8998_battery_cleanup(void)
{
platform_driver_unregister(&max8998_battery_driver);
}
module_exit(max8998_battery_cleanup);
module_platform_driver(max8998_battery_driver);
MODULE_DESCRIPTION("MAXIM 8998 battery control driver");
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
......
......@@ -519,29 +519,35 @@ static struct device_attribute olpc_bat_error = {
* Initialisation
*********************************************************************/
static struct platform_device *bat_pdev;
static struct power_supply olpc_bat = {
.name = "olpc-battery",
.get_property = olpc_bat_get_property,
.use_for_apm = 1,
};
void olpc_battery_trigger_uevent(unsigned long cause)
static int olpc_battery_suspend(struct platform_device *pdev,
pm_message_t state)
{
if (cause & EC_SCI_SRC_ACPWR)
kobject_uevent(&olpc_ac.dev->kobj, KOBJ_CHANGE);
if (cause & (EC_SCI_SRC_BATERR|EC_SCI_SRC_BATSOC|EC_SCI_SRC_BATTERY))
kobject_uevent(&olpc_bat.dev->kobj, KOBJ_CHANGE);
if (device_may_wakeup(olpc_ac.dev))
olpc_ec_wakeup_set(EC_SCI_SRC_ACPWR);
else
olpc_ec_wakeup_clear(EC_SCI_SRC_ACPWR);
if (device_may_wakeup(olpc_bat.dev))
olpc_ec_wakeup_set(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
| EC_SCI_SRC_BATERR);
else
olpc_ec_wakeup_clear(EC_SCI_SRC_BATTERY | EC_SCI_SRC_BATSOC
| EC_SCI_SRC_BATERR);
return 0;
}
static int __init olpc_bat_init(void)
static int __devinit olpc_battery_probe(struct platform_device *pdev)
{
int ret = 0;
int ret;
uint8_t status;
if (!olpc_platform_info.ecver)
return -ENXIO;
/*
* We've seen a number of EC protocol changes; this driver requires
* the latest EC protocol, supported by 0x44 and above.
......@@ -558,15 +564,10 @@ static int __init olpc_bat_init(void)
/* Ignore the status. It doesn't actually matter */
bat_pdev = platform_device_register_simple("olpc-battery", 0, NULL, 0);
if (IS_ERR(bat_pdev))
return PTR_ERR(bat_pdev);
ret = power_supply_register(&bat_pdev->dev, &olpc_ac);
ret = power_supply_register(&pdev->dev, &olpc_ac);
if (ret)
goto ac_failed;
return ret;
olpc_bat.name = bat_pdev->name;
if (olpc_board_at_least(olpc_board_pre(0xd0))) { /* XO-1.5 */
olpc_bat.properties = olpc_xo15_bat_props;
olpc_bat.num_properties = ARRAY_SIZE(olpc_xo15_bat_props);
......@@ -575,7 +576,7 @@ static int __init olpc_bat_init(void)
olpc_bat.num_properties = ARRAY_SIZE(olpc_xo1_bat_props);
}
ret = power_supply_register(&bat_pdev->dev, &olpc_bat);
ret = power_supply_register(&pdev->dev, &olpc_bat);
if (ret)
goto battery_failed;
......@@ -587,7 +588,12 @@ static int __init olpc_bat_init(void)
if (ret)
goto error_failed;
goto success;
if (olpc_ec_wakeup_available()) {
device_set_wakeup_capable(olpc_ac.dev, true);
device_set_wakeup_capable(olpc_bat.dev, true);
}
return 0;
error_failed:
device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom);
......@@ -595,23 +601,36 @@ static int __init olpc_bat_init(void)
power_supply_unregister(&olpc_bat);
battery_failed:
power_supply_unregister(&olpc_ac);
ac_failed:
platform_device_unregister(bat_pdev);
success:
return ret;
}
static void __exit olpc_bat_exit(void)
static int __devexit olpc_battery_remove(struct platform_device *pdev)
{
device_remove_file(olpc_bat.dev, &olpc_bat_error);
device_remove_bin_file(olpc_bat.dev, &olpc_bat_eeprom);
power_supply_unregister(&olpc_bat);
power_supply_unregister(&olpc_ac);
platform_device_unregister(bat_pdev);
return 0;
}
module_init(olpc_bat_init);
module_exit(olpc_bat_exit);
static const struct of_device_id olpc_battery_ids[] __devinitconst = {
{ .compatible = "olpc,xo1-battery" },
{}
};
MODULE_DEVICE_TABLE(of, olpc_battery_ids);
static struct platform_driver olpc_battery_driver = {
.driver = {
.name = "olpc-battery",
.owner = THIS_MODULE,
.of_match_table = olpc_battery_ids,
},
.probe = olpc_battery_probe,
.remove = __devexit_p(olpc_battery_remove),
.suspend = olpc_battery_suspend,
};
module_platform_driver(olpc_battery_driver);
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_LICENSE("GPL");
......
......@@ -474,17 +474,7 @@ static struct platform_driver pcf50633_mbc_driver = {
.remove = __devexit_p(pcf50633_mbc_remove),
};
static int __init pcf50633_mbc_init(void)
{
return platform_driver_register(&pcf50633_mbc_driver);
}
module_init(pcf50633_mbc_init);
static void __exit pcf50633_mbc_exit(void)
{
platform_driver_unregister(&pcf50633_mbc_driver);
}
module_exit(pcf50633_mbc_exit);
module_platform_driver(pcf50633_mbc_driver);
MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
MODULE_DESCRIPTION("PCF50633 mbc driver");
......
......@@ -14,6 +14,7 @@
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/power_supply.h>
#include <linux/pda_power.h>
#include <linux/regulator/consumer.h>
......@@ -40,7 +41,9 @@ static int polling;
#ifdef CONFIG_USB_OTG_UTILS
static struct otg_transceiver *transceiver;
static struct notifier_block otg_nb;
#endif
static struct regulator *ac_draw;
enum {
......@@ -222,7 +225,42 @@ static void polling_timer_func(unsigned long unused)
#ifdef CONFIG_USB_OTG_UTILS
static int otg_is_usb_online(void)
{
return (transceiver->state == OTG_STATE_B_PERIPHERAL);
return (transceiver->last_event == USB_EVENT_VBUS ||
transceiver->last_event == USB_EVENT_ENUMERATED);
}
static int otg_is_ac_online(void)
{
return (transceiver->last_event == USB_EVENT_CHARGER);
}
static int otg_handle_notification(struct notifier_block *nb,
unsigned long event, void *unused)
{
switch (event) {
case USB_EVENT_CHARGER:
ac_status = PDA_PSY_TO_CHANGE;
break;
case USB_EVENT_VBUS:
case USB_EVENT_ENUMERATED:
usb_status = PDA_PSY_TO_CHANGE;
break;
case USB_EVENT_NONE:
ac_status = PDA_PSY_TO_CHANGE;
usb_status = PDA_PSY_TO_CHANGE;
break;
default:
return NOTIFY_OK;
}
/*
* Wait a bit before reading ac/usb line status and setting charger,
* because ac/usb status readings may lag from irq.
*/
mod_timer(&charger_timer,
jiffies + msecs_to_jiffies(pdata->wait_for_status));
return NOTIFY_OK;
}
#endif
......@@ -282,6 +320,16 @@ static int pda_power_probe(struct platform_device *pdev)
ret = PTR_ERR(ac_draw);
}
#ifdef CONFIG_USB_OTG_UTILS
transceiver = otg_get_transceiver();
if (transceiver && !pdata->is_usb_online) {
pdata->is_usb_online = otg_is_usb_online;
}
if (transceiver && !pdata->is_ac_online) {
pdata->is_ac_online = otg_is_ac_online;
}
#endif
if (pdata->is_ac_online) {
ret = power_supply_register(&pdev->dev, &pda_psy_ac);
if (ret) {
......@@ -303,13 +351,6 @@ static int pda_power_probe(struct platform_device *pdev)
}
}
#ifdef CONFIG_USB_OTG_UTILS
transceiver = otg_get_transceiver();
if (transceiver && !pdata->is_usb_online) {
pdata->is_usb_online = otg_is_usb_online;
}
#endif
if (pdata->is_usb_online) {
ret = power_supply_register(&pdev->dev, &pda_psy_usb);
if (ret) {
......@@ -331,6 +372,18 @@ static int pda_power_probe(struct platform_device *pdev)
}
}
#ifdef CONFIG_USB_OTG_UTILS
if (transceiver && pdata->use_otg_notifier) {
otg_nb.notifier_call = otg_handle_notification;
ret = otg_register_notifier(transceiver, &otg_nb);
if (ret) {
dev_err(dev, "failure to register otg notifier\n");
goto otg_reg_notifier_failed;
}
polling = 0;
}
#endif
if (polling) {
dev_dbg(dev, "will poll for status\n");
setup_timer(&polling_timer, polling_timer_func, 0);
......@@ -343,6 +396,11 @@ static int pda_power_probe(struct platform_device *pdev)
return 0;
#ifdef CONFIG_USB_OTG_UTILS
otg_reg_notifier_failed:
if (pdata->is_usb_online && usb_irq)
free_irq(usb_irq->start, &pda_psy_usb);
#endif
usb_irq_failed:
if (pdata->is_usb_online)
power_supply_unregister(&pda_psy_usb);
......@@ -440,8 +498,6 @@ static int pda_power_resume(struct platform_device *pdev)
#define pda_power_resume NULL
#endif /* CONFIG_PM */
MODULE_ALIAS("platform:pda-power");
static struct platform_driver pda_power_pdrv = {
.driver = {
.name = "pda-power",
......@@ -452,17 +508,8 @@ static struct platform_driver pda_power_pdrv = {
.resume = pda_power_resume,
};
static int __init pda_power_init(void)
{
return platform_driver_register(&pda_power_pdrv);
}
module_platform_driver(pda_power_pdrv);
static void __exit pda_power_exit(void)
{
platform_driver_unregister(&pda_power_pdrv);
}
module_init(pda_power_init);
module_exit(pda_power_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
MODULE_ALIAS("platform:pda-power");
......@@ -98,7 +98,9 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data)
{
union power_supply_propval ret = {0,};
struct power_supply *psy = dev_get_drvdata(dev);
unsigned int *count = data;
(*count)++;
if (psy->type != POWER_SUPPLY_TYPE_BATTERY) {
if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &ret))
return 0;
......@@ -111,10 +113,18 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data)
int power_supply_is_system_supplied(void)
{
int error;
unsigned int count = 0;
error = class_for_each_device(power_supply_class, NULL, NULL,
error = class_for_each_device(power_supply_class, NULL, &count,
__power_supply_is_system_supplied);
/*
* If no power class device was found at all, most probably we are
* running on a desktop system, so assume we are on mains power.
*/
if (count == 0)
return 1;
return error;
}
EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
......@@ -147,6 +157,12 @@ struct power_supply *power_supply_get_by_name(char *name)
}
EXPORT_SYMBOL_GPL(power_supply_get_by_name);
int power_supply_powers(struct power_supply *psy, struct device *dev)
{
return sysfs_create_link(&psy->dev->kobj, &dev->kobj, "powers");
}
EXPORT_SYMBOL_GPL(power_supply_powers);
static void power_supply_dev_release(struct device *dev)
{
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
......@@ -202,6 +218,7 @@ EXPORT_SYMBOL_GPL(power_supply_register);
void power_supply_unregister(struct power_supply *psy)
{
cancel_work_sync(&psy->changed_work);
sysfs_remove_link(&psy->dev->kobj, "powers");
power_supply_remove_triggers(psy);
device_unregister(psy->dev);
}
......
......@@ -43,7 +43,7 @@ static ssize_t power_supply_show_property(struct device *dev,
struct device_attribute *attr,
char *buf) {
static char *type_text[] = {
"Battery", "UPS", "Mains", "USB",
"Unknown", "Battery", "UPS", "Mains", "USB",
"USB_DCP", "USB_CDP", "USB_ACA"
};
static char *status_text[] = {
......@@ -63,6 +63,9 @@ static ssize_t power_supply_show_property(struct device *dev,
static char *capacity_level_text[] = {
"Unknown", "Critical", "Low", "Normal", "High", "Full"
};
static char *scope_text[] = {
"Unknown", "System", "Device"
};
ssize_t ret = 0;
struct power_supply *psy = dev_get_drvdata(dev);
const ptrdiff_t off = attr - power_supply_attrs;
......@@ -78,8 +81,8 @@ static ssize_t power_supply_show_property(struct device *dev,
dev_dbg(dev, "driver has no data for `%s' property\n",
attr->attr.name);
else if (ret != -ENODEV)
dev_err(dev, "driver failed to report `%s' property\n",
attr->attr.name);
dev_err(dev, "driver failed to report `%s' property: %zd\n",
attr->attr.name, ret);
return ret;
}
......@@ -95,6 +98,8 @@ static ssize_t power_supply_show_property(struct device *dev,
return sprintf(buf, "%s\n", capacity_level_text[value.intval]);
else if (off == POWER_SUPPLY_PROP_TYPE)
return sprintf(buf, "%s\n", type_text[value.intval]);
else if (off == POWER_SUPPLY_PROP_SCOPE)
return sprintf(buf, "%s\n", scope_text[value.intval]);
else if (off >= POWER_SUPPLY_PROP_MODEL_NAME)
return sprintf(buf, "%s\n", value.strval);
......@@ -167,6 +172,7 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(time_to_full_now),
POWER_SUPPLY_ATTR(time_to_full_avg),
POWER_SUPPLY_ATTR(type),
POWER_SUPPLY_ATTR(scope),
/* Properties of type `const char *' */
POWER_SUPPLY_ATTR(model_name),
POWER_SUPPLY_ATTR(manufacturer),
......
......@@ -47,6 +47,22 @@ static void s3c_adc_bat_ext_power_changed(struct power_supply *psy)
msecs_to_jiffies(JITTER_DELAY));
}
static int gather_samples(struct s3c_adc_client *client, int num, int channel)
{
int value, i;
/* default to 1 if nothing is set */
if (num < 1)
num = 1;
value = 0;
for (i = 0; i < num; i++)
value += s3c_adc_read(client, channel);
value /= num;
return value;
}
static enum power_supply_property s3c_adc_backup_bat_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_MIN,
......@@ -67,7 +83,8 @@ static int s3c_adc_backup_bat_get_property(struct power_supply *psy,
if (bat->volt_value < 0 ||
jiffies_to_msecs(jiffies - bat->timestamp) >
BAT_POLL_INTERVAL) {
bat->volt_value = s3c_adc_read(bat->client,
bat->volt_value = gather_samples(bat->client,
bat->pdata->backup_volt_samples,
bat->pdata->backup_volt_channel);
bat->volt_value *= bat->pdata->backup_volt_mult;
bat->timestamp = jiffies;
......@@ -139,9 +156,11 @@ static int s3c_adc_bat_get_property(struct power_supply *psy,
if (bat->volt_value < 0 || bat->cur_value < 0 ||
jiffies_to_msecs(jiffies - bat->timestamp) >
BAT_POLL_INTERVAL) {
bat->volt_value = s3c_adc_read(bat->client,
bat->volt_value = gather_samples(bat->client,
bat->pdata->volt_samples,
bat->pdata->volt_channel) * bat->pdata->volt_mult;
bat->cur_value = s3c_adc_read(bat->client,
bat->cur_value = gather_samples(bat->client,
bat->pdata->current_samples,
bat->pdata->current_channel) * bat->pdata->current_mult;
bat->timestamp = jiffies;
}
......@@ -421,17 +440,7 @@ static struct platform_driver s3c_adc_bat_driver = {
.resume = s3c_adc_bat_resume,
};
static int __init s3c_adc_bat_init(void)
{
return platform_driver_register(&s3c_adc_bat_driver);
}
module_init(s3c_adc_bat_init);
static void __exit s3c_adc_bat_exit(void)
{
platform_driver_unregister(&s3c_adc_bat_driver);
}
module_exit(s3c_adc_bat_exit);
module_platform_driver(s3c_adc_bat_driver);
MODULE_AUTHOR("Vasily Khoruzhick <anarsoul@gmail.com>");
MODULE_DESCRIPTION("iPAQ H1930/H1940/RX1950 battery controller driver");
......
This diff is collapsed.
......@@ -226,17 +226,7 @@ static struct platform_driver wm831x_backup_driver = {
},
};
static int __init wm831x_backup_init(void)
{
return platform_driver_register(&wm831x_backup_driver);
}
module_init(wm831x_backup_init);
static void __exit wm831x_backup_exit(void)
{
platform_driver_unregister(&wm831x_backup_driver);
}
module_exit(wm831x_backup_exit);
module_platform_driver(wm831x_backup_driver);
MODULE_DESCRIPTION("Backup battery charger driver for WM831x PMICs");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -35,6 +35,8 @@ struct pda_power_pdata {
unsigned int polling_interval; /* msecs, default is 2000 */
unsigned long ac_max_uA; /* current to draw when on AC */
bool use_otg_notifier;
};
#endif /* __PDA_POWER_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment