aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorBeomho Seo <beomho.seo@samsung.com>2015-01-09 03:45:11 -0500
committerSebastian Reichel <sre@kernel.org>2015-01-20 07:58:31 -0500
commitb847dd96e659c13be9d94c3c19b51cdf0feb1c99 (patch)
treed162b0412438418f4ee56fb92bc203b5bd7f0e13 /drivers/power
parent0f2ecb8fa29a0bcda8385bc2277d83e3aeaa2b75 (diff)
power: rt5033_battery: Add RT5033 Fuel gauge device driver
This patch adds device driver of Richtek PMIC. The driver support battery fuel gauge. Fuel gauge calculates and determines the battery state of charge (SOC) according to battery open circuit voltage (OCV). Also, this driver provides battery average voltage, voltage and battery present property. Cc: Sebastian Reichel <sre@kernel.org> Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> Cc: David Woodhouse <dwmw2@infradead.org> Signed-off-by: Beomho Seo <beomho.seo@samsung.com> Acked-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Sebastian Reichel <sre@kernel.org>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/Kconfig8
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/rt5033_battery.c177
3 files changed, 186 insertions, 0 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 0108c2af005b..da6981f92697 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -397,6 +397,14 @@ config BATTERY_GOLDFISH
397 Say Y to enable support for the battery and AC power in the 397 Say Y to enable support for the battery and AC power in the
398 Goldfish emulator. 398 Goldfish emulator.
399 399
400config BATTERY_RT5033
401 tristate "RT5033 fuel gauge support"
402 depends on MFD_RT5033
403 help
404 This adds support for battery fuel gauge in Richtek RT5033 PMIC.
405 The fuelgauge calculates and determines the battery state of charge
406 according to battery open circuit voltage.
407
400source "drivers/power/reset/Kconfig" 408source "drivers/power/reset/Kconfig"
401 409
402endif # POWER_SUPPLY 410endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index dfa894273926..b83a0c749781 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
34obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o 34obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
35obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o 35obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
36obj-$(CONFIG_BATTERY_Z2) += z2_battery.o 36obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
37obj-$(CONFIG_BATTERY_RT5033) += rt5033_battery.o
37obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o 38obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
38obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o 39obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o
39obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o 40obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o
diff --git a/drivers/power/rt5033_battery.c b/drivers/power/rt5033_battery.c
new file mode 100644
index 000000000000..7b898f41c595
--- /dev/null
+++ b/drivers/power/rt5033_battery.c
@@ -0,0 +1,177 @@
1/*
2 * Fuel gauge driver for Richtek RT5033
3 *
4 * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
5 * Author: Beomho Seo <beomho.seo@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published bythe Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/power_supply.h>
15#include <linux/mfd/rt5033-private.h>
16#include <linux/mfd/rt5033.h>
17
18static int rt5033_battery_get_capacity(struct i2c_client *client)
19{
20 struct rt5033_battery *battery = i2c_get_clientdata(client);
21 u32 msb;
22
23 regmap_read(battery->regmap, RT5033_FUEL_REG_SOC_H, &msb);
24
25 return msb;
26}
27
28static int rt5033_battery_get_present(struct i2c_client *client)
29{
30 struct rt5033_battery *battery = i2c_get_clientdata(client);
31 u32 val;
32
33 regmap_read(battery->regmap, RT5033_FUEL_REG_CONFIG_L, &val);
34
35 return (val & RT5033_FUEL_BAT_PRESENT) ? true : false;
36}
37
38static int rt5033_battery_get_watt_prop(struct i2c_client *client,
39 enum power_supply_property psp)
40{
41 struct rt5033_battery *battery = i2c_get_clientdata(client);
42 unsigned int regh, regl;
43 int ret;
44 u32 msb, lsb;
45
46 switch (psp) {
47 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
48 regh = RT5033_FUEL_REG_VBAT_H;
49 regl = RT5033_FUEL_REG_VBAT_L;
50 break;
51 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
52 regh = RT5033_FUEL_REG_AVG_VOLT_H;
53 regl = RT5033_FUEL_REG_AVG_VOLT_L;
54 break;
55 case POWER_SUPPLY_PROP_VOLTAGE_OCV:
56 regh = RT5033_FUEL_REG_OCV_H;
57 regl = RT5033_FUEL_REG_OCV_L;
58 break;
59 default:
60 return -EINVAL;
61 }
62
63 regmap_read(battery->regmap, regh, &msb);
64 regmap_read(battery->regmap, regl, &lsb);
65
66 ret = ((msb << 4) + (lsb >> 4)) * 1250 / 1000;
67
68 return ret;
69}
70
71static int rt5033_battery_get_property(struct power_supply *psy,
72 enum power_supply_property psp,
73 union power_supply_propval *val)
74{
75 struct rt5033_battery *battery = container_of(psy,
76 struct rt5033_battery, psy);
77
78 switch (psp) {
79 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
80 case POWER_SUPPLY_PROP_VOLTAGE_AVG:
81 case POWER_SUPPLY_PROP_VOLTAGE_OCV:
82 val->intval = rt5033_battery_get_watt_prop(battery->client,
83 psp);
84 break;
85 case POWER_SUPPLY_PROP_PRESENT:
86 val->intval = rt5033_battery_get_present(battery->client);
87 break;
88 case POWER_SUPPLY_PROP_CAPACITY:
89 val->intval = rt5033_battery_get_capacity(battery->client);
90 break;
91 default:
92 return -EINVAL;
93 }
94 return 0;
95}
96
97static enum power_supply_property rt5033_battery_props[] = {
98 POWER_SUPPLY_PROP_VOLTAGE_NOW,
99 POWER_SUPPLY_PROP_VOLTAGE_AVG,
100 POWER_SUPPLY_PROP_VOLTAGE_OCV,
101 POWER_SUPPLY_PROP_PRESENT,
102 POWER_SUPPLY_PROP_CAPACITY,
103};
104
105static struct regmap_config rt5033_battery_regmap_config = {
106 .reg_bits = 8,
107 .val_bits = 8,
108 .max_register = RT5033_FUEL_REG_END,
109};
110
111static int rt5033_battery_probe(struct i2c_client *client,
112 const struct i2c_device_id *id)
113{
114 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
115 struct rt5033_battery *battery;
116 u32 ret;
117
118 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
119 return -EIO;
120
121 battery = devm_kzalloc(&client->dev, sizeof(*battery), GFP_KERNEL);
122 if (!battery)
123 return -EINVAL;
124
125 battery->client = client;
126 battery->regmap = devm_regmap_init_i2c(client,
127 &rt5033_battery_regmap_config);
128 if (IS_ERR(battery->regmap)) {
129 dev_err(&client->dev, "Failed to initialize regmap\n");
130 return -EINVAL;
131 }
132
133 i2c_set_clientdata(client, battery);
134
135 battery->psy.name = "rt5033-battery";
136 battery->psy.type = POWER_SUPPLY_TYPE_BATTERY;
137 battery->psy.get_property = rt5033_battery_get_property;
138 battery->psy.properties = rt5033_battery_props;
139 battery->psy.num_properties = ARRAY_SIZE(rt5033_battery_props);
140
141 ret = power_supply_register(&client->dev, &battery->psy);
142 if (ret) {
143 dev_err(&client->dev, "Failed to register power supply\n");
144 return ret;
145 }
146
147 return 0;
148}
149
150static int rt5033_battery_remove(struct i2c_client *client)
151{
152 struct rt5033_battery *battery = i2c_get_clientdata(client);
153
154 power_supply_unregister(&battery->psy);
155
156 return 0;
157}
158
159static const struct i2c_device_id rt5033_battery_id[] = {
160 { "rt5033-battery", },
161 { }
162};
163MODULE_DEVICE_TABLE(platform, rt5033_battery_id);
164
165static struct i2c_driver rt5033_battery_driver = {
166 .driver = {
167 .name = "rt5033-battery",
168 },
169 .probe = rt5033_battery_probe,
170 .remove = rt5033_battery_remove,
171 .id_table = rt5033_battery_id,
172};
173module_i2c_driver(rt5033_battery_driver);
174
175MODULE_DESCRIPTION("Richtek RT5033 fuel gauge driver");
176MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
177MODULE_LICENSE("GPL");