File Index
Files and directories
Sign in
FILE

max77705_charger.c

File preview with syntax highlighting.

linux-6.19.14/drivers/power/supply/max77705_charger.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Based on max77650-charger.c
  4 *
  5 * Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.org>
  6 *
  7 * Battery charger driver for MAXIM 77705 charger/power-supply.
  8 */
  9
 10#include <linux/devm-helpers.h>
 11#include <linux/i2c.h>
 12#include <linux/interrupt.h>
 13#include <linux/mfd/max77693-common.h>
 14#include <linux/mfd/max77705-private.h>
 15#include <linux/power/max77705_charger.h>
 16#include <linux/module.h>
 17#include <linux/platform_device.h>
 18#include <linux/power_supply.h>
 19#include <linux/regmap.h>
 20
 21static const char *max77705_charger_model		= "max77705";
 22static const char *max77705_charger_manufacturer	= "Maxim Integrated";
 23
 24static const struct regmap_config max77705_chg_regmap_config = {
 25	.reg_base = MAX77705_CHG_REG_BASE,
 26	.reg_bits = 8,
 27	.val_bits = 8,
 28	.max_register = MAX77705_CHG_REG_SAFEOUT_CTRL,
 29};
 30
 31static enum power_supply_property max77705_charger_props[] = {
 32	POWER_SUPPLY_PROP_ONLINE,
 33	POWER_SUPPLY_PROP_PRESENT,
 34	POWER_SUPPLY_PROP_STATUS,
 35	POWER_SUPPLY_PROP_CHARGE_TYPE,
 36	POWER_SUPPLY_PROP_HEALTH,
 37	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
 38	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
 39	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
 40	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
 41};
 42
 43static irqreturn_t max77705_aicl_irq(int irq, void *irq_drv_data)
 44{
 45	struct max77705_charger_data *chg = irq_drv_data;
 46	unsigned int regval, irq_status;
 47	int err;
 48
 49	err = regmap_read(chg->regmap, MAX77705_CHG_REG_INT_OK, &irq_status);
 50	if (err < 0)
 51		return IRQ_HANDLED;
 52
 53	// irq is fiered at the end of current decrease sequence too
 54	// early check AICL_I bit to guard against that excess irq call
 55	while (!(irq_status & BIT(MAX77705_AICL_I))) {
 56		err = regmap_field_read(chg->rfield[MAX77705_CHG_CHGIN_LIM], &regval);
 57		if (err < 0)
 58			return IRQ_HANDLED;
 59
 60		regval--;
 61
 62		err = regmap_field_write(chg->rfield[MAX77705_CHG_CHGIN_LIM], regval);
 63		if (err < 0)
 64			return IRQ_HANDLED;
 65
 66		msleep(AICL_WORK_DELAY_MS);
 67
 68		err = regmap_read(chg->regmap, MAX77705_CHG_REG_INT_OK, &irq_status);
 69		if (err < 0)
 70			return IRQ_HANDLED;
 71	}
 72
 73	return IRQ_HANDLED;
 74}
 75
 76static irqreturn_t max77705_chgin_irq(int irq, void *irq_drv_data)
 77{
 78	struct max77705_charger_data *chg = irq_drv_data;
 79
 80	queue_work(chg->wqueue, &chg->chgin_work);
 81
 82	return IRQ_HANDLED;
 83}
 84
 85static const struct regmap_irq max77705_charger_irqs[] = {
 86	REGMAP_IRQ_REG_LINE(MAX77705_BYP_I, BITS_PER_BYTE),
 87	REGMAP_IRQ_REG_LINE(MAX77705_INP_LIMIT_I, BITS_PER_BYTE),
 88	REGMAP_IRQ_REG_LINE(MAX77705_BATP_I, BITS_PER_BYTE),
 89	REGMAP_IRQ_REG_LINE(MAX77705_BAT_I, BITS_PER_BYTE),
 90	REGMAP_IRQ_REG_LINE(MAX77705_CHG_I, BITS_PER_BYTE),
 91	REGMAP_IRQ_REG_LINE(MAX77705_WCIN_I, BITS_PER_BYTE),
 92	REGMAP_IRQ_REG_LINE(MAX77705_CHGIN_I, BITS_PER_BYTE),
 93	REGMAP_IRQ_REG_LINE(MAX77705_AICL_I, BITS_PER_BYTE),
 94};
 95
 96static const struct regmap_irq_chip max77705_charger_irq_chip = {
 97	.name			= "max77705-charger",
 98	.status_base		= MAX77705_CHG_REG_INT,
 99	.mask_base		= MAX77705_CHG_REG_INT_MASK,
100	.num_regs		= 1,
101	.irqs			= max77705_charger_irqs,
102	.num_irqs		= ARRAY_SIZE(max77705_charger_irqs),
103};
104
105static int max77705_charger_enable(struct max77705_charger_data *chg)
106{
107	int rv;
108
109	rv = regmap_field_write(chg->rfield[MAX77705_CHG_EN], 1);
110	if (rv)
111		dev_err(chg->dev, "unable to enable the charger: %d\n", rv);
112
113	return rv;
114}
115
116static void max77705_charger_disable(void *data)
117{
118	struct max77705_charger_data *chg = data;
119	int rv;
120
121	rv = regmap_field_write(chg->rfield[MAX77705_CHG_EN], MAX77705_CHG_DISABLE);
122	if (rv)
123		dev_err(chg->dev, "unable to disable the charger: %d\n", rv);
124}
125
126static int max77705_get_online(struct regmap *regmap, int *val)
127{
128	unsigned int data;
129	int ret;
130
131	ret = regmap_read(regmap, MAX77705_CHG_REG_INT_OK, &data);
132	if (ret < 0)
133		return ret;
134
135	*val = !!(data & MAX77705_CHGIN_OK);
136
137	return 0;
138}
139
140static int max77705_set_integer(struct max77705_charger_data *chg, enum max77705_field_idx fidx,
141				unsigned int clamp_min, unsigned int clamp_max,
142				unsigned int div, int val)
143{
144	unsigned int regval;
145
146	regval = clamp_val(val, clamp_min, clamp_max) / div;
147
148	return regmap_field_write(chg->rfield[fidx], regval);
149}
150
151static int max77705_check_battery(struct max77705_charger_data *chg, int *val)
152{
153	unsigned int reg_data;
154	unsigned int reg_data2;
155	struct regmap *regmap = chg->regmap;
156
157	regmap_read(regmap, MAX77705_CHG_REG_INT_OK, &reg_data);
158
159	dev_dbg(chg->dev, "CHG_INT_OK(0x%x)\n", reg_data);
160
161	regmap_read(regmap, MAX77705_CHG_REG_DETAILS_00, &reg_data2);
162
163	dev_dbg(chg->dev, "CHG_DETAILS00(0x%x)\n", reg_data2);
164
165	if ((reg_data & MAX77705_BATP_OK) || !(reg_data2 & MAX77705_BATP_DTLS))
166		*val = true;
167	else
168		*val = false;
169
170	return 0;
171}
172
173static int max77705_get_charge_type(struct max77705_charger_data *chg, int *val)
174{
175	struct regmap *regmap = chg->regmap;
176	unsigned int reg_data, chg_en;
177
178	regmap_field_read(chg->rfield[MAX77705_CHG_EN], &chg_en);
179	if (!chg_en) {
180		*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
181		return 0;
182	}
183
184	regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, &reg_data);
185	reg_data &= MAX77705_CHG_DTLS;
186
187	switch (reg_data) {
188	case 0x0:
189	case MAX77705_CHARGER_CONSTANT_CURRENT:
190	case MAX77705_CHARGER_CONSTANT_VOLTAGE:
191		*val = POWER_SUPPLY_CHARGE_TYPE_FAST;
192		return 0;
193	default:
194		*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
195		return 0;
196	}
197
198	return 0;
199}
200
201static int max77705_get_status(struct max77705_charger_data *chg, int *val)
202{
203	struct regmap *regmap = chg->regmap;
204	unsigned int reg_data, chg_en;
205
206	regmap_field_read(chg->rfield[MAX77705_CHG_EN], &chg_en);
207	if (!chg_en) {
208		*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
209		return 0;
210	}
211
212	regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, &reg_data);
213	reg_data &= MAX77705_CHG_DTLS;
214
215	switch (reg_data) {
216	case 0x0:
217	case MAX77705_CHARGER_CONSTANT_CURRENT:
218	case MAX77705_CHARGER_CONSTANT_VOLTAGE:
219		*val = POWER_SUPPLY_STATUS_CHARGING;
220		return 0;
221	case MAX77705_CHARGER_END_OF_CHARGE:
222	case MAX77705_CHARGER_DONE:
223		*val = POWER_SUPPLY_STATUS_FULL;
224		return 0;
225	/* those values hard coded as in vendor kernel, because of */
226	/* failure to determine it's actual meaning. */
227	case 0x05:
228	case 0x06:
229	case 0x07:
230		*val = POWER_SUPPLY_STATUS_NOT_CHARGING;
231		return 0;
232	case 0x08:
233	case 0xA:
234	case 0xB:
235		*val = POWER_SUPPLY_STATUS_DISCHARGING;
236		return 0;
237	default:
238		*val = POWER_SUPPLY_STATUS_UNKNOWN;
239		return 0;
240	}
241
242	return 0;
243}
244
245static int max77705_get_vbus_state(struct regmap *regmap, int *value)
246{
247	int ret;
248	unsigned int charge_dtls;
249
250	ret = regmap_read(regmap, MAX77705_CHG_REG_DETAILS_00, &charge_dtls);
251	if (ret)
252		return ret;
253
254	charge_dtls = ((charge_dtls & MAX77705_CHGIN_DTLS) >>
255			MAX77705_CHGIN_DTLS_SHIFT);
256
257	switch (charge_dtls) {
258	case 0x00:
259		*value = POWER_SUPPLY_HEALTH_UNDERVOLTAGE;
260		break;
261	case 0x01:
262		*value = POWER_SUPPLY_HEALTH_UNDERVOLTAGE;
263		break;
264	case 0x02:
265		*value = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
266		break;
267	case 0x03:
268		*value = POWER_SUPPLY_HEALTH_GOOD;
269		break;
270	default:
271		return 0;
272	}
273	return 0;
274}
275
276static int max77705_get_battery_health(struct max77705_charger_data *chg,
277					int *value)
278{
279	struct regmap *regmap = chg->regmap;
280	unsigned int bat_dtls;
281
282	regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, &bat_dtls);
283	bat_dtls = ((bat_dtls & MAX77705_BAT_DTLS) >> MAX77705_BAT_DTLS_SHIFT);
284
285	switch (bat_dtls) {
286	case MAX77705_BATTERY_NOBAT:
287		dev_dbg(chg->dev, "%s: No battery and the chg is suspended\n",
288			__func__);
289		*value = POWER_SUPPLY_HEALTH_NO_BATTERY;
290		break;
291	case MAX77705_BATTERY_PREQUALIFICATION:
292		dev_dbg(chg->dev, "%s: battery is okay but its voltage is low(~VPQLB)\n",
293			__func__);
294		break;
295	case MAX77705_BATTERY_DEAD:
296		dev_dbg(chg->dev, "%s: battery dead\n", __func__);
297		*value = POWER_SUPPLY_HEALTH_DEAD;
298		break;
299	case MAX77705_BATTERY_GOOD:
300	case MAX77705_BATTERY_LOWVOLTAGE:
301		*value = POWER_SUPPLY_HEALTH_GOOD;
302		break;
303	case MAX77705_BATTERY_OVERVOLTAGE:
304		dev_dbg(chg->dev, "%s: battery ovp\n", __func__);
305		*value = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
306		break;
307	default:
308		dev_dbg(chg->dev, "%s: battery unknown\n", __func__);
309		*value = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
310		break;
311	}
312
313	return 0;
314}
315
316static int max77705_get_health(struct max77705_charger_data *chg, int *val)
317{
318	struct regmap *regmap = chg->regmap;
319	int ret, is_online = 0;
320
321	ret = max77705_get_online(regmap, &is_online);
322	if (ret)
323		return ret;
324	if (is_online) {
325		ret = max77705_get_vbus_state(regmap, val);
326		if (ret || (*val != POWER_SUPPLY_HEALTH_GOOD))
327			return ret;
328	}
329	return max77705_get_battery_health(chg, val);
330}
331
332static int max77705_get_input_current(struct max77705_charger_data *chg,
333					int *val)
334{
335	unsigned int reg_data;
336	int get_current = 0;
337
338	regmap_field_read(chg->rfield[MAX77705_CHG_CHGIN_LIM], &reg_data);
339
340	if (reg_data <= 3)
341		get_current = MAX77705_CURRENT_CHGIN_MIN;
342	else
343		get_current = (reg_data + 1) * MAX77705_CURRENT_CHGIN_STEP;
344
345	*val = get_current;
346
347	return 0;
348}
349
350static int max77705_get_charge_current(struct max77705_charger_data *chg,
351					int *val)
352{
353	unsigned int reg_data;
354
355	regmap_field_read(chg->rfield[MAX77705_CHG_CC_LIM], &reg_data);
356
357	*val = reg_data <= 0x2 ? MAX77705_CURRENT_CHGIN_MIN : reg_data * MAX77705_CURRENT_CHG_STEP;
358
359	return 0;
360}
361
362static int max77705_set_float_voltage(struct max77705_charger_data *chg,
363					int float_voltage)
364{
365	int float_voltage_mv;
366	unsigned int reg_data = 0;
367
368	float_voltage_mv = float_voltage / 1000;
369	reg_data = float_voltage_mv <= 4000 ? 0x0 :
370		float_voltage_mv >= 4500 ? 0x23 :
371		(float_voltage_mv <= 4200) ? (float_voltage_mv - 4000) / 50 :
372		(((float_voltage_mv - 4200) / 10) + 0x04);
373
374	return regmap_field_write(chg->rfield[MAX77705_CHG_CV_PRM], reg_data);
375}
376
377static int max77705_get_float_voltage(struct max77705_charger_data *chg,
378					int *val)
379{
380	unsigned int reg_data = 0;
381	int voltage_mv;
382
383	regmap_field_read(chg->rfield[MAX77705_CHG_CV_PRM], &reg_data);
384	voltage_mv = reg_data <= 0x04 ? reg_data * 50 + 4000 :
385					(reg_data - 4) * 10 + 4200;
386	*val = voltage_mv * 1000;
387
388	return 0;
389}
390
391static int max77705_chg_get_property(struct power_supply *psy,
392					enum power_supply_property psp,
393					union power_supply_propval *val)
394{
395	struct max77705_charger_data *chg = power_supply_get_drvdata(psy);
396	struct regmap *regmap = chg->regmap;
397
398	switch (psp) {
399	case POWER_SUPPLY_PROP_ONLINE:
400		return max77705_get_online(regmap, &val->intval);
401	case POWER_SUPPLY_PROP_PRESENT:
402		return max77705_check_battery(chg, &val->intval);
403	case POWER_SUPPLY_PROP_STATUS:
404		return max77705_get_status(chg, &val->intval);
405	case POWER_SUPPLY_PROP_CHARGE_TYPE:
406		return max77705_get_charge_type(chg, &val->intval);
407	case POWER_SUPPLY_PROP_HEALTH:
408		return max77705_get_health(chg, &val->intval);
409	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
410		return max77705_get_input_current(chg, &val->intval);
411	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
412		return max77705_get_charge_current(chg, &val->intval);
413	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
414		return max77705_get_float_voltage(chg, &val->intval);
415	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
416		val->intval = chg->bat_info->voltage_max_design_uv;
417		break;
418	case POWER_SUPPLY_PROP_MODEL_NAME:
419		val->strval = max77705_charger_model;
420		break;
421	case POWER_SUPPLY_PROP_MANUFACTURER:
422		val->strval = max77705_charger_manufacturer;
423		break;
424	default:
425		return -EINVAL;
426	}
427	return 0;
428}
429
430static int max77705_set_property(struct power_supply *psy,
431				 enum power_supply_property psp,
432				 const union power_supply_propval *val)
433{
434	struct max77705_charger_data *chg = power_supply_get_drvdata(psy);
435	int err = 0;
436
437	switch (psp) {
438	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
439		err = max77705_set_integer(chg, MAX77705_CHG_CC_LIM,
440					   MAX77705_CURRENT_CHGIN_MIN,
441					   MAX77705_CURRENT_CHGIN_MAX,
442					   MAX77705_CURRENT_CHG_STEP,
443					   val->intval);
444		break;
445	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
446		err = max77705_set_integer(chg, MAX77705_CHG_CHGIN_LIM,
447					   MAX77705_CURRENT_CHGIN_MIN,
448					   MAX77705_CURRENT_CHGIN_MAX,
449					   MAX77705_CURRENT_CHGIN_STEP,
450					   val->intval);
451		break;
452	default:
453		err = -EINVAL;
454	}
455
456	return err;
457};
458
459static int max77705_property_is_writeable(struct power_supply *psy,
460					  enum power_supply_property psp)
461{
462	switch (psp) {
463	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
464	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
465		return true;
466	default:
467		return false;
468	}
469}
470
471static const struct power_supply_desc max77705_charger_psy_desc = {
472	.name = "max77705-charger",
473	.type = POWER_SUPPLY_TYPE_USB,
474	.properties = max77705_charger_props,
475	.property_is_writeable = max77705_property_is_writeable,
476	.num_properties = ARRAY_SIZE(max77705_charger_props),
477	.get_property = max77705_chg_get_property,
478	.set_property = max77705_set_property,
479};
480
481static void max77705_chgin_isr_work(struct work_struct *work)
482{
483	struct max77705_charger_data *chg =
484		container_of(work, struct max77705_charger_data, chgin_work);
485
486	power_supply_changed(chg->psy_chg);
487}
488
489static int max77705_charger_initialize(struct max77705_charger_data *chg)
490{
491	struct power_supply_battery_info *info;
492	struct regmap *regmap = chg->regmap;
493	int err;
494
495	err = power_supply_get_battery_info(chg->psy_chg, &info);
496	if (err)
497		return dev_err_probe(chg->dev, err, "error on getting battery info");
498
499	chg->bat_info = info;
500
501	/* unlock charger setting protect */
502	/* slowest LX slope */
503	err = regmap_field_write(chg->rfield[MAX77705_CHGPROT], MAX77705_CHGPROT_UNLOCKED);
504	if (err)
505		goto err;
506
507	err = regmap_field_write(chg->rfield[MAX77705_LX_SLOPE], MAX77705_SLOWEST_LX_SLOPE);
508	if (err)
509		goto err;
510
511	/* fast charge timer disable */
512	/* restart threshold disable */
513	/* pre-qual charge disable */
514	err = regmap_field_write(chg->rfield[MAX77705_FCHGTIME], MAX77705_FCHGTIME_DISABLE);
515	if (err)
516		goto err;
517
518	err = regmap_field_write(chg->rfield[MAX77705_CHG_RSTRT], MAX77705_CHG_RSTRT_DISABLE);
519	if (err)
520		goto err;
521
522	err = regmap_field_write(chg->rfield[MAX77705_CHG_PQEN], MAX77705_CHG_PQEN_DISABLE);
523	if (err)
524		goto err;
525
526	err = regmap_field_write(chg->rfield[MAX77705_MODE],
527			MAX77705_CHG_MASK | MAX77705_BUCK_MASK);
528	if (err)
529		goto err;
530
531	/* charge current 450mA(default) */
532	/* otg current limit 900mA */
533	err = regmap_field_write(chg->rfield[MAX77705_OTG_ILIM], MAX77705_OTG_ILIM_900);
534	if (err)
535		goto err;
536
537	/* BAT to SYS OCP 4.80A */
538	err = regmap_field_write(chg->rfield[MAX77705_REG_B2SOVRC], MAX77705_B2SOVRC_4_8A);
539	if (err)
540		goto err;
541
542	/* top off current 150mA */
543	/* top off timer 30min */
544	err = regmap_field_write(chg->rfield[MAX77705_TO], MAX77705_TO_ITH_150MA);
545	if (err)
546		goto err;
547
548	err = regmap_field_write(chg->rfield[MAX77705_TO_TIME], MAX77705_TO_TIME_30M);
549	if (err)
550		goto err;
551
552	err = regmap_field_write(chg->rfield[MAX77705_SYS_TRACK], MAX77705_SYS_TRACK_DISABLE);
553	if (err)
554		goto err;
555
556	/* cv voltage 4.2V or 4.35V */
557	/* MINVSYS 3.6V(default) */
558	if (info->voltage_max_design_uv < 0) {
559		dev_warn(chg->dev, "missing battery:voltage-max-design-microvolt\n");
560		max77705_set_float_voltage(chg, 4200000);
561	} else {
562		max77705_set_float_voltage(chg, info->voltage_max_design_uv);
563	}
564
565	err = regmap_field_write(chg->rfield[MAX77705_VCHGIN], MAX77705_VCHGIN_4_5);
566	if (err)
567		goto err;
568
569	err = regmap_field_write(chg->rfield[MAX77705_WCIN], MAX77705_WCIN_4_5);
570	if (err)
571		goto err;
572
573	/* Watchdog timer */
574	regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_00,
575				MAX77705_WDTEN_MASK, 0);
576
577	/* VBYPSET=5.0V */
578	err = regmap_field_write(chg->rfield[MAX77705_VBYPSET], 0);
579	if (err)
580		goto err;
581
582	/* Switching Frequency : 1.5MHz */
583	err = regmap_field_write(chg->rfield[MAX77705_REG_FSW], MAX77705_CHG_FSW_1_5MHz);
584	if (err)
585		goto err;
586
587	/* Auto skip mode */
588	err = regmap_field_write(chg->rfield[MAX77705_REG_DISKIP], MAX77705_AUTO_SKIP);
589	if (err)
590		goto err;
591
592	return 0;
593
594err:
595	return dev_err_probe(chg->dev, err, "error while configuring");
596
597}
598
599static int max77705_charger_probe(struct i2c_client *i2c)
600{
601	struct power_supply_config pscfg = {};
602	struct max77705_charger_data *chg;
603	struct regmap_irq_chip *chip_desc;
604	struct device *dev;
605	struct regmap_irq_chip_data *irq_data;
606	int ret;
607
608	dev = &i2c->dev;
609
610	chg = devm_kzalloc(dev, sizeof(*chg), GFP_KERNEL);
611	if (!chg)
612		return -ENOMEM;
613
614	chg->dev = dev;
615	i2c_set_clientdata(i2c, chg);
616
617	chip_desc = devm_kmemdup(dev, &max77705_charger_irq_chip,
618				 sizeof(max77705_charger_irq_chip),
619				 GFP_KERNEL);
620	if (!chip_desc)
621		return -ENOMEM;
622	chip_desc->irq_drv_data = chg;
623
624	chg->regmap = devm_regmap_init_i2c(i2c, &max77705_chg_regmap_config);
625	if (IS_ERR(chg->regmap))
626		return PTR_ERR(chg->regmap);
627
628	for (int i = 0; i < MAX77705_N_REGMAP_FIELDS; i++) {
629		chg->rfield[i] = devm_regmap_field_alloc(dev, chg->regmap,
630							 max77705_reg_field[i]);
631		if (IS_ERR(chg->rfield[i]))
632			return dev_err_probe(dev, PTR_ERR(chg->rfield[i]),
633					     "cannot allocate regmap field\n");
634	}
635
636	pscfg.fwnode = dev_fwnode(dev);
637	pscfg.drv_data = chg;
638
639	chg->psy_chg = devm_power_supply_register(dev, &max77705_charger_psy_desc, &pscfg);
640	if (IS_ERR(chg->psy_chg))
641		return PTR_ERR(chg->psy_chg);
642
643	ret = devm_regmap_add_irq_chip(chg->dev, chg->regmap, i2c->irq,
644					IRQF_ONESHOT, 0,
645					chip_desc, &irq_data);
646	if (ret)
647		return dev_err_probe(dev, ret, "failed to add irq chip\n");
648
649	chg->wqueue = create_singlethread_workqueue(dev_name(dev));
650	if (!chg->wqueue)
651		return -ENOMEM;
652
653	ret = devm_work_autocancel(dev, &chg->chgin_work, max77705_chgin_isr_work);
654	if (ret) {
655		dev_err_probe(dev, ret, "failed to initialize interrupt work\n");
656		goto destroy_wq;
657	}
658
659	ret = max77705_charger_initialize(chg);
660	if (ret) {
661		dev_err_probe(dev, ret, "failed to initialize charger IC\n");
662		goto destroy_wq;
663	}
664
665	ret = devm_request_threaded_irq(dev, regmap_irq_get_virq(irq_data, MAX77705_CHGIN_I),
666					NULL, max77705_chgin_irq,
667					IRQF_TRIGGER_NONE,
668					"chgin-irq", chg);
669	if (ret) {
670		dev_err_probe(dev, ret, "Failed to Request chgin IRQ\n");
671		goto destroy_wq;
672	}
673
674	ret = devm_request_threaded_irq(dev, regmap_irq_get_virq(irq_data, MAX77705_AICL_I),
675					NULL, max77705_aicl_irq,
676					IRQF_TRIGGER_NONE,
677					"aicl-irq", chg);
678	if (ret) {
679		dev_err_probe(dev, ret, "Failed to Request aicl IRQ\n");
680		goto destroy_wq;
681	}
682
683	ret = max77705_charger_enable(chg);
684	if (ret) {
685		dev_err_probe(dev, ret, "failed to enable charge\n");
686		goto destroy_wq;
687	}
688
689	return devm_add_action_or_reset(dev, max77705_charger_disable, chg);
690
691destroy_wq:
692	destroy_workqueue(chg->wqueue);
693	return ret;
694}
695
696static const struct of_device_id max77705_charger_of_match[] = {
697	{ .compatible = "maxim,max77705-charger" },
698	{ }
699};
700MODULE_DEVICE_TABLE(of, max77705_charger_of_match);
701
702static struct i2c_driver max77705_charger_driver = {
703	.driver = {
704		.name = "max77705-charger",
705		.of_match_table = max77705_charger_of_match,
706	},
707	.probe = max77705_charger_probe,
708};
709module_i2c_driver(max77705_charger_driver);
710
711MODULE_AUTHOR("Dzmitry Sankouski <dsankouski@gmail.com>");
712MODULE_DESCRIPTION("Maxim MAX77705 charger driver");
713MODULE_LICENSE("GPL");
~/ Read-only file preview.