1 // SPDX-License-Identifier: GPL-2.0-only
3 * Fuel gauge driver for Richtek RT5033
5 * Copyright (C) 2014 Samsung Electronics, Co., Ltd.
6 * Author: Beomho Seo <beomho.seo@samsung.com>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/power_supply.h>
12 #include <linux/mfd/rt5033-private.h>
13 #include <linux/mfd/rt5033.h>
15 static int rt5033_battery_get_capacity(struct i2c_client
*client
)
17 struct rt5033_battery
*battery
= i2c_get_clientdata(client
);
20 regmap_read(battery
->regmap
, RT5033_FUEL_REG_SOC_H
, &msb
);
25 static int rt5033_battery_get_present(struct i2c_client
*client
)
27 struct rt5033_battery
*battery
= i2c_get_clientdata(client
);
30 regmap_read(battery
->regmap
, RT5033_FUEL_REG_CONFIG_L
, &val
);
32 return (val
& RT5033_FUEL_BAT_PRESENT
) ? true : false;
35 static int rt5033_battery_get_watt_prop(struct i2c_client
*client
,
36 enum power_supply_property psp
)
38 struct rt5033_battery
*battery
= i2c_get_clientdata(client
);
39 unsigned int regh
, regl
;
44 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
45 regh
= RT5033_FUEL_REG_VBAT_H
;
46 regl
= RT5033_FUEL_REG_VBAT_L
;
48 case POWER_SUPPLY_PROP_VOLTAGE_AVG
:
49 regh
= RT5033_FUEL_REG_AVG_VOLT_H
;
50 regl
= RT5033_FUEL_REG_AVG_VOLT_L
;
52 case POWER_SUPPLY_PROP_VOLTAGE_OCV
:
53 regh
= RT5033_FUEL_REG_OCV_H
;
54 regl
= RT5033_FUEL_REG_OCV_L
;
60 regmap_read(battery
->regmap
, regh
, &msb
);
61 regmap_read(battery
->regmap
, regl
, &lsb
);
63 ret
= ((msb
<< 4) + (lsb
>> 4)) * 1250 / 1000;
68 static int rt5033_battery_get_property(struct power_supply
*psy
,
69 enum power_supply_property psp
,
70 union power_supply_propval
*val
)
72 struct rt5033_battery
*battery
= power_supply_get_drvdata(psy
);
75 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
76 case POWER_SUPPLY_PROP_VOLTAGE_AVG
:
77 case POWER_SUPPLY_PROP_VOLTAGE_OCV
:
78 val
->intval
= rt5033_battery_get_watt_prop(battery
->client
,
81 case POWER_SUPPLY_PROP_PRESENT
:
82 val
->intval
= rt5033_battery_get_present(battery
->client
);
84 case POWER_SUPPLY_PROP_CAPACITY
:
85 val
->intval
= rt5033_battery_get_capacity(battery
->client
);
93 static enum power_supply_property rt5033_battery_props
[] = {
94 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
95 POWER_SUPPLY_PROP_VOLTAGE_AVG
,
96 POWER_SUPPLY_PROP_VOLTAGE_OCV
,
97 POWER_SUPPLY_PROP_PRESENT
,
98 POWER_SUPPLY_PROP_CAPACITY
,
101 static const struct regmap_config rt5033_battery_regmap_config
= {
104 .max_register
= RT5033_FUEL_REG_END
,
107 static const struct power_supply_desc rt5033_battery_desc
= {
108 .name
= "rt5033-battery",
109 .type
= POWER_SUPPLY_TYPE_BATTERY
,
110 .get_property
= rt5033_battery_get_property
,
111 .properties
= rt5033_battery_props
,
112 .num_properties
= ARRAY_SIZE(rt5033_battery_props
),
115 static int rt5033_battery_probe(struct i2c_client
*client
,
116 const struct i2c_device_id
*id
)
118 struct i2c_adapter
*adapter
= client
->adapter
;
119 struct power_supply_config psy_cfg
= {};
120 struct rt5033_battery
*battery
;
123 if (!i2c_check_functionality(adapter
, I2C_FUNC_SMBUS_BYTE
))
126 battery
= devm_kzalloc(&client
->dev
, sizeof(*battery
), GFP_KERNEL
);
130 battery
->client
= client
;
131 battery
->regmap
= devm_regmap_init_i2c(client
,
132 &rt5033_battery_regmap_config
);
133 if (IS_ERR(battery
->regmap
)) {
134 dev_err(&client
->dev
, "Failed to initialize regmap\n");
138 i2c_set_clientdata(client
, battery
);
139 psy_cfg
.drv_data
= battery
;
141 battery
->psy
= power_supply_register(&client
->dev
,
142 &rt5033_battery_desc
, &psy_cfg
);
143 if (IS_ERR(battery
->psy
)) {
144 dev_err(&client
->dev
, "Failed to register power supply\n");
145 ret
= PTR_ERR(battery
->psy
);
152 static int rt5033_battery_remove(struct i2c_client
*client
)
154 struct rt5033_battery
*battery
= i2c_get_clientdata(client
);
156 power_supply_unregister(battery
->psy
);
161 static const struct i2c_device_id rt5033_battery_id
[] = {
162 { "rt5033-battery", },
165 MODULE_DEVICE_TABLE(i2c
, rt5033_battery_id
);
167 static struct i2c_driver rt5033_battery_driver
= {
169 .name
= "rt5033-battery",
171 .probe
= rt5033_battery_probe
,
172 .remove
= rt5033_battery_remove
,
173 .id_table
= rt5033_battery_id
,
175 module_i2c_driver(rt5033_battery_driver
);
177 MODULE_DESCRIPTION("Richtek RT5033 fuel gauge driver");
178 MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
179 MODULE_LICENSE("GPL");