static int32_t qpnp_iadc_init_calib(void) { struct qpnp_iadc_drv *iadc = qpnp_iadc; int32_t rc = 0, result; rc = qpnp_iadc_configure(GAIN_CALIBRATION_25MV, &result); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail; } iadc->adc->calib.gain = result; rc = qpnp_iadc_configure(OFFSET_CALIBRATION_SHORT_CADC_LEADS, &result); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail; } iadc->adc->calib.offset = result; fail: return rc; }
int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel, int32_t *result) { struct qpnp_iadc_drv *iadc = qpnp_iadc; int32_t vsense_mv = 0, rc; mutex_lock(&iadc->adc->adc_lock); if (!iadc->iadc_init_calib) { rc = qpnp_iadc_init_calib(); if (!rc) { pr_err("Calibration failed\n"); goto fail; } else iadc->iadc_init_calib = true; } rc = qpnp_iadc_configure(channel, result); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail; } vsense_mv = ((*result - iadc->adc->calib.offset)/ (iadc->adc->calib.gain - iadc->adc->calib.offset)) * QPNP_ADC_GAIN_CALCULATION; *result = (vsense_mv/qpnp_iadc->rsense); fail: mutex_unlock(&iadc->adc->adc_lock); return rc; }
int32_t qpnp_iadc_read(enum qpnp_iadc_channels channel, struct qpnp_iadc_result *result) { struct qpnp_iadc_drv *iadc = qpnp_iadc; int32_t rc, rsense_n_ohms, sign = 0, num, mode_sel = 0; int32_t rsense_u_ohms = 0; int64_t result_current; uint16_t raw_data; if (!iadc || !iadc->iadc_initialized) return -EPROBE_DEFER; if (!iadc->iadc_mode_sel) { rc = qpnp_check_pmic_temp(); if (rc) { pr_err("Error checking pmic therm temp\n"); return rc; } } mutex_lock(&iadc->adc->adc_lock); rc = qpnp_iadc_configure(channel, &raw_data, mode_sel); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail; } rc = qpnp_iadc_get_rsense(&rsense_n_ohms); pr_debug("current raw:0%x and rsense:%d\n", raw_data, rsense_n_ohms); rsense_u_ohms = rsense_n_ohms/1000; num = raw_data - iadc->adc->calib.offset_raw; if (num < 0) { sign = 1; num = -num; } result->result_uv = (num * QPNP_ADC_GAIN_NV)/ (iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw); result_current = result->result_uv; result_current *= QPNP_IADC_NANO_VOLTS_FACTOR; do_div(result_current, rsense_u_ohms); if (sign) { result->result_uv = -result->result_uv; result_current = -result_current; } result->result_ua = (int32_t) result_current; fail: 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); } 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_vadc_sync_read(struct qpnp_iadc_chip *iadc, enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result, enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result) { int rc = 0, mode_sel = 0, num = 0, rsense_n_ohms = 0, sign = 0; int dt_index = 0; uint16_t raw_data; int32_t rsense_u_ohms = 0; int64_t result_current; if (qpnp_iadc_is_valid(iadc) < 0) return -EPROBE_DEFER; if ((iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw) == 0) { pr_err("raw offset errors! run iadc calibration again\n"); return -EINVAL; } mutex_lock(&iadc->adc->adc_lock); if (iadc->iadc_poll_eoc) { pr_debug("acquiring iadc eoc wakelock\n"); pm_stay_awake(iadc->dev); } iadc->iadc_mode_sel = true; rc = qpnp_vadc_iadc_sync_request(iadc->vadc_dev, v_channel); if (rc) { pr_err("Configuring VADC failed\n"); goto fail; } while (((enum qpnp_iadc_channels) iadc->adc->adc_channels[dt_index].channel_num != i_channel) && (dt_index < iadc->max_channels_available)) dt_index++; if (dt_index >= iadc->max_channels_available) { pr_err("not a valid IADC channel\n"); rc = -EINVAL; goto fail; } iadc->adc->amux_prop->decimation = iadc->adc->adc_channels[dt_index].adc_decimation; iadc->adc->amux_prop->fast_avg_setup = iadc->adc->adc_channels[dt_index].fast_avg_setup; rc = qpnp_iadc_configure(iadc, i_channel, &raw_data, mode_sel); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail_release_vadc; } rc = qpnp_iadc_get_rsense(iadc, &rsense_n_ohms); pr_debug("current raw:0%x and rsense:%d\n", raw_data, rsense_n_ohms); rsense_u_ohms = rsense_n_ohms/1000; num = raw_data - iadc->adc->calib.offset_raw; if (num < 0) { sign = 1; num = -num; } i_result->result_uv = (num * QPNP_ADC_GAIN_NV)/ (iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw); result_current = i_result->result_uv; result_current *= QPNP_IADC_NANO_VOLTS_FACTOR; /* Intentional fall through. Process the result w/o comp */ if (!rsense_u_ohms) { pr_err("rsense error=%d\n", rsense_u_ohms); goto fail_release_vadc; } do_div(result_current, rsense_u_ohms); if (sign) { i_result->result_uv = -i_result->result_uv; result_current = -result_current; } result_current *= -1; rc = qpnp_iadc_comp_result(iadc, &result_current); if (rc < 0) pr_err("Error during compensating the IADC\n"); rc = 0; result_current *= -1; i_result->result_ua = (int32_t) result_current; fail_release_vadc: rc = qpnp_vadc_iadc_sync_complete_request(iadc->vadc_dev, v_channel, v_result); if (rc) pr_err("Releasing VADC failed\n"); fail: iadc->iadc_mode_sel = false; 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_vadc_sync_read(struct qpnp_iadc_chip *iadc, enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result, enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result) { int rc = 0, mode_sel = 0, num = 0, rsense_n_ohms = 0, sign = 0; uint16_t raw_data; int32_t rsense_u_ohms = 0; int64_t result_current; 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->iadc_mode_sel = true; rc = qpnp_vadc_iadc_sync_request(iadc->vadc_dev, v_channel); if (rc) { pr_err("Configuring VADC failed\n"); goto fail; } rc = qpnp_iadc_configure(iadc, i_channel, &raw_data, mode_sel); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail_release_vadc; } rc = qpnp_iadc_get_rsense(iadc, &rsense_n_ohms); pr_debug("current raw:0%x and rsense:%d\n", raw_data, rsense_n_ohms); rsense_u_ohms = rsense_n_ohms/1000; num = raw_data - iadc->adc->calib.offset_raw; if (num < 0) { sign = 1; num = -num; } i_result->result_uv = (num * QPNP_ADC_GAIN_NV)/ (iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw); result_current = i_result->result_uv; result_current *= QPNP_IADC_NANO_VOLTS_FACTOR; /* Intentional fall through. Process the result w/o comp */ do_div(result_current, rsense_u_ohms); if (sign) { i_result->result_uv = -i_result->result_uv; result_current = -result_current; } result_current *= -1; rc = qpnp_iadc_comp_result(iadc, &result_current); if (rc < 0) pr_err("Error during compensating the IADC\n"); rc = 0; result_current *= -1; i_result->result_ua = (int32_t) result_current; fail_release_vadc: rc = qpnp_vadc_iadc_sync_complete_request(iadc->vadc_dev, v_channel, v_result); if (rc) pr_err("Releasing VADC failed\n"); fail: iadc->iadc_mode_sel = false; 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_read(struct qpnp_iadc_chip *iadc, enum qpnp_iadc_channels channel, struct qpnp_iadc_result *result) { int32_t rc, rsense_n_ohms, sign = 0, num, mode_sel = 0; int32_t rsense_u_ohms = 0; int64_t result_current; uint16_t raw_data; if (qpnp_iadc_is_valid(iadc) < 0) return -EPROBE_DEFER; if ((iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw) == 0) { pr_err("raw offset errors! run iadc calibration again\n"); return -EINVAL; } rc = qpnp_check_pmic_temp(iadc); if (rc) { pr_err("Error checking pmic therm temp\n"); return rc; } 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, channel, &raw_data, mode_sel); if (rc < 0) { pr_err("qpnp adc result read failed with %d\n", rc); goto fail; } rc = qpnp_iadc_get_rsense(iadc, &rsense_n_ohms); pr_debug("current raw:0%x and rsense:%d\n", raw_data, rsense_n_ohms); rsense_u_ohms = rsense_n_ohms/1000; num = raw_data - iadc->adc->calib.offset_raw; if (num < 0) { sign = 1; num = -num; } result->result_uv = (num * QPNP_ADC_GAIN_NV)/ (iadc->adc->calib.gain_raw - iadc->adc->calib.offset_raw); result_current = result->result_uv; result_current *= QPNP_IADC_NANO_VOLTS_FACTOR; /* Intentional fall through. Process the result w/o comp */ do_div(result_current, rsense_u_ohms); if (sign) { result->result_uv = -result->result_uv; result_current = -result_current; } result_current *= -1; rc = qpnp_iadc_comp_result(iadc, &result_current); if (rc < 0) pr_err("Error during compensating the IADC\n"); rc = 0; result_current *= -1; result->result_ua = (int32_t) result_current; 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; }