static int qpnp_get_battery_current(int *current_ua) { struct qpnp_iadc_result i_result; int ret; if (qpnp_iadc_is_ready()) { pr_err("%s: qpnp iadc is not ready!\n", __func__); *current_ua = 0; return 0; } ret = qpnp_iadc_read(EXTERNAL_RSENSE, &i_result); if (ret) { pr_err("%s: failed to read iadc\n", __func__); *current_ua = 0; return ret; } *current_ua = -i_result.result_ua; return 0; }
int32_t qpnp_iadc_calibrate_for_trim(void) { struct qpnp_iadc_drv *iadc = qpnp_iadc; uint8_t rslt_lsb, rslt_msb; int32_t rc = 0; uint16_t raw_data; uint32_t mode_sel = 0; if (!iadc || !iadc->iadc_initialized) return -EPROBE_DEFER; mutex_lock(&iadc->adc->adc_lock); if (iadc->iadc_poll_eoc) { pr_debug("acquiring iadc eoc wakelock\n"); pm_stay_awake(iadc->dev); } /* Exported symbol may be called from outside this driver. * Ensure this driver is ready (probed) before supporting * calibration. */ rc = qpnp_iadc_is_ready(); if (rc < 0) goto fail; rc = qpnp_iadc_configure(GAIN_CALIBRATION_17P857MV, &raw_data, mode_sel); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail; } iadc->adc->calib.gain_raw = raw_data; if (iadc->external_rsense) { /* external offset calculation */ rc = qpnp_iadc_configure(OFFSET_CALIBRATION_CSP_CSN, &raw_data, mode_sel); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail; } } else { /* internal offset calculation */ rc = qpnp_iadc_configure(OFFSET_CALIBRATION_CSP2_CSN2, &raw_data, mode_sel); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail; } } iadc->adc->calib.offset_raw = raw_data; if (rc < 0) { pr_err("qpnp adc offset/gain calculation failed\n"); goto fail; } pr_debug("raw gain:0x%x, raw offset:0x%x\n", iadc->adc->calib.gain_raw, iadc->adc->calib.offset_raw); rc = qpnp_convert_raw_offset_voltage(); if (rc < 0) { pr_err("qpnp raw_voltage conversion failed\n"); goto fail; } rslt_msb = (raw_data & QPNP_RAW_CODE_16_BIT_MSB_MASK) >> QPNP_BIT_SHIFT_8; rslt_lsb = raw_data & QPNP_RAW_CODE_16_BIT_LSB_MASK; pr_debug("trim values:lsb:0x%x and msb:0x%x\n", rslt_lsb, rslt_msb); rc = qpnp_iadc_write_reg(QPNP_IADC_SEC_ACCESS, QPNP_IADC_SEC_ACCESS_DATA); if (rc < 0) { pr_err("qpnp iadc configure error for sec access\n"); goto fail; } rc = qpnp_iadc_write_reg(QPNP_IADC_MSB_OFFSET, rslt_msb); if (rc < 0) { pr_err("qpnp iadc configure error for MSB write\n"); goto fail; } rc = qpnp_iadc_write_reg(QPNP_IADC_SEC_ACCESS, QPNP_IADC_SEC_ACCESS_DATA); if (rc < 0) { pr_err("qpnp iadc configure error for sec access\n"); goto fail; } rc = qpnp_iadc_write_reg(QPNP_IADC_LSB_OFFSET, rslt_lsb); if (rc < 0) { pr_err("qpnp iadc configure error for LSB write\n"); goto fail; } fail: if (iadc->iadc_poll_eoc) { pr_debug("releasing iadc eoc wakelock\n"); pm_relax(iadc->dev); } mutex_unlock(&iadc->adc->adc_lock); return rc; }