|
@@ -64,8 +64,25 @@
|
|
|
|
|
|
#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,
|
|
@@ -76,32 +93,37 @@ enum isl29028_als_ir_mode {
|
|
|
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);
|
|
@@ -112,16 +134,18 @@ static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
|
|
|
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;
|
|
|
|
|
@@ -132,8 +156,12 @@ static int isl29028_enable_proximity(struct isl29028_chip *chip)
|
|
|
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;
|
|
|
}
|
|
@@ -361,7 +389,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
|
|
|
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) {
|
|
@@ -439,7 +467,8 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
|
|
|
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:
|
|
@@ -472,7 +501,7 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
|
|
|
}
|
|
|
|
|
|
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)
|
|
@@ -571,7 +600,8 @@ static int isl29028_probe(struct i2c_client *client,
|
|
|
}
|
|
|
|
|
|
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);
|