#define ISL29028_POWER_OFF_DELAY_MS 2000
-static const unsigned int isl29028_prox_sleep_time[] = {800, 400, 200, 100, 75,
- 50, 12, 0};
+struct isl29028_prox_data {
+ int sampling_int;
+ int sampling_fract;
+ int sleep_time;
+};
+
+static const struct isl29028_prox_data isl29028_prox_data[] = {
+ { 1, 250000, 800 },
+ { 2, 500000, 400 },
+ { 5, 0, 200 },
+ { 10, 0, 100 },
+ { 13, 300000, 75 },
+ { 20, 0, 50 },
+ { 80, 0, 13 }, /*
+ * Note: Data sheet lists 12.5 ms sleep time.
+ * Round up a half millisecond for msleep().
+ */
+ { 100, 0, 0 }
+};
enum isl29028_als_ir_mode {
ISL29028_MODE_NONE = 0,
struct isl29028_chip {
struct mutex lock;
struct regmap *regmap;
- unsigned int prox_sampling;
+ int prox_sampling_int;
+ int prox_sampling_frac;
bool enable_prox;
int lux_scale;
enum isl29028_als_ir_mode als_ir_mode;
};
-static int isl29028_find_prox_sleep_time_index(int sampling)
+static int isl29028_find_prox_sleep_index(int sampling_int, int sampling_fract)
{
- unsigned int period = DIV_ROUND_UP(1000, sampling);
int i;
- for (i = 0; i < ARRAY_SIZE(isl29028_prox_sleep_time); ++i) {
- if (period >= isl29028_prox_sleep_time[i])
- break;
+ for (i = 0; i < ARRAY_SIZE(isl29028_prox_data); ++i) {
+ if (isl29028_prox_data[i].sampling_int == sampling_int &&
+ isl29028_prox_data[i].sampling_fract == sampling_fract)
+ return i;
}
- return i;
+ return -EINVAL;
}
static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
- unsigned int sampling)
+ int sampling_int, int sampling_fract)
{
struct device *dev = regmap_get_device(chip->regmap);
int sleep_index, ret;
- sleep_index = isl29028_find_prox_sleep_time_index(sampling);
+ sleep_index = isl29028_find_prox_sleep_index(sampling_int,
+ sampling_fract);
+ if (sleep_index < 0)
+ return sleep_index;
+
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
ISL29028_CONF_PROX_SLP_MASK,
sleep_index << ISL29028_CONF_PROX_SLP_SH);
return ret;
}
- chip->prox_sampling = sampling;
+ chip->prox_sampling_int = sampling_int;
+ chip->prox_sampling_frac = sampling_fract;
return ret;
}
static int isl29028_enable_proximity(struct isl29028_chip *chip)
{
- int sleep_index, ret;
+ int prox_index, ret;
- ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling);
+ ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling_int,
+ chip->prox_sampling_frac);
if (ret < 0)
return ret;
return ret;
/* Wait for conversion to be complete for first sample */
- sleep_index = isl29028_find_prox_sleep_time_index(chip->prox_sampling);
- msleep(isl29028_prox_sleep_time[sleep_index]);
+ prox_index = isl29028_find_prox_sleep_index(chip->prox_sampling_int,
+ chip->prox_sampling_frac);
+ if (prox_index < 0)
+ return prox_index;
+
+ msleep(isl29028_prox_data[prox_index].sleep_time);
return 0;
}
break;
}
- ret = isl29028_set_proxim_sampling(chip, val);
+ ret = isl29028_set_proxim_sampling(chip, val, val2);
break;
case IIO_LIGHT:
if (mask != IIO_CHAN_INFO_SCALE) {
if (chan->type != IIO_PROXIMITY)
break;
- *val = chip->prox_sampling;
+ *val = chip->prox_sampling_int;
+ *val2 = chip->prox_sampling_frac;
ret = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
}
static IIO_CONST_ATTR(in_proximity_sampling_frequency_available,
- "1 3 5 10 13 20 83 100");
+ "1.25 2.5 5 10 13.3 20 80 100");
static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000");
#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
}
chip->enable_prox = false;
- chip->prox_sampling = 20;
+ chip->prox_sampling_int = 20;
+ chip->prox_sampling_frac = 0;
chip->lux_scale = 2000;
ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);