drivers/power/supply/twl4030_charger.c

Source file repositories/reference/linux-study-clean/drivers/power/supply/twl4030_charger.c

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/twl4030_charger.c
Extension
.c
Size
29710 bytes
Lines
1147
Domain
Driver Families
Bucket
drivers/power
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct twl4030_bci {
	struct device		*dev;
	struct power_supply	*ac;
	struct power_supply	*usb;
	struct usb_phy		*transceiver;
	struct notifier_block	usb_nb;
	struct work_struct	work;
	int			irq_chg;
	int			irq_bci;
	int			usb_enabled;

	/*
	 * ichg_* and *_cur values in uA. If any are 'large', we set
	 * CGAIN to '1' which doubles the range for half the
	 * precision.
	 */
	unsigned int		ichg_eoc, ichg_lo, ichg_hi;
	unsigned int		usb_cur, ac_cur;
	struct iio_channel	*channel_vac;
	bool			ac_is_active;
	int			usb_mode, ac_mode; /* charging mode requested */
#define	CHARGE_OFF	0
#define	CHARGE_AUTO	1
#define	CHARGE_LINEAR	2

	/* When setting the USB current we slowly increase the
	 * requested current until target is reached or the voltage
	 * drops below 4.75V.  In the latter case we step back one
	 * step.
	 */
	unsigned int		usb_cur_target;
	struct delayed_work	current_worker;
#define	USB_CUR_STEP	20000	/* 20mA at a time */
#define	USB_MIN_VOLT	4750000	/* 4.75V */
#define	USB_CUR_DELAY	msecs_to_jiffies(100)
#define	USB_MAX_CURRENT	1700000 /* TWL4030 caps at 1.7A */

	unsigned long		event;
};

/* strings for 'usb_mode' values */
static const char *modes[] = { "off", "auto", "continuous" };

/*
 * clear and set bits on an given register on a given module
 */
static int twl4030_clear_set(u8 mod_no, u8 clear, u8 set, u8 reg)
{
	u8 val = 0;
	int ret;

	ret = twl_i2c_read_u8(mod_no, &val, reg);
	if (ret)
		return ret;

	val &= ~clear;
	val |= set;

	return twl_i2c_write_u8(mod_no, val, reg);
}

static int twl4030_bci_read(u8 reg, u8 *val)
{
	return twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, val, reg);
}

static int twl4030_clear_set_boot_bci(u8 clear, u8 set)
{
	return twl4030_clear_set(TWL_MODULE_PM_MASTER, clear,
			TWL4030_CONFIG_DONE | TWL4030_BCIAUTOWEN | set,
			TWL4030_PM_MASTER_BOOT_BCI);
}

static int twl4030bci_read_adc_val(u8 reg)
{
	int ret, temp;
	u8 val;

	/* read MSB */
	ret = twl4030_bci_read(reg + 1, &val);
	if (ret)
		return ret;

	temp = (int)(val & 0x03) << 8;

	/* read LSB */
	ret = twl4030_bci_read(reg, &val);
	if (ret)
		return ret;

Annotation

Implementation Notes