int32_t qpnp_iadc_calibrate_for_trim(struct qpnp_iadc_chip *iadc, bool batfet_closed) { uint8_t rslt_lsb, rslt_msb; int32_t rc = 0, version = 0; uint16_t raw_data; uint32_t mode_sel = 0; bool iadc_offset_ch_batfet_check; if (qpnp_iadc_is_valid(iadc) < 0) 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); } iadc->adc->amux_prop->decimation = DECIMATION_TYPE1; iadc->adc->amux_prop->fast_avg_setup = ADC_FAST_AVG_SAMPLE_1; rc = qpnp_iadc_configure(iadc, 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; /* * there is a features on PM8941 in the BMS where if the batfet is * opened the BMS reads from INTERNAL_RSENSE (channel 0) actually go to * OFFSET_CALIBRATION_CSP_CSN (channel 5). Hence if batfet is opened * we have to calibrate based on OFFSET_CALIBRATION_CSP_CSN even for * internal rsense. */ version = qpnp_adc_get_revid_version(iadc->dev); if ((version == QPNP_REV_ID_8941_3_1) || (version == QPNP_REV_ID_8941_3_0) || (version == QPNP_REV_ID_8941_2_0)) iadc_offset_ch_batfet_check = true; else iadc_offset_ch_batfet_check = false; if ((iadc_offset_ch_batfet_check && !batfet_closed) || (iadc->external_rsense)) { /* external offset calculation */ rc = qpnp_iadc_configure(iadc, 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(iadc, 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; } if (iadc->iadc_comp.revision_dig_major == QPNP_IADC_PM8026_2_REV2 && iadc->iadc_comp.revision_ana_minor == QPNP_IADC_PM8026_2_REV3) iadc->adc->calib.gain_raw = iadc->adc->calib.offset_raw + IADC_IDEAL_RAW_GAIN; 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(iadc); 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(iadc, 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(iadc, 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(iadc, 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(iadc, 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; }
int32_t qpnp_iadc_calibrate_for_trim(struct qpnp_iadc_chip *iadc, bool batfet_closed) { uint8_t rslt_lsb, rslt_msb; int32_t rc = 0, version = 0; uint16_t raw_data; uint32_t mode_sel = 0; bool iadc_offset_ch_batfet_check; if (qpnp_iadc_is_valid(iadc) < 0) 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); } rc = qpnp_iadc_configure(iadc, 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; version = qpnp_adc_get_revid_version(iadc->dev); if ((version == QPNP_REV_ID_8941_3_1) || (version == QPNP_REV_ID_8941_3_0) || (version == QPNP_REV_ID_8941_2_0)) iadc_offset_ch_batfet_check = true; else iadc_offset_ch_batfet_check = false; if ((iadc_offset_ch_batfet_check && !batfet_closed) || (iadc->external_rsense)) { rc = qpnp_iadc_configure(iadc, 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 { rc = qpnp_iadc_configure(iadc, 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; } if (iadc->iadc_comp.revision_dig_major == QPNP_IADC_PM8026_2_REV2 && iadc->iadc_comp.revision_ana_minor == QPNP_IADC_PM8026_2_REV3) iadc->adc->calib.gain_raw = iadc->adc->calib.offset_raw + IADC_IDEAL_RAW_GAIN; 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(iadc); 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(iadc, 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(iadc, 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(iadc, 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(iadc, 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; }
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; }
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; mutex_lock(&iadc->adc->adc_lock); if (iadc->iadc_poll_eoc) { pr_debug("acquiring iadc eoc wakelock\n"); pm_stay_awake(iadc->dev); } 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; 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; }
static 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; 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; 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; } rc = qpnp_convert_raw_offset_voltage(); 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; 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: return rc; }