xref: /linux/drivers/power/supply/chagall-battery.c (revision c7c18635363f06c1943514c2f4c8170b325302e8)
1*fbc1d056SSvyatoslav Ryhel // SPDX-License-Identifier: GPL-2.0-or-later
2*fbc1d056SSvyatoslav Ryhel 
3*fbc1d056SSvyatoslav Ryhel #include <linux/array_size.h>
4*fbc1d056SSvyatoslav Ryhel #include <linux/delay.h>
5*fbc1d056SSvyatoslav Ryhel #include <linux/devm-helpers.h>
6*fbc1d056SSvyatoslav Ryhel #include <linux/err.h>
7*fbc1d056SSvyatoslav Ryhel #include <linux/i2c.h>
8*fbc1d056SSvyatoslav Ryhel #include <linux/leds.h>
9*fbc1d056SSvyatoslav Ryhel #include <linux/mod_devicetable.h>
10*fbc1d056SSvyatoslav Ryhel #include <linux/module.h>
11*fbc1d056SSvyatoslav Ryhel #include <linux/power_supply.h>
12*fbc1d056SSvyatoslav Ryhel #include <linux/regmap.h>
13*fbc1d056SSvyatoslav Ryhel 
14*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_LED_AMBER				0x60
15*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_LED_WHITE				0x70
16*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_BATTERY_TEMPERATURE			0xa2
17*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_BATTERY_VOLTAGE			0xa4
18*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_BATTERY_CURRENT			0xa6
19*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_BATTERY_CAPACITY			0xa8
20*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_BATTERY_CHARGING_CURRENT		0xaa
21*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_BATTERY_CHARGING_VOLTAGE		0xac
22*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_BATTERY_STATUS			0xae
23*fbc1d056SSvyatoslav Ryhel #define   BATTERY_DISCHARGING				BIT(6)
24*fbc1d056SSvyatoslav Ryhel #define   BATTERY_FULL_CHARGED				BIT(5)
25*fbc1d056SSvyatoslav Ryhel #define   BATTERY_FULL_DISCHARGED			BIT(4)
26*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_BATTERY_REMAIN_CAPACITY		0xb0
27*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_BATTERY_FULL_CAPACITY		0xb2
28*fbc1d056SSvyatoslav Ryhel #define CHAGALL_REG_MAX_COUNT				0xb4
29*fbc1d056SSvyatoslav Ryhel 
30*fbc1d056SSvyatoslav Ryhel #define CHAGALL_BATTERY_DATA_REFRESH			5000
31*fbc1d056SSvyatoslav Ryhel #define TEMP_CELSIUS_OFFSET				2731
32*fbc1d056SSvyatoslav Ryhel 
33*fbc1d056SSvyatoslav Ryhel static const struct regmap_config chagall_battery_regmap_config = {
34*fbc1d056SSvyatoslav Ryhel 	.reg_bits = 8,
35*fbc1d056SSvyatoslav Ryhel 	.val_bits = 8,
36*fbc1d056SSvyatoslav Ryhel 	.max_register = CHAGALL_REG_MAX_COUNT,
37*fbc1d056SSvyatoslav Ryhel 	.reg_format_endian = REGMAP_ENDIAN_LITTLE,
38*fbc1d056SSvyatoslav Ryhel 	.val_format_endian = REGMAP_ENDIAN_LITTLE,
39*fbc1d056SSvyatoslav Ryhel };
40*fbc1d056SSvyatoslav Ryhel 
41*fbc1d056SSvyatoslav Ryhel struct chagall_battery_data {
42*fbc1d056SSvyatoslav Ryhel 	struct regmap *regmap;
43*fbc1d056SSvyatoslav Ryhel 	struct led_classdev amber_led;
44*fbc1d056SSvyatoslav Ryhel 	struct led_classdev white_led;
45*fbc1d056SSvyatoslav Ryhel 	struct power_supply *battery;
46*fbc1d056SSvyatoslav Ryhel 	struct delayed_work poll_work;
47*fbc1d056SSvyatoslav Ryhel 	u16 last_state;
48*fbc1d056SSvyatoslav Ryhel };
49*fbc1d056SSvyatoslav Ryhel 
chagall_led_set_brightness_amber(struct led_classdev * led,enum led_brightness brightness)50*fbc1d056SSvyatoslav Ryhel static void chagall_led_set_brightness_amber(struct led_classdev *led,
51*fbc1d056SSvyatoslav Ryhel 					     enum led_brightness brightness)
52*fbc1d056SSvyatoslav Ryhel {
53*fbc1d056SSvyatoslav Ryhel 	struct chagall_battery_data *cg =
54*fbc1d056SSvyatoslav Ryhel 		container_of(led, struct chagall_battery_data, amber_led);
55*fbc1d056SSvyatoslav Ryhel 
56*fbc1d056SSvyatoslav Ryhel 	regmap_write(cg->regmap, CHAGALL_REG_LED_AMBER, brightness);
57*fbc1d056SSvyatoslav Ryhel }
58*fbc1d056SSvyatoslav Ryhel 
chagall_led_set_brightness_white(struct led_classdev * led,enum led_brightness brightness)59*fbc1d056SSvyatoslav Ryhel static void chagall_led_set_brightness_white(struct led_classdev *led,
60*fbc1d056SSvyatoslav Ryhel 					     enum led_brightness brightness)
61*fbc1d056SSvyatoslav Ryhel {
62*fbc1d056SSvyatoslav Ryhel 	struct chagall_battery_data *cg =
63*fbc1d056SSvyatoslav Ryhel 		container_of(led, struct chagall_battery_data, white_led);
64*fbc1d056SSvyatoslav Ryhel 
65*fbc1d056SSvyatoslav Ryhel 	regmap_write(cg->regmap, CHAGALL_REG_LED_WHITE, brightness);
66*fbc1d056SSvyatoslav Ryhel }
67*fbc1d056SSvyatoslav Ryhel 
68*fbc1d056SSvyatoslav Ryhel static const enum power_supply_property chagall_battery_properties[] = {
69*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_STATUS,
70*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_PRESENT,
71*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
72*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_VOLTAGE_MAX,
73*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_CURRENT_NOW,
74*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_CURRENT_MAX,
75*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_CAPACITY,
76*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_TEMP,
77*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_CHARGE_FULL,
78*fbc1d056SSvyatoslav Ryhel 	POWER_SUPPLY_PROP_CHARGE_NOW,
79*fbc1d056SSvyatoslav Ryhel };
80*fbc1d056SSvyatoslav Ryhel 
81*fbc1d056SSvyatoslav Ryhel static const unsigned int chagall_battery_prop_offs[] = {
82*fbc1d056SSvyatoslav Ryhel 	[POWER_SUPPLY_PROP_STATUS] = CHAGALL_REG_BATTERY_STATUS,
83*fbc1d056SSvyatoslav Ryhel 	[POWER_SUPPLY_PROP_VOLTAGE_NOW] = CHAGALL_REG_BATTERY_VOLTAGE,
84*fbc1d056SSvyatoslav Ryhel 	[POWER_SUPPLY_PROP_VOLTAGE_MAX] = CHAGALL_REG_BATTERY_CHARGING_VOLTAGE,
85*fbc1d056SSvyatoslav Ryhel 	[POWER_SUPPLY_PROP_CURRENT_NOW] = CHAGALL_REG_BATTERY_CURRENT,
86*fbc1d056SSvyatoslav Ryhel 	[POWER_SUPPLY_PROP_CURRENT_MAX] = CHAGALL_REG_BATTERY_CHARGING_CURRENT,
87*fbc1d056SSvyatoslav Ryhel 	[POWER_SUPPLY_PROP_CAPACITY] = CHAGALL_REG_BATTERY_CAPACITY,
88*fbc1d056SSvyatoslav Ryhel 	[POWER_SUPPLY_PROP_TEMP] = CHAGALL_REG_BATTERY_TEMPERATURE,
89*fbc1d056SSvyatoslav Ryhel 	[POWER_SUPPLY_PROP_CHARGE_FULL] = CHAGALL_REG_BATTERY_FULL_CAPACITY,
90*fbc1d056SSvyatoslav Ryhel 	[POWER_SUPPLY_PROP_CHARGE_NOW] = CHAGALL_REG_BATTERY_REMAIN_CAPACITY,
91*fbc1d056SSvyatoslav Ryhel };
92*fbc1d056SSvyatoslav Ryhel 
chagall_battery_get_value(struct chagall_battery_data * cg,enum power_supply_property psp,u32 * val)93*fbc1d056SSvyatoslav Ryhel static int chagall_battery_get_value(struct chagall_battery_data *cg,
94*fbc1d056SSvyatoslav Ryhel 				     enum power_supply_property psp, u32 *val)
95*fbc1d056SSvyatoslav Ryhel {
96*fbc1d056SSvyatoslav Ryhel 	if (psp >= ARRAY_SIZE(chagall_battery_prop_offs))
97*fbc1d056SSvyatoslav Ryhel 		return -EINVAL;
98*fbc1d056SSvyatoslav Ryhel 	if (!chagall_battery_prop_offs[psp])
99*fbc1d056SSvyatoslav Ryhel 		return -EINVAL;
100*fbc1d056SSvyatoslav Ryhel 
101*fbc1d056SSvyatoslav Ryhel 	/* Battery data is stored in 2 consecutive registers with little-endian */
102*fbc1d056SSvyatoslav Ryhel 	return regmap_bulk_read(cg->regmap, chagall_battery_prop_offs[psp], val, 2);
103*fbc1d056SSvyatoslav Ryhel }
104*fbc1d056SSvyatoslav Ryhel 
chagall_battery_get_status(u32 status_reg)105*fbc1d056SSvyatoslav Ryhel static int chagall_battery_get_status(u32 status_reg)
106*fbc1d056SSvyatoslav Ryhel {
107*fbc1d056SSvyatoslav Ryhel 	if (status_reg & BATTERY_FULL_CHARGED)
108*fbc1d056SSvyatoslav Ryhel 		return POWER_SUPPLY_STATUS_FULL;
109*fbc1d056SSvyatoslav Ryhel 	else if (status_reg & BATTERY_DISCHARGING)
110*fbc1d056SSvyatoslav Ryhel 		return POWER_SUPPLY_STATUS_DISCHARGING;
111*fbc1d056SSvyatoslav Ryhel 	else
112*fbc1d056SSvyatoslav Ryhel 		return POWER_SUPPLY_STATUS_CHARGING;
113*fbc1d056SSvyatoslav Ryhel }
114*fbc1d056SSvyatoslav Ryhel 
chagall_battery_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)115*fbc1d056SSvyatoslav Ryhel static int chagall_battery_get_property(struct power_supply *psy,
116*fbc1d056SSvyatoslav Ryhel 					enum power_supply_property psp,
117*fbc1d056SSvyatoslav Ryhel 					union power_supply_propval *val)
118*fbc1d056SSvyatoslav Ryhel {
119*fbc1d056SSvyatoslav Ryhel 	struct chagall_battery_data *cg = power_supply_get_drvdata(psy);
120*fbc1d056SSvyatoslav Ryhel 	int ret;
121*fbc1d056SSvyatoslav Ryhel 
122*fbc1d056SSvyatoslav Ryhel 	switch (psp) {
123*fbc1d056SSvyatoslav Ryhel 	case POWER_SUPPLY_PROP_PRESENT:
124*fbc1d056SSvyatoslav Ryhel 		val->intval = 1;
125*fbc1d056SSvyatoslav Ryhel 		break;
126*fbc1d056SSvyatoslav Ryhel 
127*fbc1d056SSvyatoslav Ryhel 	default:
128*fbc1d056SSvyatoslav Ryhel 		ret = chagall_battery_get_value(cg, psp, &val->intval);
129*fbc1d056SSvyatoslav Ryhel 		if (ret)
130*fbc1d056SSvyatoslav Ryhel 			return ret;
131*fbc1d056SSvyatoslav Ryhel 
132*fbc1d056SSvyatoslav Ryhel 		switch (psp) {
133*fbc1d056SSvyatoslav Ryhel 		case POWER_SUPPLY_PROP_TEMP:
134*fbc1d056SSvyatoslav Ryhel 			val->intval -= TEMP_CELSIUS_OFFSET;
135*fbc1d056SSvyatoslav Ryhel 			break;
136*fbc1d056SSvyatoslav Ryhel 
137*fbc1d056SSvyatoslav Ryhel 		case POWER_SUPPLY_PROP_VOLTAGE_MAX:
138*fbc1d056SSvyatoslav Ryhel 		case POWER_SUPPLY_PROP_VOLTAGE_NOW:
139*fbc1d056SSvyatoslav Ryhel 		case POWER_SUPPLY_PROP_CURRENT_MAX:
140*fbc1d056SSvyatoslav Ryhel 		case POWER_SUPPLY_PROP_CURRENT_NOW:
141*fbc1d056SSvyatoslav Ryhel 		case POWER_SUPPLY_PROP_CHARGE_FULL:
142*fbc1d056SSvyatoslav Ryhel 		case POWER_SUPPLY_PROP_CHARGE_NOW:
143*fbc1d056SSvyatoslav Ryhel 			val->intval *= 1000;
144*fbc1d056SSvyatoslav Ryhel 			break;
145*fbc1d056SSvyatoslav Ryhel 
146*fbc1d056SSvyatoslav Ryhel 		case POWER_SUPPLY_PROP_STATUS:
147*fbc1d056SSvyatoslav Ryhel 			val->intval = chagall_battery_get_status(val->intval);
148*fbc1d056SSvyatoslav Ryhel 			break;
149*fbc1d056SSvyatoslav Ryhel 
150*fbc1d056SSvyatoslav Ryhel 		default:
151*fbc1d056SSvyatoslav Ryhel 			break;
152*fbc1d056SSvyatoslav Ryhel 		}
153*fbc1d056SSvyatoslav Ryhel 
154*fbc1d056SSvyatoslav Ryhel 		break;
155*fbc1d056SSvyatoslav Ryhel 	}
156*fbc1d056SSvyatoslav Ryhel 
157*fbc1d056SSvyatoslav Ryhel 	return 0;
158*fbc1d056SSvyatoslav Ryhel }
159*fbc1d056SSvyatoslav Ryhel 
chagall_battery_poll_work(struct work_struct * work)160*fbc1d056SSvyatoslav Ryhel static void chagall_battery_poll_work(struct work_struct *work)
161*fbc1d056SSvyatoslav Ryhel {
162*fbc1d056SSvyatoslav Ryhel 	struct chagall_battery_data *cg =
163*fbc1d056SSvyatoslav Ryhel 		container_of(work, struct chagall_battery_data, poll_work.work);
164*fbc1d056SSvyatoslav Ryhel 	u32 state;
165*fbc1d056SSvyatoslav Ryhel 	int ret;
166*fbc1d056SSvyatoslav Ryhel 
167*fbc1d056SSvyatoslav Ryhel 	ret = chagall_battery_get_value(cg, POWER_SUPPLY_PROP_STATUS, &state);
168*fbc1d056SSvyatoslav Ryhel 	if (ret)
169*fbc1d056SSvyatoslav Ryhel 		return;
170*fbc1d056SSvyatoslav Ryhel 
171*fbc1d056SSvyatoslav Ryhel 	state = chagall_battery_get_status(state);
172*fbc1d056SSvyatoslav Ryhel 
173*fbc1d056SSvyatoslav Ryhel 	if (cg->last_state != state) {
174*fbc1d056SSvyatoslav Ryhel 		cg->last_state = state;
175*fbc1d056SSvyatoslav Ryhel 		power_supply_changed(cg->battery);
176*fbc1d056SSvyatoslav Ryhel 	}
177*fbc1d056SSvyatoslav Ryhel 
178*fbc1d056SSvyatoslav Ryhel 	/* continuously send uevent notification */
179*fbc1d056SSvyatoslav Ryhel 	schedule_delayed_work(&cg->poll_work,
180*fbc1d056SSvyatoslav Ryhel 			      msecs_to_jiffies(CHAGALL_BATTERY_DATA_REFRESH));
181*fbc1d056SSvyatoslav Ryhel }
182*fbc1d056SSvyatoslav Ryhel 
183*fbc1d056SSvyatoslav Ryhel static const struct power_supply_desc chagall_battery_desc = {
184*fbc1d056SSvyatoslav Ryhel 	.name = "chagall-battery",
185*fbc1d056SSvyatoslav Ryhel 	.type = POWER_SUPPLY_TYPE_BATTERY,
186*fbc1d056SSvyatoslav Ryhel 	.properties = chagall_battery_properties,
187*fbc1d056SSvyatoslav Ryhel 	.num_properties = ARRAY_SIZE(chagall_battery_properties),
188*fbc1d056SSvyatoslav Ryhel 	.get_property = chagall_battery_get_property,
189*fbc1d056SSvyatoslav Ryhel 	.external_power_changed = power_supply_changed,
190*fbc1d056SSvyatoslav Ryhel };
191*fbc1d056SSvyatoslav Ryhel 
chagall_battery_probe(struct i2c_client * client)192*fbc1d056SSvyatoslav Ryhel static int chagall_battery_probe(struct i2c_client *client)
193*fbc1d056SSvyatoslav Ryhel {
194*fbc1d056SSvyatoslav Ryhel 	struct chagall_battery_data *cg;
195*fbc1d056SSvyatoslav Ryhel 	struct device *dev = &client->dev;
196*fbc1d056SSvyatoslav Ryhel 	struct power_supply_config cfg = { };
197*fbc1d056SSvyatoslav Ryhel 	int ret;
198*fbc1d056SSvyatoslav Ryhel 
199*fbc1d056SSvyatoslav Ryhel 	cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL);
200*fbc1d056SSvyatoslav Ryhel 	if (!cg)
201*fbc1d056SSvyatoslav Ryhel 		return -ENOMEM;
202*fbc1d056SSvyatoslav Ryhel 
203*fbc1d056SSvyatoslav Ryhel 	cfg.drv_data = cg;
204*fbc1d056SSvyatoslav Ryhel 	cfg.fwnode = dev_fwnode(dev);
205*fbc1d056SSvyatoslav Ryhel 
206*fbc1d056SSvyatoslav Ryhel 	i2c_set_clientdata(client, cg);
207*fbc1d056SSvyatoslav Ryhel 
208*fbc1d056SSvyatoslav Ryhel 	cg->regmap = devm_regmap_init_i2c(client, &chagall_battery_regmap_config);
209*fbc1d056SSvyatoslav Ryhel 	if (IS_ERR(cg->regmap))
210*fbc1d056SSvyatoslav Ryhel 		return dev_err_probe(dev, PTR_ERR(cg->regmap), "cannot allocate regmap\n");
211*fbc1d056SSvyatoslav Ryhel 
212*fbc1d056SSvyatoslav Ryhel 	cg->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
213*fbc1d056SSvyatoslav Ryhel 	cg->battery = devm_power_supply_register(dev, &chagall_battery_desc, &cfg);
214*fbc1d056SSvyatoslav Ryhel 	if (IS_ERR(cg->battery))
215*fbc1d056SSvyatoslav Ryhel 		return dev_err_probe(dev, PTR_ERR(cg->battery),
216*fbc1d056SSvyatoslav Ryhel 				     "failed to register power supply\n");
217*fbc1d056SSvyatoslav Ryhel 
218*fbc1d056SSvyatoslav Ryhel 	cg->amber_led.name = "power::amber";
219*fbc1d056SSvyatoslav Ryhel 	cg->amber_led.max_brightness = 1;
220*fbc1d056SSvyatoslav Ryhel 	cg->amber_led.flags = LED_CORE_SUSPENDRESUME;
221*fbc1d056SSvyatoslav Ryhel 	cg->amber_led.brightness_set = chagall_led_set_brightness_amber;
222*fbc1d056SSvyatoslav Ryhel 	cg->amber_led.default_trigger = "chagall-battery-charging";
223*fbc1d056SSvyatoslav Ryhel 
224*fbc1d056SSvyatoslav Ryhel 	ret = devm_led_classdev_register(dev, &cg->amber_led);
225*fbc1d056SSvyatoslav Ryhel 	if (ret)
226*fbc1d056SSvyatoslav Ryhel 		return dev_err_probe(dev, ret, "failed to register amber LED\n");
227*fbc1d056SSvyatoslav Ryhel 
228*fbc1d056SSvyatoslav Ryhel 	cg->white_led.name = "power::white";
229*fbc1d056SSvyatoslav Ryhel 	cg->white_led.max_brightness = 1;
230*fbc1d056SSvyatoslav Ryhel 	cg->white_led.flags = LED_CORE_SUSPENDRESUME;
231*fbc1d056SSvyatoslav Ryhel 	cg->white_led.brightness_set = chagall_led_set_brightness_white;
232*fbc1d056SSvyatoslav Ryhel 	cg->white_led.default_trigger = "chagall-battery-full";
233*fbc1d056SSvyatoslav Ryhel 
234*fbc1d056SSvyatoslav Ryhel 	ret = devm_led_classdev_register(dev, &cg->white_led);
235*fbc1d056SSvyatoslav Ryhel 	if (ret)
236*fbc1d056SSvyatoslav Ryhel 		return dev_err_probe(dev, ret, "failed to register white LED\n");
237*fbc1d056SSvyatoslav Ryhel 
238*fbc1d056SSvyatoslav Ryhel 	led_set_brightness(&cg->amber_led, LED_OFF);
239*fbc1d056SSvyatoslav Ryhel 	led_set_brightness(&cg->white_led, LED_OFF);
240*fbc1d056SSvyatoslav Ryhel 
241*fbc1d056SSvyatoslav Ryhel 	ret = devm_delayed_work_autocancel(dev, &cg->poll_work, chagall_battery_poll_work);
242*fbc1d056SSvyatoslav Ryhel 	if (ret)
243*fbc1d056SSvyatoslav Ryhel 		return ret;
244*fbc1d056SSvyatoslav Ryhel 
245*fbc1d056SSvyatoslav Ryhel 	schedule_delayed_work(&cg->poll_work, msecs_to_jiffies(CHAGALL_BATTERY_DATA_REFRESH));
246*fbc1d056SSvyatoslav Ryhel 
247*fbc1d056SSvyatoslav Ryhel 	return 0;
248*fbc1d056SSvyatoslav Ryhel }
249*fbc1d056SSvyatoslav Ryhel 
chagall_battery_suspend(struct device * dev)250*fbc1d056SSvyatoslav Ryhel static int __maybe_unused chagall_battery_suspend(struct device *dev)
251*fbc1d056SSvyatoslav Ryhel {
252*fbc1d056SSvyatoslav Ryhel 	struct i2c_client *client = to_i2c_client(dev);
253*fbc1d056SSvyatoslav Ryhel 	struct chagall_battery_data *cg = i2c_get_clientdata(client);
254*fbc1d056SSvyatoslav Ryhel 
255*fbc1d056SSvyatoslav Ryhel 	cancel_delayed_work_sync(&cg->poll_work);
256*fbc1d056SSvyatoslav Ryhel 
257*fbc1d056SSvyatoslav Ryhel 	return 0;
258*fbc1d056SSvyatoslav Ryhel }
259*fbc1d056SSvyatoslav Ryhel 
chagall_battery_resume(struct device * dev)260*fbc1d056SSvyatoslav Ryhel static int __maybe_unused chagall_battery_resume(struct device *dev)
261*fbc1d056SSvyatoslav Ryhel {
262*fbc1d056SSvyatoslav Ryhel 	struct i2c_client *client = to_i2c_client(dev);
263*fbc1d056SSvyatoslav Ryhel 	struct chagall_battery_data *cg = i2c_get_clientdata(client);
264*fbc1d056SSvyatoslav Ryhel 
265*fbc1d056SSvyatoslav Ryhel 	schedule_delayed_work(&cg->poll_work, msecs_to_jiffies(CHAGALL_BATTERY_DATA_REFRESH));
266*fbc1d056SSvyatoslav Ryhel 
267*fbc1d056SSvyatoslav Ryhel 	return 0;
268*fbc1d056SSvyatoslav Ryhel }
269*fbc1d056SSvyatoslav Ryhel 
270*fbc1d056SSvyatoslav Ryhel static SIMPLE_DEV_PM_OPS(chagall_battery_pm_ops,
271*fbc1d056SSvyatoslav Ryhel 			 chagall_battery_suspend, chagall_battery_resume);
272*fbc1d056SSvyatoslav Ryhel 
273*fbc1d056SSvyatoslav Ryhel static const struct of_device_id chagall_of_match[] = {
274*fbc1d056SSvyatoslav Ryhel 	{ .compatible = "pegatron,chagall-ec" },
275*fbc1d056SSvyatoslav Ryhel 	{ }
276*fbc1d056SSvyatoslav Ryhel };
277*fbc1d056SSvyatoslav Ryhel MODULE_DEVICE_TABLE(of, chagall_of_match);
278*fbc1d056SSvyatoslav Ryhel 
279*fbc1d056SSvyatoslav Ryhel static struct i2c_driver chagall_battery_driver = {
280*fbc1d056SSvyatoslav Ryhel 	.driver = {
281*fbc1d056SSvyatoslav Ryhel 		.name = "chagall-battery",
282*fbc1d056SSvyatoslav Ryhel 		.pm = &chagall_battery_pm_ops,
283*fbc1d056SSvyatoslav Ryhel 		.of_match_table = chagall_of_match,
284*fbc1d056SSvyatoslav Ryhel 	},
285*fbc1d056SSvyatoslav Ryhel 	.probe = chagall_battery_probe,
286*fbc1d056SSvyatoslav Ryhel };
287*fbc1d056SSvyatoslav Ryhel module_i2c_driver(chagall_battery_driver);
288*fbc1d056SSvyatoslav Ryhel 
289*fbc1d056SSvyatoslav Ryhel MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>");
290*fbc1d056SSvyatoslav Ryhel MODULE_DESCRIPTION("Pegatron Chagall fuel gauge driver");
291*fbc1d056SSvyatoslav Ryhel MODULE_LICENSE("GPL");
292