Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0164a226 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mfd: qcom-i2c-pmic: Toggle STAT pin at init"

parents 46499873 ea80f0a2
Loading
Loading
Loading
Loading
+74 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2017, 2020, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt) "I2C PMIC: %s: " fmt, __func__
@@ -61,6 +61,7 @@ struct i2c_pmic {
	int			summary_irq;
	bool			resume_completed;
	bool			irq_waiting;
	bool			toggle_stat;
};

static void i2c_pmic_irq_bus_lock(struct irq_data *d)
@@ -473,6 +474,9 @@ static int i2c_pmic_parse_dt(struct i2c_pmic *chip)

	of_property_read_string(node, "pinctrl-names", &chip->pinctrl_name);

	chip->toggle_stat = of_property_read_bool(node,
				"qcom,enable-toggle-stat");

	return rc;
}

@@ -513,6 +517,69 @@ static int i2c_pmic_determine_initial_status(struct i2c_pmic *chip)
	return 0;
}

#define INT_TEST_OFFSET			0xE0
#define INT_TEST_MODE_EN_BIT		BIT(7)
#define INT_TEST_VAL_OFFSET		0xE1
#define INT_0_BIT			BIT(0)
static int i2c_pmic_toggle_stat(struct i2c_pmic *chip)
{
	int rc = 0, i;

	if (!chip->toggle_stat || !chip->num_periphs)
		return 0;

	rc = regmap_write(chip->regmap,
				chip->periph[0].addr | INT_EN_SET_OFFSET,
				INT_0_BIT);
	if (rc < 0) {
		pr_err("Couldn't write to int_en_set rc=%d\n", rc);
		return rc;
	}

	rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_OFFSET,
				INT_TEST_MODE_EN_BIT);
	if (rc < 0) {
		pr_err("Couldn't write to int_test rc=%d\n", rc);
		return rc;
	}

	for (i = 0; i < 5; i++) {
		rc = regmap_write(chip->regmap,
				chip->periph[0].addr | INT_TEST_VAL_OFFSET,
				INT_0_BIT);
		if (rc < 0) {
			pr_err("Couldn't write to int_test_val rc=%d\n", rc);
			goto exit;
		}

		usleep_range(10000, 11000);

		rc = regmap_write(chip->regmap,
				chip->periph[0].addr | INT_TEST_VAL_OFFSET,
				0);
		if (rc < 0) {
			pr_err("Couldn't write to int_test_val rc=%d\n", rc);
			goto exit;
		}

		rc = regmap_write(chip->regmap,
				chip->periph[0].addr | INT_LATCHED_CLR_OFFSET,
				INT_0_BIT);
		if (rc < 0) {
			pr_err("Couldn't write to int_latched_clr rc=%d\n", rc);
			goto exit;
		}

		usleep_range(10000, 11000);
	}
exit:
	regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_OFFSET, 0);
	regmap_write(chip->regmap, chip->periph[0].addr | INT_EN_CLR_OFFSET,
							INT_0_BIT);

	return rc;
}

static struct regmap_config i2c_pmic_regmap_config = {
	.reg_bits	= 16,
	.val_bits	= 8,
@@ -571,6 +638,12 @@ static int i2c_pmic_probe(struct i2c_client *client,
	chip->resume_completed = true;
	mutex_init(&chip->irq_complete);

	rc = i2c_pmic_toggle_stat(chip);
	if (rc < 0) {
		pr_err("Couldn't toggle stat rc=%d\n", rc);
		goto cleanup;
	}

	rc = devm_request_threaded_irq(&client->dev, client->irq, NULL,
				       i2c_pmic_irq_handler,
				       IRQF_ONESHOT | IRQF_SHARED,
+81 −1
Original line number Diff line number Diff line
@@ -724,6 +724,46 @@ static int smb5_parse_dt_voltages(struct smb5 *chip, struct device_node *node)
	return 0;
}

static int smb5_parse_sdam(struct smb5 *chip, struct device_node *node)
{
	struct device_node *child;
	struct smb_charger *chg = &chip->chg;
	struct property *prop;
	const char *name;
	int rc;
	u32 base;
	u8 type;

	for_each_available_child_of_node(node, child) {
		of_property_for_each_string(child, "reg", prop, name) {
			rc = of_property_read_u32(child, "reg", &base);
			if (rc < 0) {
				pr_err("Failed to read base rc=%d\n", rc);
				return rc;
			}

			rc = smblib_read(chg, base + PERPH_TYPE_OFFSET, &type);
			if (rc < 0) {
				pr_err("Failed to read type rc=%d\n", rc);
				return rc;
			}

			switch (type) {
			case SDAM_TYPE:
				chg->sdam_base = base;
				break;
			default:
				break;
			}
		}
	}

	if (!chg->sdam_base)
		pr_debug("SDAM node not defined\n");

	return 0;
}

static int smb5_parse_dt(struct smb5 *chip)
{
	struct smb_charger *chg = &chip->chg;
@@ -751,6 +791,10 @@ static int smb5_parse_dt(struct smb5 *chip)
	if (rc < 0)
		return rc;

	rc = smb5_parse_sdam(chip, node);
	if (rc < 0)
		return rc;

	return 0;
}

@@ -822,6 +866,8 @@ static enum power_supply_property smb5_usb_props[] = {
	POWER_SUPPLY_PROP_SKIN_HEALTH,
	POWER_SUPPLY_PROP_APSD_RERUN,
	POWER_SUPPLY_PROP_APSD_TIMEOUT,
	POWER_SUPPLY_PROP_CHARGER_STATUS,
	POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
};

static int smb5_usb_get_prop(struct power_supply *psy,
@@ -831,6 +877,7 @@ static int smb5_usb_get_prop(struct power_supply *psy,
	struct smb5 *chip = power_supply_get_drvdata(psy);
	struct smb_charger *chg = &chip->chg;
	int rc = 0;
	u8 reg = 0, buff[2] = {0};
	val->intval = 0;

	switch (psp) {
@@ -971,6 +1018,24 @@ static int smb5_usb_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_APSD_TIMEOUT:
		val->intval = chg->apsd_ext_timeout;
		break;
	case POWER_SUPPLY_PROP_CHARGER_STATUS:
		val->intval = 0;
		if (chg->sdam_base) {
			rc = smblib_read(chg,
				chg->sdam_base + SDAM_QC_DET_STATUS_REG, &reg);
			if (!rc)
				val->intval = reg;
		}
		break;
	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED:
		val->intval = 0;
		if (chg->sdam_base) {
			rc = smblib_batch_read(chg,
				chg->sdam_base + SDAM_QC_ADC_LSB_REG, buff, 2);
			if (!rc)
				val->intval = (buff[1] << 8 | buff[0]) * 1038;
		}
		break;
	default:
		pr_err("get prop %d is not supported in usb\n", psp);
		rc = -EINVAL;
@@ -2568,11 +2633,23 @@ static int smb5_init_hw(struct smb5 *chip)
{
	struct smb_charger *chg = &chip->chg;
	int rc;
	u8 val = 0, mask = 0;
	u8 val = 0, mask = 0, buf[2] = {0};

	if (chip->dt.no_battery)
		chg->fake_capacity = 50;

	if (chg->sdam_base) {
		rc = smblib_write(chg,
			chg->sdam_base + SDAM_QC_DET_STATUS_REG, 0);
		if (rc < 0)
			pr_err("Couldn't clear SDAM QC status rc=%d\n", rc);

		rc = smblib_batch_write(chg,
			chg->sdam_base + SDAM_QC_ADC_LSB_REG, buf, 2);
		if (rc < 0)
			pr_err("Couldn't clear SDAM ADC status rc=%d\n", rc);
	}

	if (chip->dt.batt_profile_fcc_ua < 0)
		smblib_get_charge_param(chg, &chg->param.fcc,
				&chg->batt_profile_fcc_ua);
@@ -3628,6 +3705,9 @@ static void smb5_shutdown(struct platform_device *pdev)
	/* disable all interrupts */
	smb5_disable_interrupts(chg);

	/* disable the SMB_EN configuration */
	smblib_masked_write(chg, MISC_SMB_EN_CMD_REG, EN_CP_CMD_BIT, 0);

	/* configure power role for UFP */
	if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC)
		smblib_masked_write(chg, TYPE_C_MODE_CFG_REG,
+13 −0
Original line number Diff line number Diff line
@@ -5905,6 +5905,7 @@ static void typec_src_removal(struct smb_charger *chg)
	struct smb_irq_data *data;
	struct storm_watch *wdata;
	int sec_charger;
	u8 val[2] = {0};

	sec_charger = chg->sec_pl_present ? POWER_SUPPLY_CHARGER_SEC_PL :
				POWER_SUPPLY_CHARGER_SEC_NONE;
@@ -5995,6 +5996,18 @@ static void typec_src_removal(struct smb_charger *chg)
		smblib_err(chg, "Couldn't write float charger options rc=%d\n",
			rc);

	if (chg->sdam_base) {
		rc = smblib_write(chg,
			chg->sdam_base + SDAM_QC_DET_STATUS_REG, 0);
		if (rc < 0)
			pr_err("Couldn't clear SDAM QC status rc=%d\n", rc);

		rc = smblib_batch_write(chg,
			chg->sdam_base + SDAM_QC_ADC_LSB_REG, val, 2);
		if (rc < 0)
			pr_err("Couldn't clear SDAM ADC status rc=%d\n", rc);
	}

	if (!chg->pr_swap_in_progress) {
		rc = smblib_usb_pd_adapter_allowance_override(chg, FORCE_NULL);
		if (rc < 0)
+1 −0
Original line number Diff line number Diff line
@@ -382,6 +382,7 @@ struct smb_charger {
	struct smb_chg_freq	chg_freq;
	int			otg_delay_ms;
	int			weak_chg_icl_ua;
	u32			sdam_base;
	bool			pd_not_supported;

	/* locks */
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#define PERPH_SUBTYPE_OFFSET	0x05
#define SUBTYPE_MASK		GENMASK(7, 0)
#define INT_RT_STS_OFFSET	0x10
#define SDAM_TYPE		0x2E

/********************************
 *  CHGR Peripheral Registers  *
@@ -549,4 +550,8 @@ enum {
/* SDAM regs */
#define MISC_PBS_RT_STS_REG			(MISC_PBS_BASE + 0x10)
#define PULSE_SKIP_IRQ_BIT			BIT(4)

#define SDAM_QC_DET_STATUS_REG			0x58
#define SDAM_QC_ADC_LSB_REG			0x54

#endif /* __SMB5_CHARGER_REG_H */