|
@@ -224,74 +224,7 @@ static int isl29018_read_proximity_ir(struct i2c_client *client, int scheme,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static ssize_t get_sensor_data(struct device *dev, char *buf, int mode)
|
|
|
-{
|
|
|
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
|
|
- struct isl29018_chip *chip = iio_priv(indio_dev);
|
|
|
- struct i2c_client *client = chip->client;
|
|
|
- int value = 0;
|
|
|
- int status;
|
|
|
-
|
|
|
- mutex_lock(&chip->lock);
|
|
|
- switch (mode) {
|
|
|
- case COMMMAND1_OPMODE_PROX_ONCE:
|
|
|
- status = isl29018_read_proximity_ir(client,
|
|
|
- chip->prox_scheme, &value);
|
|
|
- break;
|
|
|
-
|
|
|
- case COMMMAND1_OPMODE_ALS_ONCE:
|
|
|
- status = isl29018_read_lux(client, &value);
|
|
|
- break;
|
|
|
-
|
|
|
- case COMMMAND1_OPMODE_IR_ONCE:
|
|
|
- status = isl29018_read_ir(client, &value);
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- dev_err(&client->dev, "Mode %d is not supported\n", mode);
|
|
|
- mutex_unlock(&chip->lock);
|
|
|
- return -EBUSY;
|
|
|
- }
|
|
|
- if (status < 0) {
|
|
|
- dev_err(&client->dev, "Error in Reading data");
|
|
|
- mutex_unlock(&chip->lock);
|
|
|
- return status;
|
|
|
- }
|
|
|
-
|
|
|
- mutex_unlock(&chip->lock);
|
|
|
-
|
|
|
- return sprintf(buf, "%d\n", value);
|
|
|
-}
|
|
|
-
|
|
|
/* Sysfs interface */
|
|
|
-/* lux_scale */
|
|
|
-static ssize_t show_lux_scale(struct device *dev,
|
|
|
- struct device_attribute *attr, char *buf)
|
|
|
-{
|
|
|
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
|
|
- struct isl29018_chip *chip = indio_dev->dev_data;
|
|
|
-
|
|
|
- return sprintf(buf, "%d\n", chip->lux_scale);
|
|
|
-}
|
|
|
-
|
|
|
-static ssize_t store_lux_scale(struct device *dev,
|
|
|
- struct device_attribute *attr, const char *buf, size_t count)
|
|
|
-{
|
|
|
- struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
|
|
- struct isl29018_chip *chip = indio_dev->dev_data;
|
|
|
- unsigned long lval;
|
|
|
-
|
|
|
- lval = simple_strtoul(buf, NULL, 10);
|
|
|
- if (lval == 0)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- mutex_lock(&chip->lock);
|
|
|
- chip->lux_scale = lval;
|
|
|
- mutex_unlock(&chip->lock);
|
|
|
-
|
|
|
- return count;
|
|
|
-}
|
|
|
-
|
|
|
/* range */
|
|
|
static ssize_t show_range(struct device *dev,
|
|
|
struct device_attribute *attr, char *buf)
|
|
@@ -409,27 +342,87 @@ static ssize_t store_prox_infrared_supression(struct device *dev,
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
-/* Read lux */
|
|
|
-static ssize_t show_lux(struct device *dev,
|
|
|
- struct device_attribute *devattr, char *buf)
|
|
|
+/* Channel IO */
|
|
|
+static int isl29018_write_raw(struct iio_dev *indio_dev,
|
|
|
+ struct iio_chan_spec const *chan,
|
|
|
+ int val,
|
|
|
+ int val2,
|
|
|
+ long mask)
|
|
|
{
|
|
|
- return get_sensor_data(dev, buf, COMMMAND1_OPMODE_ALS_ONCE);
|
|
|
-}
|
|
|
+ struct isl29018_chip *chip = iio_priv(indio_dev);
|
|
|
+ int ret = -EINVAL;
|
|
|
|
|
|
-/* Read ir */
|
|
|
-static ssize_t show_ir(struct device *dev,
|
|
|
- struct device_attribute *devattr, char *buf)
|
|
|
-{
|
|
|
- return get_sensor_data(dev, buf, COMMMAND1_OPMODE_IR_ONCE);
|
|
|
+ mutex_lock(&chip->lock);
|
|
|
+ if (mask == (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) &&
|
|
|
+ chan->type == IIO_LIGHT) {
|
|
|
+ chip->lux_scale = val;
|
|
|
+ ret = 0;
|
|
|
+ }
|
|
|
+ mutex_unlock(&chip->lock);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-/* Read nearest ir */
|
|
|
-static ssize_t show_proxim_ir(struct device *dev,
|
|
|
- struct device_attribute *devattr, char *buf)
|
|
|
+static int isl29018_read_raw(struct iio_dev *indio_dev,
|
|
|
+ struct iio_chan_spec const *chan,
|
|
|
+ int *val,
|
|
|
+ int *val2,
|
|
|
+ long mask)
|
|
|
{
|
|
|
- return get_sensor_data(dev, buf, COMMMAND1_OPMODE_PROX_ONCE);
|
|
|
+ int ret = -EINVAL;
|
|
|
+ struct isl29018_chip *chip = iio_priv(indio_dev);
|
|
|
+ struct i2c_client *client = chip->client;
|
|
|
+
|
|
|
+ mutex_lock(&chip->lock);
|
|
|
+ switch (mask) {
|
|
|
+ case 0:
|
|
|
+ switch (chan->type) {
|
|
|
+ case IIO_LIGHT:
|
|
|
+ ret = isl29018_read_lux(client, val);
|
|
|
+ break;
|
|
|
+ case IIO_INTENSITY:
|
|
|
+ ret = isl29018_read_ir(client, val);
|
|
|
+ break;
|
|
|
+ case IIO_PROXIMITY:
|
|
|
+ ret = isl29018_read_proximity_ir(client,
|
|
|
+ chip->prox_scheme, val);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (!ret)
|
|
|
+ ret = IIO_VAL_INT;
|
|
|
+ break;
|
|
|
+ case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
|
|
|
+ if (chan->type == IIO_LIGHT) {
|
|
|
+ *val = chip->lux_scale;
|
|
|
+ ret = IIO_VAL_INT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ mutex_unlock(&chip->lock);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
+static const struct iio_chan_spec isl29018_channels[] = {
|
|
|
+ {
|
|
|
+ .type = IIO_LIGHT,
|
|
|
+ .indexed = 1,
|
|
|
+ .channel = 0,
|
|
|
+ .processed_val = 1,
|
|
|
+ .info_mask = (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE),
|
|
|
+ }, {
|
|
|
+ .type = IIO_INTENSITY,
|
|
|
+ .modified = 1,
|
|
|
+ .channel2 = IIO_MOD_LIGHT_IR,
|
|
|
+ }, {
|
|
|
+ /* Unindexed in current ABI. But perhaps it should be. */
|
|
|
+ .type = IIO_PROXIMITY,
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
static IIO_DEVICE_ATTR(range, S_IRUGO | S_IWUSR, show_range, store_range, 0);
|
|
|
static IIO_CONST_ATTR(range_available, "1000 4000 16000 64000");
|
|
|
static IIO_CONST_ATTR(adc_resolution_available, "4 8 12 16");
|
|
@@ -439,11 +432,6 @@ static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_supression,
|
|
|
S_IRUGO | S_IWUSR,
|
|
|
show_prox_infrared_supression,
|
|
|
store_prox_infrared_supression, 0);
|
|
|
-static IIO_DEVICE_ATTR(illuminance0_input, S_IRUGO, show_lux, NULL, 0);
|
|
|
-static IIO_DEVICE_ATTR(illuminance0_calibscale, S_IRUGO | S_IWUSR,
|
|
|
- show_lux_scale, store_lux_scale, 0);
|
|
|
-static IIO_DEVICE_ATTR(intensity_infrared_raw, S_IRUGO, show_ir, NULL, 0);
|
|
|
-static IIO_DEVICE_ATTR(proximity_raw, S_IRUGO, show_proxim_ir, NULL, 0);
|
|
|
|
|
|
#define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
|
|
|
#define ISL29018_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
|
|
@@ -453,10 +441,6 @@ static struct attribute *isl29018_attributes[] = {
|
|
|
ISL29018_DEV_ATTR(adc_resolution),
|
|
|
ISL29018_CONST_ATTR(adc_resolution_available),
|
|
|
ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_supression),
|
|
|
- ISL29018_DEV_ATTR(illuminance0_input),
|
|
|
- ISL29018_DEV_ATTR(illuminance0_calibscale),
|
|
|
- ISL29018_DEV_ATTR(intensity_infrared_raw),
|
|
|
- ISL29018_DEV_ATTR(proximity_raw),
|
|
|
NULL
|
|
|
};
|
|
|
|
|
@@ -489,6 +473,8 @@ static int isl29018_chip_init(struct i2c_client *client)
|
|
|
static const struct iio_info isl29108_info = {
|
|
|
.attrs = &isl29108_group,
|
|
|
.driver_module = THIS_MODULE,
|
|
|
+ .read_raw = &isl29018_read_raw,
|
|
|
+ .write_raw = &isl29018_write_raw,
|
|
|
};
|
|
|
|
|
|
static int __devinit isl29018_probe(struct i2c_client *client,
|
|
@@ -520,6 +506,8 @@ static int __devinit isl29018_probe(struct i2c_client *client,
|
|
|
goto exit_iio_free;
|
|
|
|
|
|
indio_dev->info = &isl29108_info;
|
|
|
+ indio_dev->channels = isl29018_channels;
|
|
|
+ indio_dev->num_channels = ARRAY_SIZE(isl29018_channels);
|
|
|
indio_dev->name = id->name;
|
|
|
indio_dev->dev.parent = &client->dev;
|
|
|
indio_dev->modes = INDIO_DIRECT_MODE;
|