static int apds990x_chip_off(struct apds990x_chip *chip) { apds990x_write_byte(chip, APDS990X_ENABLE, APDS990X_EN_DISABLE_ALL); if (chip->pdata->power_on) chip->pdata->power_on(0); return 0; }
static int apds990x_configure(struct apds990x_chip *chip) { /* It is recommended to use disabled mode during these operations */ apds990x_write_byte(chip, APDS990X_ENABLE, APDS990X_EN_DISABLE_ALL); /* conversion and wait times for different state machince states */ apds990x_write_byte(chip, APDS990X_PTIME, APDS990X_PTIME_DEFAULT); apds990x_write_byte(chip, APDS990X_WTIME, APDS990X_WTIME_DEFAULT); apds990x_set_atime(chip, APDS_LUX_AVERAGING_TIME); apds990x_write_byte(chip, APDS990X_CONFIG, 0); /* Persistence levels */ apds990x_write_byte(chip, APDS990X_PERS, (chip->lux_persistence << APDS990X_APERS_SHIFT) | (chip->prox_persistence << APDS990X_PPERS_SHIFT)); apds990x_write_byte(chip, APDS990X_PPCOUNT, chip->pdata->ppcount); /* Start with relatively small gain */ chip->again_meas = 1; chip->again_next = 1; apds990x_write_byte(chip, APDS990X_CONTROL, (chip->pdrive << 6) | (chip->pdiode << 4) | (chip->pgain << 2) | (chip->again_next << 0)); return 0; }
static inline int apds990x_set_atime(struct apds990x_chip *chip, u32 time_ms) { u8 reg_value; chip->atime = time_ms; /* Formula is specified in the data sheet */ reg_value = 256 - ((time_ms * TIME_STEP_SCALER) / TIMESTEP); /* Calculate max ADC value for given integration time */ chip->a_max_result = (u16)(256 - reg_value) * APDS990X_TIME_TO_ADC; return apds990x_write_byte(chip, APDS990X_ATIME, reg_value); }
static int apds990x_mode_on(struct apds990x_chip *chip) { /* ALS is mandatory, proximity optional */ u8 reg = APDS990X_EN_AIEN | APDS990X_EN_PON | APDS990X_EN_AEN | APDS990X_EN_WEN; if (chip->prox_en) reg |= APDS990X_EN_PIEN | APDS990X_EN_PEN; return apds990x_write_byte(chip, APDS990X_ENABLE, reg); }
/* 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; }
static int apds990x_set_arate(struct apds990x_chip *chip, int rate) { int i; for (i = 0; i < ARRAY_SIZE(arates_hz); i++) if (rate >= arates_hz[i]) break; if (i == ARRAY_SIZE(arates_hz)) return -EINVAL; /* Pick up corresponding persistence value */ chip->lux_persistence = apersis[i]; chip->arate = arates_hz[i]; /* If the chip is not in use, don't try to access it */ if (pm_runtime_suspended(&chip->client->dev)) return 0; /* Persistence levels */ return apds990x_write_byte(chip, APDS990X_PERS, (chip->lux_persistence << APDS990X_APERS_SHIFT) | (chip->prox_persistence << APDS990X_PPERS_SHIFT)); }
static int apds990x_chip_off(struct apds990x_chip *chip) { apds990x_write_byte(chip, APDS990X_ENABLE, APDS990X_EN_DISABLE_ALL); regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs); return 0; }