Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8a07551 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "iio: qcom-spmi-adc5: Handle EOC properly"

parents e7d08db3 cdc861b1
Loading
Loading
Loading
Loading
+34 −4
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@
/* For PMIC7 */
#define ADC_APP_SID				0x40
#define ADC_APP_SID_MASK			0xf
#define ADC7_CONV_TIMEOUT			msecs_to_jiffies(10)
#define ADC7_CONV_TIMEOUT_MS			501

enum adc5_cal_method {
	ADC5_NO_CAL = 0,
@@ -433,6 +433,8 @@ static int adc7_do_conversion(struct adc5_chip *adc,
			u16 *data_volt, u16 *data_cur)
{
	int ret;
	unsigned long rc;
	unsigned int time_pending_ms;
	u8 status = 0;

	mutex_lock(&adc->lock);
@@ -444,15 +446,43 @@ static int adc7_do_conversion(struct adc5_chip *adc,
	}

	/* No support for polling mode at present*/
	wait_for_completion_timeout(&adc->complete,
					ADC7_CONV_TIMEOUT);
	rc = wait_for_completion_timeout(&adc->complete,
					msecs_to_jiffies(ADC7_CONV_TIMEOUT_MS));
	if (!rc) {
		pr_err("Reading ADC channel %s timed out\n",
			prop->datasheet_name);
		ret = -ETIMEDOUT;
		goto unlock;
	}

	/*
	 * As per the hardware documentation, EOC should happen within 15 ms
	 * in a good case where there could be multiple conversion requests
	 * going through PMIC HW arbiter for reading ADC channels. However, if
	 * for some reason, one of the conversion request fails and times out,
	 * worst possible delay can be 500 ms. Hence print a warning when we
	 * see EOC completion happened more than 15 ms.
	 */
	time_pending_ms = jiffies_to_msecs(rc);
	if (time_pending_ms < ADC7_CONV_TIMEOUT_MS &&
	    (ADC7_CONV_TIMEOUT_MS - time_pending_ms) > 15)
		pr_warn("ADC channel %s EOC took %u ms\n", prop->datasheet_name,
			ADC7_CONV_TIMEOUT_MS - time_pending_ms);

	ret = adc5_read(adc, ADC5_USR_STATUS1, &status, 1);
	if (ret < 0)
		goto unlock;

	if (status & ADC5_USR_STATUS1_CONV_FAULT) {
		pr_err("Unexpected conversion fault\n");
		pr_err("ADC channel %s unexpected conversion fault\n",
			prop->datasheet_name);
		ret = -EIO;
		goto unlock;
	}

	if (!(status & ADC5_USR_STATUS1_EOC)) {
		pr_err("ADC channel %s EOC bit not set, status=%#x\n",
			prop->datasheet_name, status);
		ret = -EIO;
		goto unlock;
	}