drivers/power/supply/s2m-charger.c

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

File Facts

System
Linux kernel
Corpus path
drivers/power/supply/s2m-charger.c
Extension
.c
Size
8630 bytes
Lines
314
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 s2m_chgr {
	struct device *dev;
	struct regmap *regmap;
	struct power_supply *psy;
	struct extcon_dev *extcon;
	struct work_struct extcon_work;
	struct notifier_block extcon_nb;
};

static int s2mu005_chgr_get_online(struct s2m_chgr *priv, int *value)
{
	u32 val;
	int ret;

	ret = regmap_read(priv->regmap, S2MU005_REG_CHGR_STATUS0, &val);
	if (ret) {
		dev_err(priv->dev, "failed to read register (%d)\n", ret);
		return ret;
	}

	*value = !!(val & S2MU005_CHGR_CHG);

	return 0;
}

static void s2mu005_chgr_get_usb_type(struct s2m_chgr *priv, int *value)
{
	if (extcon_get_state(priv->extcon, EXTCON_CHG_USB_CDP) > 0)
		*value = POWER_SUPPLY_USB_TYPE_CDP;
	else if (extcon_get_state(priv->extcon, EXTCON_CHG_USB_SDP) > 0)
		*value = POWER_SUPPLY_USB_TYPE_SDP;
	else if (extcon_get_state(priv->extcon, EXTCON_CHG_USB_DCP) > 0)
		*value = POWER_SUPPLY_USB_TYPE_DCP;
	else
		*value = POWER_SUPPLY_USB_TYPE_UNKNOWN;
}

static int s2mu005_chgr_get_property(struct power_supply *psy,
				     enum power_supply_property psp,
				     union power_supply_propval *val)
{
	struct s2m_chgr *priv = power_supply_get_drvdata(psy);
	int ret;

	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		ret = s2mu005_chgr_get_online(priv, &val->intval);
		if (ret)
			return ret;
		break;
	case POWER_SUPPLY_PROP_USB_TYPE:
		s2mu005_chgr_get_usb_type(priv, &val->intval);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int s2mu005_chgr_mode_set_host(struct s2m_chgr *priv)
{
	int ret;

	/* set mode to OTG */
	ret = regmap_update_bits(priv->regmap, S2MU005_REG_CHGR_CTRL0,
				 S2MU005_CHGR_OP_MODE,
				 FIELD_PREP(S2MU005_CHGR_OP_MODE,
					    S2MU005_CHGR_OP_MODE_OTG));
	if (ret) {
		dev_err(priv->dev, "failed to set OTG mode (%d)\n", ret);
		return ret;
	}

	/* set boost frequency to 2MHz */
	ret = regmap_update_bits(priv->regmap, S2MU005_REG_CHGR_CTRL11,
				 S2MU005_CHGR_OSC_BOOST,
				 FIELD_PREP(S2MU005_CHGR_OSC_BOOST,
					    S2MU005_CHGR_OSC_BOOST_2MHZ));
	if (ret) {
		dev_err(priv->dev, "failed to set boost frequency (%d)\n", ret);
		return ret;
	}

	/* set OTG current limit to 1.5 A */
	ret = regmap_update_bits(priv->regmap, S2MU005_REG_CHGR_CTRL4,
				 S2MU005_CHGR_OTG_OCP,
				 FIELD_PREP(S2MU005_CHGR_OTG_OCP,
					    S2MU005_CHGR_OTG_OCP_1P5A));
	if (ret) {

Annotation

Implementation Notes