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

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

Merge "power: supply: qbg: Fixes in QBG driver"

parents 304bff3f 9a48d58c
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -484,7 +484,7 @@ int qbg_batterydata_init(struct device_node *profile_node,
	rc = alloc_chrdev_region(&battery->dev_no, 0, 1, "qbg_battery");
	if (rc < 0) {
		pr_err("Failed to allocate chrdev, rc=%d\n", rc);
		goto free_battery;
		return rc;
	}

	cdev_init(&battery->battery_cdev, &qbg_battery_data_fops);
@@ -534,8 +534,6 @@ int qbg_batterydata_init(struct device_node *profile_node,
	cdev_del(&battery->battery_cdev);
unregister_chrdev:
	unregister_chrdev_region(battery->dev_no, 1);
free_battery:
	kfree(battery);
	return rc;
}

+36 −6
Original line number Diff line number Diff line
@@ -17,14 +17,13 @@
enum debug_mask {
	QBG_DEBUG_BUS_READ	= BIT(0),
	QBG_DEBUG_BUS_WRITE	= BIT(1),
	QBG_DEBUG_FIFO		= BIT(2),
	QBG_DEBUG_SDAM		= BIT(2),
	QBG_DEBUG_IRQ		= BIT(3),
	QBG_DEBUG_DEVICE	= BIT(4),
	QBG_DEBUG_PROFILE	= BIT(5),
	QBG_DEBUG_SOC		= BIT(6),
	QBG_DEBUG_SDAM		= BIT(7),
	QBG_DEBUG_STATUS	= BIT(8),
	QBG_DEBUG_PON		= BIT(9),
	QBG_DEBUG_STATUS	= BIT(7),
	QBG_DEBUG_PON		= BIT(8),
};

enum qbg_sdam {
@@ -37,6 +36,32 @@ enum qbg_sdam {
	SDAM_DATA4,
};

enum qbg_data_tag {
	QBG_DATA_TAG_FAST_CHAR,
};

enum QBG_SAMPLE_NUM_TYPE {
	SAMPLE_NUM_1,
	SAMPLE_NUM_2,
	SAMPLE_NUM_4,
	SAMPLE_NUM_8,
	SAMPLE_NUM_16,
	SAMPLE_NUM_32,
	QBG_SAMPLE_NUM_INVALID,
};

enum QBG_ACCUM_INTERVAL_TYPE {
	ACCUM_INTERVAL_100MS,
	ACCUM_INTERVAL_200MS,
	ACCUM_INTERVAL_500MS,
	ACCUM_INTERVAL_1000MS,
	ACCUM_INTERVAL_2000MS,
	ACCUM_INTERVAL_5000MS,
	ACCUM_INTERVAL_10000MS,
	ACCUM_INTERVAL_100000MS,
	ACCUM_INTERVAL_INVALID,
};

/**
 * struct qti_qbg - Structure for QTI QBG device
 * @dev:		Pointer to QBG device structure
@@ -70,8 +95,11 @@ enum qbg_sdam {
 * @batt_type_str:	String array denoting battery type
 * @irq:		QBG irq number
 * @base:		Base address of QBG HW
 * @num_sdams:		Number of sdams used for QBG
 * @num_data_sdams:	Number of data sdams used for QBG
 * @batt_id_ohm:	Battery resistance in ohms
 * @sdam_batt_id:	Battery ID stored and retrieved from SDAM
 * @essential_param_revid:	QBG essential parameters revision ID
 * @sample_time_us:	Array of accumulator sample time in each QBG HW state
 * @debug_mask:		Debug mask to enable/disable debug prints
 * @pon_ocv:		Power-on OCV of QBG device
 * @pon_ibat:		Power-on current of QBG device
@@ -138,9 +166,11 @@ struct qti_qbg {
	int			irq;
	u32			base;
	u32			sdam_base;
	u32			num_sdams;
	u32			num_data_sdams;
	u32			batt_id_ohm;
	u32			sdam_batt_id;
	u32			essential_param_revid;
	u32			sample_time_us[QBG_STATE_MAX];
	u32			*debug_mask;
	int			pon_ocv;
	int			pon_ibat;
+91 −14
Original line number Diff line number Diff line
@@ -49,22 +49,18 @@ int qbg_sdam_get_fifo_data(struct qti_qbg *chip, struct fifo_data *fifo,
	fifo_data_length = fifo_count * QBG_ONE_FIFO_LENGTH;
	num_sdams = fifo_data_length / QBG_SDAM_ONE_FIFO_REGION_SIZE;

	if (num_sdams > chip->num_sdams) {
	if (num_sdams > chip->num_data_sdams) {
		pr_err("Fifo count exceeds QBG SDAMs\n");
		return -EINVAL;
	}

	qbg_dbg(chip, QBG_DEBUG_FIFO, "Completely filled sdams=%d\n",
	qbg_dbg(chip, QBG_DEBUG_SDAM, "Completely filled sdams=%d\n",
		num_sdams);

	/* First read SDAMs that are completely filled */
	for (i = 0; i < num_sdams; i++) {
		if (!chip->sdam[i]) {
			pr_err("Number of SDAMs not sufficient to read FIFOs\n");
			return -ENODEV;
		}
		rc = qbg_sdam_read(chip,
			QBG_SDAM_DATA_START_OFFSET(chip, SDAM_DATA0 + i),
			QBG_SDAM_DATA_START_OFFSET(chip, (SDAM_DATA0 + i)),
			(((u8 *)fifo) + bytes_read),
			QBG_SDAM_ONE_FIFO_REGION_SIZE);
		if (rc < 0) {
@@ -77,12 +73,12 @@ int qbg_sdam_get_fifo_data(struct qti_qbg *chip, struct fifo_data *fifo,

	/* Next read SDAM that is partially filled */
	bytes_remaining = fifo_data_length - bytes_read;
	qbg_dbg(chip, QBG_DEBUG_FIFO, "Valid data in partially filled sdam:%d bytes\n",
	qbg_dbg(chip, QBG_DEBUG_SDAM, "Valid data in partially filled sdam:%d bytes\n",
		bytes_remaining);

	if (bytes_remaining) {
		rc = qbg_sdam_read(chip,
				QBG_SDAM_DATA_START_OFFSET(chip, SDAM_DATA0 + i),
				QBG_SDAM_DATA_START_OFFSET(chip, (SDAM_DATA0 + i)),
				(((u8 *)fifo) + bytes_read),
				bytes_remaining);
		if (rc < 0) {
@@ -93,7 +89,7 @@ int qbg_sdam_get_fifo_data(struct qti_qbg *chip, struct fifo_data *fifo,
		bytes_read += bytes_remaining;
	}

	qbg_dbg(chip, QBG_DEBUG_FIFO, "Total bytes read=%d\n", bytes_read);
	qbg_dbg(chip, QBG_DEBUG_SDAM, "Total bytes read=%d\n", bytes_read);

	return rc;
}
@@ -106,13 +102,13 @@ int qbg_sdam_get_essential_params(struct qti_qbg *chip, u8 *params)
		return -EINVAL;

	rc = qbg_sdam_read(chip,
			chip->sdam_base + (SDAM_CTRL1 * 0x100) +
			chip->sdam_base + (SDAM_CTRL1 * QBG_SINGLE_SDAM_SIZE) +
			QBG_ESSENTIAL_PARAMS_START_OFFSET,
			(u8 *)params, sizeof(struct qbg_essential_params));
	if (rc < 0)
		pr_err("Failed to read QBG essential params, rc=%d\n", rc);
	else
		qbg_dbg(chip, QBG_DEBUG_FIFO, "Read QBG essential params\n");
		qbg_dbg(chip, QBG_DEBUG_SDAM, "Read QBG essential params\n");

	return rc;
}
@@ -125,13 +121,94 @@ int qbg_sdam_set_essential_params(struct qti_qbg *chip, u8 *params)
		return -EINVAL;

	rc = qbg_sdam_write(chip,
			chip->sdam_base + (SDAM_CTRL1 * 0x100) +
			chip->sdam_base + (SDAM_CTRL1 * QBG_SINGLE_SDAM_SIZE) +
			QBG_ESSENTIAL_PARAMS_START_OFFSET,
			(u8 *)params, sizeof(struct qbg_essential_params));
	if (rc < 0)
		pr_err("Failed to write QBG essential params, rc=%d\n", rc);
	else
		qbg_dbg(chip, QBG_DEBUG_FIFO, "Written QBG essential params\n");
		qbg_dbg(chip, QBG_DEBUG_SDAM, "Written QBG essential params\n");

	return rc;
}

int qbg_sdam_get_essential_param_revid(struct qti_qbg *chip, u8 *revid)
{
	int rc;

	if (!chip || !revid)
		return -EINVAL;

	rc = qbg_sdam_read(chip,
			chip->sdam_base + (SDAM_CTRL1 * QBG_SINGLE_SDAM_SIZE) +
			QBG_ESSENTIAL_PARAMS_REVID_OFFSET,
			revid, 1);
	if (rc < 0)
		pr_err("Failed to read QBG essential params revid, rc=%d\n", rc);
	else
		qbg_dbg(chip, QBG_DEBUG_SDAM, "Read QBG essential params revid:%u\n", *revid);

	return rc;
}

int qbg_sdam_set_essential_param_revid(struct qti_qbg *chip, u8 revid)
{
	int rc;

	if (!chip)
		return -EINVAL;

	rc = qbg_sdam_write(chip,
			chip->sdam_base + (SDAM_CTRL1 * QBG_SINGLE_SDAM_SIZE) +
			QBG_ESSENTIAL_PARAMS_REVID_OFFSET,
			&revid, 1);
	if (rc < 0)
		pr_err("Failed to write QBG essential params revid, rc=%d\n", rc);
	else
		qbg_dbg(chip, QBG_DEBUG_SDAM, "Store QBG essential params revid:%u\n",
				revid);

	return rc;
}

int qbg_sdam_get_battery_id(struct qti_qbg *chip, u32 *battid)
{
	int rc;
	u8 buf[2];

	if (!chip || !battid)
		return -EINVAL;

	rc = qbg_sdam_read(chip,
			chip->sdam_base + (SDAM_CTRL1 * QBG_SINGLE_SDAM_SIZE) +
			QBG_ESSENTIAL_PARAMS_BATTID_OFFSET,
			buf, 2);
	if (rc < 0) {
		pr_err("Failed to read QBG battery ID, rc=%d\n", rc);
	} else {
		*battid = buf[0] | (buf[1] << 8);
		qbg_dbg(chip, QBG_DEBUG_SDAM, "Read QBG battery ID:%u\n",
			*battid);
	}

	return rc;
}

int qbg_sdam_set_battery_id(struct qti_qbg *chip, u32 battid)
{
	int rc;

	if (!chip)
		return -EINVAL;

	rc = qbg_sdam_write(chip,
			chip->sdam_base + (SDAM_CTRL1 * QBG_SINGLE_SDAM_SIZE) +
			QBG_ESSENTIAL_PARAMS_BATTID_OFFSET,
			(u8 *)&battid, 2);
	if (rc < 0)
		pr_err("Failed to write QBG battery ID, rc=%d\n", rc);
	else
		qbg_dbg(chip, QBG_DEBUG_SDAM, "Store QBG battery ID:%u\n", battid);

	return rc;
}
+14 −3
Original line number Diff line number Diff line
@@ -10,7 +10,9 @@
#define QBG_SDAM_FIFO_COUNT_OFFSET		0x46
#define QBG_ESSENTIAL_PARAMS_START_OFFSET	0x47
#define QBG_SDAM_START_OFFSET			0x4b
#define QBG_ESSENTIAL_PARAMS_BATTID_OFFSET	0x45
#define QBG_SDAM_BHARGER_OCV_HDRM_OFFSET	0x5b
#define QBG_ESSENTIAL_PARAMS_REVID_OFFSET	0xbb
#define QBG_SDAM_INT_TEST1			0xe0
#define QBG_SDAM_INT_TEST_VAL			0xe1
#define QBG_SDAM_DATA_PUSH_COUNTER_OFFSET	0x46
@@ -19,14 +21,23 @@
#define QBG_SDAM_ONE_FIFO_REGION_SIZE		117 /* 117 bytes for FIFO starting from 0x4B */
#define QBG_SDAM_ESR_PULSE_FIFO_INDEX		11

#define QBG_SINGLE_SDAM_SIZE			0x100
#define QBG_SDAM_BASE(chip, index)	(chip->sdam_base + (index * QBG_SINGLE_SDAM_SIZE))

#define QBG_SDAM_DATA_START_OFFSET(chip, index)	\
	(chip->sdam_base + (index * 0x100) + QBG_SDAM_START_OFFSET)
	(QBG_SDAM_BASE(chip, index) + QBG_SDAM_START_OFFSET)

int qbg_sdam_read(struct qti_qbg *chip, int offset, u8 *data, int length);
int qbg_sdam_write(struct qti_qbg *chip, int offset, u8 *data, int length);
int qbg_sdam_read(struct qti_qbg *chip, int offset, u8 *data,
			int length);
int qbg_sdam_write(struct qti_qbg *chip, int offset, u8 *data,
			int length);
int qbg_sdam_get_fifo_data(struct qti_qbg *chip, struct fifo_data *fifo,
				u32 fifo_count);
int qbg_sdam_get_essential_params(struct qti_qbg *chip, u8 *params);
int qbg_sdam_set_essential_params(struct qti_qbg *chip, u8 *params);

int qbg_sdam_get_essential_param_revid(struct qti_qbg *chip, u8 *revid);
int qbg_sdam_set_essential_param_revid(struct qti_qbg *chip, u8 revid);
int qbg_sdam_get_battery_id(struct qti_qbg *chip, u32 *battid);
int qbg_sdam_set_battery_id(struct qti_qbg *chip, u32 battid);
#endif /* __QBG_SDAM_H__ */
+174 −56
Original line number Diff line number Diff line
@@ -67,15 +67,28 @@

#define QBG_MAIN_VBAT_EMPTY_THRESH			0x56

#define QBG_MAIN_HPM_MEAS_CTL2				0x5d

#define QBG_MAIN_MPM_MEAS_CTL2				0x61

#define QBG_MAIN_LPM_MEAS_CTL2				0x65
#define QBG_NUM_OF_ACCUM_MASK				GENMASK(7, 5)
#define QBG_NUM_OF_ACCUM_SHIFT				5
#define QBG_ACCUM_INTERVAL_MASK				GENMASK(2, 0)

#define QBG_MAIN_FAST_CHAR_MEAS_CTL2			0x69

#define QBG_MAIN_PON_OCV_ACC0_DATA0			0x70

#define QBG_MAIN_LAST_ADC_ACC0_DATA0			0x9A

#define QBG_MAIN_LAST_BURST_AVG_ACC0_DATA0		0xA0

#define QBG_MAIN_LAST_BURST_AVG_ACC2_DATA0		0xA4

#define QBG_FAST_CHAR_DELTA_MS				100000
#define VBATT_1S_LSB					19463
#define IBATT_10A_LSB					30518
#define IBATT_10A_LSB					6103
#define VBAT_0PCT_OCV					300000000ULL
#define ICHG_FS_10A					1
#define TBAT_LSB					7500
@@ -86,12 +99,15 @@
#define OCV_BOOST_MAX_UV				5600000
#define OCV_BOOST_STEP_UV				100000

enum qbg_data_tag {
	QBG_DATA_TAG_FAST_CHAR,
};

static int qbg_debug_mask;

static const unsigned int qbg_accum_interval[8] = {
	10000, 20000, 50000, 100000, 150000, 200000, 500000, 1000000};
static const unsigned int qbg_lpm_accum_interval[8] = {
	100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000, 100000000};
static const unsigned int qbg_fast_char_avg_interval[8] = {
	6250, 12500, 25000, 50000, 100000, 200000, 400000, 800000};

static const struct qbg_iio_channels qbg_iio_psy_channels[] = {
	QBG_CHAN_INDEX("debug_battery", PSY_IIO_DEBUG_BATTERY)
	QBG_CHAN_ENERGY("capacity", PSY_IIO_CAPACITY)
@@ -100,6 +116,7 @@ static const struct qbg_iio_channels qbg_iio_psy_channels[] = {
	QBG_CHAN_VOLT("voltage_max", PSY_IIO_VOLTAGE_MAX)
	QBG_CHAN_VOLT("voltage_now", PSY_IIO_VOLTAGE_NOW)
	QBG_CHAN_VOLT("voltage_ocv", PSY_IIO_VOLTAGE_OCV)
	QBG_CHAN_VOLT("voltage_avg", PSY_IIO_VOLTAGE_AVG)
	QBG_CHAN_CUR("current_now", PSY_IIO_CURRENT_NOW)
	QBG_CHAN_RES("resistance_id", PSY_IIO_RESISTANCE_ID)
	QBG_CHAN_TSTAMP("time_to_full_avg", PSY_IIO_TIME_TO_FULL_AVG)
@@ -215,7 +232,7 @@ static int qbg_get_fifo_count(struct qti_qbg *chip, u32 *fifo_count)
	u8 val[2];

	rc = qbg_sdam_read(chip,
		QBG_SDAM_DATA_START_OFFSET(chip, SDAM_CTRL0) + QBG_SDAM_FIFO_COUNT_OFFSET,
		QBG_SDAM_BASE(chip, SDAM_CTRL0) + QBG_SDAM_FIFO_COUNT_OFFSET,
		val, 2);
	if (rc < 0) {
		pr_err("Failed to read QBG SDAM, rc=%d\n", rc);
@@ -223,7 +240,7 @@ static int qbg_get_fifo_count(struct qti_qbg *chip, u32 *fifo_count)
	}

	*fifo_count = (val[1] << 8) | val[0];
	qbg_dbg(chip, QBG_DEBUG_FIFO, "FIFO count=%d\n", *fifo_count);
	qbg_dbg(chip, QBG_DEBUG_SDAM, "FIFO count=%d\n", *fifo_count);

	return rc;
}
@@ -248,13 +265,14 @@ static void update_ocv_for_boost(struct qti_qbg *chip)

	qbg_dbg(chip, QBG_DEBUG_STATUS, "Boost OCV value written =%d\n", ocv_for_boost);
	qbg_sdam_write(chip,
		QBG_SDAM_DATA_START_OFFSET(chip, SDAM_CTRL0) + QBG_SDAM_BHARGER_OCV_HDRM_OFFSET,
		QBG_SDAM_BASE(chip, SDAM_CTRL0) + QBG_SDAM_BHARGER_OCV_HDRM_OFFSET,
		(u8 *)&ocv_for_boost, 1);
}

static void process_udata_work(struct work_struct *work)
{
	struct qti_qbg *chip = container_of(work, struct qti_qbg, udata_work);
	int rc;

	if (chip->udata.param[QBG_PARAM_BATT_SOC].valid)
		chip->batt_soc = chip->udata.param[QBG_PARAM_BATT_SOC].data;
@@ -306,6 +324,20 @@ static void process_udata_work(struct work_struct *work)
	if (chip->udata.param[QBG_PARAM_TBAT].valid)
		chip->tbat = chip->udata.param[QBG_PARAM_TBAT].data;

	if (chip->udata.param[QBG_PARAM_ESSENTIAL_PARAM_REVID].valid) {
		chip->essential_param_revid =
			chip->udata.param[QBG_PARAM_ESSENTIAL_PARAM_REVID].data;

		rc = qbg_sdam_set_essential_param_revid(chip, chip->essential_param_revid);
		if (rc < 0)
			pr_err("Failed to set essential param revid in sdam, rc=%d\n",
				rc);
	}

	rc = qbg_sdam_set_battery_id(chip, chip->batt_id_ohm / 1000);
	if (rc < 0)
		pr_err("Failed to set battid in sdam, rc=%d\n", rc);

	qbg_dbg(chip, QBG_DEBUG_STATUS, "udata update: batt_soc=%d sys_soc=%d soc=%d qbg_esr=%d\n",
		(chip->batt_soc != INT_MIN) ? chip->batt_soc : -EINVAL,
		(chip->sys_soc != INT_MIN) ? chip->sys_soc : -EINVAL,
@@ -382,7 +414,7 @@ static int qbg_process_fifo(struct qti_qbg *chip, u32 fifo_count)
	unsigned long timestamp;

	if (!fifo_count) {
		qbg_dbg(chip, QBG_DEBUG_FIFO, "No FIFO data\n");
		qbg_dbg(chip, QBG_DEBUG_SDAM, "No FIFO data\n");
		return -EINVAL;
	}

@@ -439,7 +471,7 @@ static int qbg_process_fifo(struct qti_qbg *chip, u32 fifo_count)
			esr = (vbat1 - vbat1_esr) / ((ibat_esr - ibat) * 10000);
			esr *= 10000;
			chip->esr = esr;
			qbg_dbg(chip, QBG_DEBUG_FIFO, "ESR:%u, ibat=%d ibat_esr=%d vbat1:%u vbat1_esr:%u\n",
			qbg_dbg(chip, QBG_DEBUG_SDAM, "ESR:%u, ibat=%d ibat_esr=%d vbat1:%u vbat1_esr:%u\n",
				esr, ibat, ibat_esr, vbat1, vbat1_esr);
		} else {
			pr_err("Couldn't calculate ESR, ibat=%d ibat_esr=%d vbat1:%u vbat1_esr:%u\n",
@@ -456,7 +488,7 @@ static int qbg_process_fifo(struct qti_qbg *chip, u32 fifo_count)
			goto ret;
		}

		qbg_dbg(chip, QBG_DEBUG_FIFO, "vbat1:%u ibat:%d tbat:%u ibat_t:%u\n",
		qbg_dbg(chip, QBG_DEBUG_SDAM, "vbat1:%u ibat:%d tbat:%u ibat_t:%u\n",
			vbat1, ibat, tbat, ibat_t);

		chip->kdata.fifo[i].v1 = vbat1;
@@ -464,6 +496,7 @@ static int qbg_process_fifo(struct qti_qbg *chip, u32 fifo_count)
		chip->kdata.fifo[i].i = ibat;
		chip->kdata.fifo[i].tbat = tbat;
		chip->kdata.fifo[i].ibat = ibat_t;
		chip->kdata.fifo[i].data_tag = fifo[i].data_tag;
	}

ret:
@@ -477,7 +510,7 @@ static int qbg_clear_fifo_data(struct qti_qbg *chip)
	u8 val[2] = {0, 0};

	rc = qbg_sdam_write(chip,
		QBG_SDAM_DATA_START_OFFSET(chip, SDAM_CTRL0) + QBG_SDAM_FIFO_COUNT_OFFSET,
		QBG_SDAM_BASE(chip, SDAM_CTRL0) + QBG_SDAM_FIFO_COUNT_OFFSET,
		val, 2);
	if (rc < 0) {
		pr_err("Failed to clear QBG FIFO Count, rc=%d\n", rc);
@@ -487,7 +520,7 @@ static int qbg_clear_fifo_data(struct qti_qbg *chip)
	for (i = 0; i < 10; i++) {
		val[0] = 0;
		rc = qbg_sdam_write(chip,
			QBG_SDAM_DATA_START_OFFSET(chip, SDAM_CTRL0) + QBG_SDAM_INT_TEST_VAL,
			QBG_SDAM_BASE(chip, SDAM_CTRL0) + QBG_SDAM_INT_TEST_VAL,
			val, 1);
		if (rc < 0) {
			pr_err("Failed to SDAM0 test val to 0, rc=%d\n", rc);
@@ -496,7 +529,7 @@ static int qbg_clear_fifo_data(struct qti_qbg *chip)

		/* Handshake with PBS to access FIFO data */
		rc = qbg_sdam_read(chip,
			QBG_SDAM_DATA_START_OFFSET(chip, SDAM_CTRL0) + QBG_SDAM_INT_TEST_VAL,
			QBG_SDAM_BASE(chip, SDAM_CTRL0) + QBG_SDAM_INT_TEST_VAL,
			val, 1);
		if (rc < 0) {
			pr_err("Failed to read QBG SDAM, rc=%d\n", rc);
@@ -512,7 +545,7 @@ static int qbg_clear_fifo_data(struct qti_qbg *chip)
	val[0] = QBG_SDAM_START_OFFSET;
	val[1] = 0x0;
	rc = qbg_sdam_write(chip,
		QBG_SDAM_DATA_START_OFFSET(chip, SDAM_DATA0) + QBG_SDAM_DATA_PUSH_COUNTER_OFFSET,
		QBG_SDAM_BASE(chip, SDAM_DATA0) + QBG_SDAM_DATA_PUSH_COUNTER_OFFSET,
		val, 2);
	if (rc < 0) {
		pr_err("Failed to configure QBG data push counter, rc=%d\n", rc);
@@ -520,7 +553,7 @@ static int qbg_clear_fifo_data(struct qti_qbg *chip)
	}
	val[0] = 0x0;
	rc = qbg_sdam_write(chip,
		QBG_SDAM_DATA_START_OFFSET(chip, SDAM_CTRL0) + QBG_SDAM_PBS_STATUS_OFFSET,
		QBG_SDAM_BASE(chip, SDAM_CTRL0) + QBG_SDAM_PBS_STATUS_OFFSET,
		val, 1);
	if (rc < 0) {
		pr_err("Failed to set QBG PBS status, rc=%d\n", rc);
@@ -537,7 +570,7 @@ static int qbg_init_sdam(struct qti_qbg *chip)

	val[0] = 0x80;
	rc = qbg_sdam_write(chip,
		QBG_SDAM_DATA_START_OFFSET(chip, SDAM_CTRL0) + QBG_SDAM_INT_TEST1, val, 1);
		QBG_SDAM_BASE(chip, SDAM_CTRL0) + QBG_SDAM_INT_TEST1, val, 1);
	if (rc < 0) {
		pr_err("Failed to write QBG SDAM, rc=%d\n", rc);
		return rc;
@@ -545,7 +578,7 @@ static int qbg_init_sdam(struct qti_qbg *chip)

	val[0] = 0;
	rc = qbg_sdam_read(chip,
		QBG_SDAM_DATA_START_OFFSET(chip, SDAM_CTRL0) +  QBG_SDAM_INT_TEST_VAL,
		QBG_SDAM_BASE(chip, SDAM_CTRL0) +  QBG_SDAM_INT_TEST_VAL,
		val, 1);
	if (rc < 0) {
		pr_err("Faiiled to read QBG SDAM, rc=%d\n", rc);
@@ -687,7 +720,7 @@ static int qbg_load_battery_profile(struct qti_qbg *chip)
	}

	profile_node = of_batterydata_get_best_profile(chip->batt_node,
			chip->batt_id_ohm, NULL);
			chip->batt_id_ohm / 1000, NULL);
	if (IS_ERR(profile_node)) {
		rc = PTR_ERR(profile_node);
		pr_err("Failed to detect valid QBG battery profile, rc=%d\n",
@@ -723,7 +756,7 @@ static int qbg_load_battery_profile(struct qti_qbg *chip)
		goto out;
	}

	rc = of_property_read_u32(profile_node, "qcom,fastchg-curr-ma",
	rc = of_property_read_u32(profile_node, "qcom,fastchg-current-ma",
				&chip->fastchg_curr_ma);
	if (rc < 0) {
		pr_err("Failed to read battery fastcharge current, rc:%d\n", rc);
@@ -868,42 +901,23 @@ static bool is_battery_present(struct qti_qbg *chip)
	return present;
}

#define BID_RPULL_OHM		100000
#define BID_VREF_MV		1875
static int get_batt_id_ohm(struct qti_qbg *chip, u32 *batt_id_ohm)
{
	int rc, batt_id_mv;
	int64_t denom;
	int rc, batt_id;

	if (!chip->batt_id_chan)
		return -EINVAL;

	/* Read battery-id */
	rc = iio_read_channel_processed(chip->batt_id_chan, &batt_id_mv);
	rc = iio_read_channel_processed(chip->batt_id_chan, &batt_id);
	if (rc < 0) {
		pr_err("Failed to read BATT_ID over ADC, rc=%d\n", rc);
		return rc;
	}

	batt_id_mv = div_s64(batt_id_mv, 1000);
	if (batt_id_mv == 0) {
		*batt_id_ohm = 0;
		pr_debug("batt_id_mv = 0 from ADC\n");
		return 0;
	}

	denom = div64_s64(BID_VREF_MV * 1000, batt_id_mv) - 1000;
	if (denom <= 0) {
		/* batt id connector might be open, return 0 kohms */
		*batt_id_ohm = 0;
		return 0;
	}

	*batt_id_ohm = div64_u64(BID_RPULL_OHM * 1000 + denom / 2, denom);
	chip->batt_id_ohm = *batt_id_ohm;
	*batt_id_ohm = (u32)batt_id;

	qbg_dbg(chip, QBG_DEBUG_PROFILE, "batt_id_mv=%d, batt_id_ohm=%d\n",
					batt_id_mv, *batt_id_ohm);
	qbg_dbg(chip, QBG_DEBUG_PROFILE, "batt_id_ohm=%u\n", *batt_id_ohm);

	return 0;
}
@@ -934,7 +948,7 @@ static int qbg_setup_battery(struct qti_qbg *chip)
		/* Update OCV boost headroom compensation value to 4.3V in debug battery case */
		if (is_debug_batt_id(chip)) {
			rc = qbg_sdam_write(chip,
				QBG_SDAM_DATA_START_OFFSET(chip, SDAM_CTRL0) +
				QBG_SDAM_BASE(chip, SDAM_CTRL0) +
				QBG_SDAM_BHARGER_OCV_HDRM_OFFSET, &ocv_boost_val, 1);
		}
	}
@@ -1034,13 +1048,6 @@ static int qbg_determine_pon_soc(struct qti_qbg *chip)
	return 0;
}

static int qbg_psy_set_prop(struct power_supply *psy,
			enum power_supply_property psp,
			const union power_supply_propval *pval)
{
	return 0;
}

static int qbg_psy_get_prop(struct power_supply *psy,
			enum power_supply_property psp,
			union power_supply_propval *pval)
@@ -1061,7 +1068,6 @@ static struct power_supply_desc qbg_psy_desc = {
	.properties		= qbg_psy_props,
	.num_properties		= ARRAY_SIZE(qbg_psy_props),
	.get_property		= qbg_psy_get_prop,
	.set_property		= qbg_psy_set_prop,
};

static int qbg_init_psy(struct qti_qbg *chip)
@@ -1121,6 +1127,9 @@ static int qbg_iio_read_raw(struct iio_dev *indio_dev,
	case PSY_IIO_VOLTAGE_OCV:
		*val1 = chip->ocv_uv;
		break;
	case PSY_IIO_VOLTAGE_AVG:
		rc = qbg_get_battery_voltage(chip, val1);
		break;
	case PSY_IIO_VOLTAGE_NOW:
		rc = qbg_get_battery_voltage(chip, val1);
		break;
@@ -1228,6 +1237,85 @@ static int qbg_init_iio(struct qti_qbg *chip,
	return rc;
}

static int qbg_get_accumulator_properties(struct qti_qbg *chip,
				enum QBG_STATE state,
				enum QBG_SAMPLE_NUM_TYPE *num_of_accum,
				enum QBG_ACCUM_INTERVAL_TYPE *accum_interval)
{
	int rc = 0;
	unsigned int reg = QBG_MAIN_LPM_MEAS_CTL2;
	unsigned char data = 0;

	if (state >= QBG_STATE_MAX || !num_of_accum || !accum_interval)
		return -EINVAL;

	switch (state) {
	case QBG_LPM:
		reg = QBG_MAIN_LPM_MEAS_CTL2;
		break;
	case QBG_MPM:
		reg = QBG_MAIN_MPM_MEAS_CTL2;
		break;
	case QBG_HPM:
		reg = QBG_MAIN_HPM_MEAS_CTL2;
		break;
	case QBG_FAST_CHAR:
		reg = QBG_MAIN_FAST_CHAR_MEAS_CTL2;
		break;
	default:
		pr_err("Invalid QBG state requested for accumulator properties %u\n",
			state);
		return rc;
	}

	rc = qbg_read(chip, reg, &data, 1);
	if (rc < 0) {
		pr_err("Failed to MEAS_CTL2 %u, rc=%d\n", reg, rc);
		return rc;
	}

	if (state == QBG_FAST_CHAR)
		*num_of_accum = 0;
	else
		*num_of_accum = (data & QBG_NUM_OF_ACCUM_MASK) >> QBG_NUM_OF_ACCUM_SHIFT;

	*accum_interval = data & QBG_ACCUM_INTERVAL_MASK;

	qbg_dbg(chip, QBG_DEBUG_DEVICE, "state:%u num_of_accum:%u accum_interval:%u\n",
			state, *num_of_accum, *accum_interval);

	return rc;
}

static int qbg_get_sample_time_us(struct qti_qbg *chip)
{
	int rc = 0, index;
	unsigned int interval;
	enum QBG_ACCUM_INTERVAL_TYPE accum_interval = ACCUM_INTERVAL_100MS;
	enum QBG_SAMPLE_NUM_TYPE num_accum = SAMPLE_NUM_1;

	for (index = 0; index < QBG_STATE_MAX; index++) {
		if (index == QBG_PON_OCV)
			continue;

		rc = qbg_get_accumulator_properties(chip, index, &num_accum,
					&accum_interval);
		if (rc < 0)
			return rc;

		if (index == QBG_FAST_CHAR)
			interval = qbg_fast_char_avg_interval[accum_interval];
		else if (index == QBG_LPM)
			interval = qbg_lpm_accum_interval[accum_interval];
		else
			interval = qbg_accum_interval[accum_interval];

		chip->sample_time_us[index] = interval;
	}

	return rc;
}

static ssize_t qbg_device_read(struct file *file, char __user *buf, size_t count,
			  loff_t *ppos)
{
@@ -1361,7 +1449,7 @@ static long qbg_device_ioctl(struct file *file, unsigned int cmd,
	struct qbg_config config;
	struct qbg_essential_params __user *params_user;
	unsigned long rtc_sec;
	int rc = 0;
	int rc = 0, i;

	if (!chip) {
		pr_err("Device private data not set!\n");
@@ -1383,8 +1471,29 @@ static long qbg_device_ioctl(struct file *file, unsigned int cmd,
	switch (cmd) {
	case QBGIOCXCFG:
		config_user = (struct qbg_config __user *)arg;

		rc = qbg_get_sample_time_us(chip);
		if (rc < 0) {
			pr_err("Failed to calculate sample time us, rc=%d\n", rc);
			return rc;
		}

		rc = qbg_sdam_get_battery_id(chip, &chip->sdam_batt_id);
		if (rc < 0) {
			pr_err("Failed to get battid from sdam, rc=%d\n", rc);
			return rc;
		}

		rc = qbg_sdam_get_essential_param_revid(chip,
					(u8 *)&chip->essential_param_revid);
		if (rc < 0) {
			pr_err("Failed to get essential param revid, rc=%d\n",
				rc);
			return rc;
		}

		config.current_time = rtc_sec;
		config.batt_id = chip->batt_id_ohm;
		config.batt_id = chip->batt_id_ohm / 1000;
		config.pon_ocv = chip->pon_ocv;
		config.pon_ibat = chip->pon_ibat;
		config.pon_tbat = chip->pon_tbat;
@@ -1395,16 +1504,25 @@ static long qbg_device_ioctl(struct file *file, unsigned int cmd,
		config.vph_min_mv = chip->vph_min_mv;
		config.iterm_ma = chip->iterm_ma;
		config.rconn_mohm = chip->rconn_mohm;
		config.sdam_batt_id = chip->sdam_batt_id;
		config.essential_param_revid = chip->essential_param_revid;
		for (i = 0; i < QBG_STATE_MAX; i++) {
			config.sample_time_us[i] = chip->sample_time_us[i];
			qbg_dbg(chip, QBG_DEBUG_DEVICE, "QBGIOCXCFG: sample_time_us[%d]:%u\n",
					i, config.sample_time_us[i]);
		}

		if (copy_to_user(config_user, (void *)&config, sizeof(config))) {
			pr_err("Failed to copy QBG config to user\n");
			return -EFAULT;
		}

		qbg_dbg(chip, QBG_DEBUG_DEVICE, "QBGIOCXCFG: battid:%u pon_ocv:%u pon_ibat:%u pon_soc:%u vbatt_cutoff_mv:%u iterm_ma:%u\n",
		qbg_dbg(chip, QBG_DEBUG_DEVICE, "QBGIOCXCFG: sdam_battid:%u essential param revid:%u battid:%u pon_ocv:%u pon_ibat:%u pon_soc:%u vbatt_cutoff_mv:%u iterm_ma:%u\n",
				config.sdam_batt_id, config.essential_param_revid,
				config.batt_id, config.pon_ocv,
				config.pon_ibat, config.pon_soc,
				config.vbat_cutoff_mv, config.iterm_ma);

		break;
	case QBGIOCXEPR:
		params_user = (struct qbg_essential_params __user *)arg;
@@ -1538,7 +1656,7 @@ static int qbg_parse_sdam_dt(struct qti_qbg *chip, struct device_node *node)
		return rc;
	}

	rc = of_property_read_u32(node, "sdam-base", &chip->sdam_base);
	rc = of_property_read_u32(node, "qcom,sdam-base", &chip->sdam_base);
	if (rc < 0) {
		pr_err("Failed to read SDAM base address, rc=%d\n", rc);
		return rc;
Loading