mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 15:11:48 -04:00
Merge "power: supply: qbg: Fixes in QBG driver"
This commit is contained in:
commit
6392f903e7
6 changed files with 329 additions and 86 deletions
|
|
@ -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 @@ delete_cdev:
|
|||
cdev_del(&battery->battery_cdev);
|
||||
unregister_chrdev:
|
||||
unregister_chrdev_region(battery->dev_no, 1);
|
||||
free_battery:
|
||||
kfree(battery);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_SDAM_DATA_START_OFFSET(chip, index) \
|
||||
(chip->sdam_base + (index * 0x100) + QBG_SDAM_START_OFFSET)
|
||||
#define QBG_SINGLE_SDAM_SIZE 0x100
|
||||
#define QBG_SDAM_BASE(chip, index) (chip->sdam_base + (index * QBG_SINGLE_SDAM_SIZE))
|
||||
|
||||
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);
|
||||
#define QBG_SDAM_DATA_START_OFFSET(chip, index) \
|
||||
(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_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__ */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
*batt_id_ohm = (u32)batt_id;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,15 @@
|
|||
|
||||
#define MAX_FIFO_COUNT 36
|
||||
|
||||
enum QBG_STATE {
|
||||
QBG_LPM,
|
||||
QBG_MPM,
|
||||
QBG_HPM,
|
||||
QBG_FAST_CHAR,
|
||||
QBG_PON_OCV,
|
||||
QBG_STATE_MAX,
|
||||
};
|
||||
|
||||
enum QBG_SDAM_DATA_OFFSET {
|
||||
QBG_ACC0_OFFSET = 0,
|
||||
QBG_ACC1_OFFSET = 2,
|
||||
|
|
@ -41,10 +50,7 @@ enum qbg {
|
|||
QBG_PARAM_SYS_SOC_HOLD_100PCT,
|
||||
QBG_PARAM_JEITA_COOL_THRESHOLD,
|
||||
QBG_PARAM_TOTAL_IMPEDANCE,
|
||||
QBG_PARAM_PON_OCV,
|
||||
QBG_PARAM_PON_IBAT,
|
||||
QBG_PARAM_PON_SOC,
|
||||
QBG_PARAM_BATT_ID,
|
||||
QBG_PARAM_ESSENTIAL_PARAM_REVID,
|
||||
QBG_PARAM_FIFO_TIMESTAMP,
|
||||
QBG_PARAM_MAX,
|
||||
};
|
||||
|
|
@ -115,6 +121,9 @@ struct qbg_config {
|
|||
unsigned int iterm_ma;
|
||||
unsigned int rconn_mohm;
|
||||
unsigned long current_time;
|
||||
unsigned int sdam_batt_id;
|
||||
unsigned int essential_param_revid;
|
||||
unsigned long sample_time_us[QBG_STATE_MAX];
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct qbg_param {
|
||||
|
|
|
|||
Loading…
Reference in a new issue