2 * Fuel gauge driver for Richtek RT5033
4 * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
5 * Author: Beomho Seo <beomho.seo@samsung.com>
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.
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>
18 static int rt5033_battery_get_capacity(struct i2c_client
*client
)
20 struct rt5033_battery
*battery
= i2c_get_clientdata(client
);
23 regmap_read(battery
->regmap
, RT5033_FUEL_REG_SOC_H
, &msb
);
28 static int rt5033_battery_get_present(struct i2c_client
*client
)
30 struct rt5033_battery
*battery
= i2c_get_clientdata(client
);
33 regmap_read(battery
->regmap
, RT5033_FUEL_REG_CONFIG_L
, &val
);
35 return (val
& RT5033_FUEL_BAT_PRESENT
) ? true : false;
38 static int rt5033_battery_get_watt_prop(struct i2c_client
*client
,
39 enum power_supply_property psp
)
41 struct rt5033_battery
*battery
= i2c_get_clientdata(client
);
42 unsigned int regh
, regl
;
47 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
48 regh
= RT5033_FUEL_REG_VBAT_H
;
49 regl
= RT5033_FUEL_REG_VBAT_L
;
51 case POWER_SUPPLY_PROP_VOLTAGE_AVG
:
52 regh
= RT5033_FUEL_REG_AVG_VOLT_H
;
53 regl
= RT5033_FUEL_REG_AVG_VOLT_L
;
55 case POWER_SUPPLY_PROP_VOLTAGE_OCV
:
56 regh
= RT5033_FUEL_REG_OCV_H
;
57 regl
= RT5033_FUEL_REG_OCV_L
;
63 regmap_read(battery
->regmap
, regh
, &msb
);
64 regmap_read(battery
->regmap
, regl
, &lsb
);
66 ret
= ((msb
<< 4) + (lsb
>> 4)) * 1250 / 1000;
71 static int rt5033_battery_get_property(struct power_supply
*psy
,
72 enum power_supply_property psp
,
73 union power_supply_propval
*val
)
75 struct rt5033_battery
*battery
= power_supply_get_drvdata(psy
);
78 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
79 case POWER_SUPPLY_PROP_VOLTAGE_AVG
:
80 case POWER_SUPPLY_PROP_VOLTAGE_OCV
:
81 val
->intval
= rt5033_battery_get_watt_prop(battery
->client
,
84 case POWER_SUPPLY_PROP_PRESENT
:
85 val
->intval
= rt5033_battery_get_present(battery
->client
);
87 case POWER_SUPPLY_PROP_CAPACITY
:
88 val
->intval
= rt5033_battery_get_capacity(battery
->client
);
96 static enum power_supply_property rt5033_battery_props
[] = {
97 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
98 POWER_SUPPLY_PROP_VOLTAGE_AVG
,
99 POWER_SUPPLY_PROP_VOLTAGE_OCV
,
100 POWER_SUPPLY_PROP_PRESENT
,
101 POWER_SUPPLY_PROP_CAPACITY
,
104 static const struct regmap_config rt5033_battery_regmap_config
= {
107 .max_register
= RT5033_FUEL_REG_END
,
110 static const struct power_supply_desc rt5033_battery_desc
= {
111 .name
= "rt5033-battery",
112 .type
= POWER_SUPPLY_TYPE_BATTERY
,
113 .get_property
= rt5033_battery_get_property
,
114 .properties
= rt5033_battery_props
,
115 .num_properties
= ARRAY_SIZE(rt5033_battery_props
),
118 static int rt5033_battery_probe(struct i2c_client
*client
,
119 const struct i2c_device_id
*id
)
121 struct i2c_adapter
*adapter
= to_i2c_adapter(client
->dev
.parent
);
122 struct power_supply_config psy_cfg
= {};
123 struct rt5033_battery
*battery
;
126 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_BYTE
))
129 battery
= devm_kzalloc(&client
->dev
, sizeof(*battery
), GFP_KERNEL
);
133 battery
->client
= client
;
134 battery
->regmap
= devm_regmap_init_i2c(client
,
135 &rt5033_battery_regmap_config
);
136 if (IS_ERR(battery
->regmap
)) {
137 dev_err(&client
->dev
, "Failed to initialize regmap\n");
141 i2c_set_clientdata(client
, battery
);
142 psy_cfg
.drv_data
= battery
;
144 battery
->psy
= power_supply_register(&client
->dev
,
145 &rt5033_battery_desc
, &psy_cfg
);
146 if (IS_ERR(battery
->psy
)) {
147 dev_err(&client
->dev
, "Failed to register power supply\n");
148 ret
= PTR_ERR(battery
->psy
);
155 static int rt5033_battery_remove(struct i2c_client
*client
)
157 struct rt5033_battery
*battery
= i2c_get_clientdata(client
);
159 power_supply_unregister(battery
->psy
);
164 static const struct i2c_device_id rt5033_battery_id
[] = {
165 { "rt5033-battery", },
168 MODULE_DEVICE_TABLE(platform
, rt5033_battery_id
);
170 static struct i2c_driver rt5033_battery_driver
= {
172 .name
= "rt5033-battery",
174 .probe
= rt5033_battery_probe
,
175 .remove
= rt5033_battery_remove
,
176 .id_table
= rt5033_battery_id
,
178 module_i2c_driver(rt5033_battery_driver
);
180 MODULE_DESCRIPTION("Richtek RT5033 fuel gauge driver");
181 MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
182 MODULE_LICENSE("GPL");