Exemple #1
0
static ssize_t apds990x_set_lux_thresh(struct apds990x_chip *chip, u32 *target,
				const char *buf)
{
	unsigned long thresh;
	int ret;

	ret = kstrtoul(buf, 0, &thresh);
	if (ret)
		return ret;

	if (thresh > APDS_RANGE)
		return -EINVAL;

	mutex_lock(&chip->mutex);
	*target = thresh;
	/*
	 * Don't update values in HW if we are still waiting for
	 * first interrupt to come after device handle open call.
	 */
	if (!chip->lux_wait_fresh_res)
		apds990x_refresh_athres(chip);
	mutex_unlock(&chip->mutex);
	return ret;

}
Exemple #2
0
/* Called always with mutex locked */
static int apds990x_calc_again(struct apds990x_chip *chip)
{
	int curr_again = chip->again_meas;
	int next_again = chip->again_meas;
	int ret = 0;

	/* Calculate suitable als gain */
	if (chip->lux_clear == chip->a_max_result)
		next_again -= 2; /* ALS saturated. Decrease gain by 2 steps */
	else if (chip->lux_clear > chip->a_max_result / 2)
		next_again--;
	else if (chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT_STRICT)
		next_again += 2; /* Too dark. Increase gain by 2 steps */
	else if (chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT)
		next_again++;

	/* Limit gain to available range */
	if (next_again < 0)
		next_again = 0;
	else if (next_again > APDS990X_MAX_AGAIN)
		next_again = APDS990X_MAX_AGAIN;

	/* Let's check can we trust the measured result */
	if (chip->lux_clear == chip->a_max_result)
		/* Result can be totally garbage due to saturation */
		ret = -ERANGE;
	else if (next_again != curr_again &&
		chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT_STRICT)
		/*
		 * Gain is changed and measurement result is very small.
		 * Result can be totally garbage due to underflow
		 */
		ret = -ERANGE;

	chip->again_next = next_again;
	apds990x_write_byte(chip, APDS990X_CONTROL,
			(chip->pdrive << 6) |
			(chip->pdiode << 4) |
			(chip->pgain << 2) |
			(chip->again_next << 0));

	/*
	 * Error means bad result -> re-measurement is needed. The forced
	 * refresh uses fastest possible persistence setting to get result
	 * as soon as possible.
	 */
	if (ret < 0)
		apds990x_force_a_refresh(chip);
	else
		apds990x_refresh_athres(chip);

	return ret;
}