Exemplo n.º 1
0
int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_calib *result)
{
	struct qpnp_iadc_drv *iadc = qpnp_iadc;
	int rc;

	if (!iadc || !iadc->iadc_initialized)
		return -EPROBE_DEFER;

	rc = qpnp_check_pmic_temp();
	if (rc) {
		pr_err("Error checking pmic therm temp\n");
		return rc;
	}

	mutex_lock(&iadc->adc->adc_lock);
	result->gain_raw = iadc->adc->calib.gain_raw;
	result->ideal_gain_nv = QPNP_ADC_GAIN_NV;
	result->gain_uv = iadc->adc->calib.gain_uv;
	result->offset_raw = iadc->adc->calib.offset_raw;
	result->ideal_offset_uv =
				QPNP_OFFSET_CALIBRATION_SHORT_CADC_LEADS_IDEAL;
	result->offset_uv = iadc->adc->calib.offset_uv;
	mutex_unlock(&iadc->adc->adc_lock);

	return 0;
}
int32_t qpnp_iadc_get_gain_and_offset(struct qpnp_iadc_chip *iadc,
                                      struct qpnp_iadc_calib *result)
{
    int rc;

    if (qpnp_iadc_is_valid(iadc) < 0)
        return -EPROBE_DEFER;

    rc = qpnp_check_pmic_temp(iadc);
    if (rc) {
        pr_err("Error checking pmic therm temp\n");
        return rc;
    }

    mutex_lock(&iadc->adc->adc_lock);
    result->gain_raw = iadc->adc->calib.gain_raw;
    result->ideal_gain_nv = QPNP_ADC_GAIN_NV;
    result->gain_uv = iadc->adc->calib.gain_uv;
    result->offset_raw = iadc->adc->calib.offset_raw;
    result->ideal_offset_uv =
        QPNP_OFFSET_CALIBRATION_SHORT_CADC_LEADS_IDEAL;
    result->offset_uv = iadc->adc->calib.offset_uv;
    pr_debug("raw gain:0%x, raw offset:0%x\n",
             result->gain_raw, result->offset_raw);
    pr_debug("gain_uv:%d offset_uv:%d\n",
             result->gain_uv, result->offset_uv);
    mutex_unlock(&iadc->adc->adc_lock);

    return 0;
}
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;
}
Exemplo n.º 4
0
int32_t qpnp_iadc_vadc_sync_read(
	enum qpnp_iadc_channels i_channel, struct qpnp_iadc_result *i_result,
	enum qpnp_vadc_channels v_channel, struct qpnp_vadc_result *v_result)
{
	struct qpnp_iadc_drv *iadc = qpnp_iadc;
	int rc = 0;

	if (!iadc || !iadc->iadc_initialized)
		return -EPROBE_DEFER;

	mutex_lock(&iadc->iadc_vadc_lock);

	if (iadc->iadc_poll_eoc) {
		pr_debug("acquiring iadc eoc wakelock\n");
		pm_stay_awake(iadc->dev);
	}

	rc = qpnp_check_pmic_temp();
	if (rc) {
		pr_err("PMIC die temp check failed\n");
		goto fail;
	}

	iadc->iadc_mode_sel = true;

	rc = qpnp_vadc_iadc_sync_request(v_channel);
	if (rc) {
		pr_err("Configuring VADC failed\n");
		goto fail;
	}

	rc = qpnp_iadc_read(i_channel, i_result);
	if (rc)
		pr_err("Configuring IADC failed\n");
	/* Intentional fall through to release VADC */

	rc = qpnp_vadc_iadc_sync_complete_request(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->iadc_vadc_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;
    int dt_index = 0;

    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);

    while (((enum qpnp_iadc_channels)
            iadc->adc->adc_channels[dt_index].channel_num
            != 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;

    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_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;
	
	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_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);

	if (iadc->iadc_poll_eoc) {
		pr_debug("acquiring iadc eoc wakelock\n");
		pm_stay_awake(iadc->dev);
	}

	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;
	/* 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;
	}
	rc = qpnp_iadc_comp_result(&result_current);
	if (rc < 0)
		pr_err("Error during compensating the IADC\n");
	rc = 0;

	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;
}