diff options
author | 2016-04-11 10:41:07 +0300 | |
---|---|---|
committer | 2016-04-13 08:17:18 +0300 | |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/drivers/staging/iio/light | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/drivers/staging/iio/light')
-rw-r--r-- | kernel/drivers/staging/iio/light/isl29018.c | 296 | ||||
-rw-r--r-- | kernel/drivers/staging/iio/light/isl29028.c | 12 | ||||
-rw-r--r-- | kernel/drivers/staging/iio/light/tsl2583.c | 16 | ||||
-rw-r--r-- | kernel/drivers/staging/iio/light/tsl2x7x_core.c | 14 |
4 files changed, 176 insertions, 162 deletions
diff --git a/kernel/drivers/staging/iio/light/isl29018.c b/kernel/drivers/staging/iio/light/isl29018.c index a3489187a..bbf7e35cb 100644 --- a/kernel/drivers/staging/iio/light/isl29018.c +++ b/kernel/drivers/staging/iio/light/isl29018.c @@ -66,58 +66,113 @@ #define ISL29035_BOUT_SHIFT 0x07 #define ISL29035_BOUT_MASK (0x01 << ISL29035_BOUT_SHIFT) +#define ISL29018_INT_TIME_AVAIL "0.090000 0.005630 0.000351 0.000021" +#define ISL29023_INT_TIME_AVAIL "0.090000 0.005600 0.000352 0.000022" +#define ISL29035_INT_TIME_AVAIL "0.105000 0.006500 0.000410 0.000025" + +static const char * const int_time_avail[] = { + ISL29018_INT_TIME_AVAIL, + ISL29023_INT_TIME_AVAIL, + ISL29035_INT_TIME_AVAIL, +}; + +enum isl29018_int_time { + ISL29018_INT_TIME_16, + ISL29018_INT_TIME_12, + ISL29018_INT_TIME_8, + ISL29018_INT_TIME_4, +}; + +static const unsigned int isl29018_int_utimes[3][4] = { + {90000, 5630, 351, 21}, + {90000, 5600, 352, 22}, + {105000, 6500, 410, 25}, +}; + +static const struct isl29018_scale { + unsigned int scale; + unsigned int uscale; +} isl29018_scales[4][4] = { + { {0, 15258}, {0, 61035}, {0, 244140}, {0, 976562} }, + { {0, 244140}, {0, 976562}, {3, 906250}, {15, 625000} }, + { {3, 906250}, {15, 625000}, {62, 500000}, {250, 0} }, + { {62, 500000}, {250, 0}, {1000, 0}, {4000, 0} } +}; + struct isl29018_chip { struct device *dev; struct regmap *regmap; struct mutex lock; int type; - unsigned int lux_scale; - unsigned int lux_uscale; - unsigned int range; - unsigned int adc_bit; + unsigned int calibscale; + unsigned int ucalibscale; + unsigned int int_time; + struct isl29018_scale scale; int prox_scheme; bool suspended; }; -static int isl29018_set_range(struct isl29018_chip *chip, unsigned long range, - unsigned int *new_range) +static int isl29018_set_integration_time(struct isl29018_chip *chip, + unsigned int utime) { - static const unsigned long supp_ranges[] = {1000, 4000, 16000, 64000}; - int i; + int i, ret; + unsigned int int_time, new_int_time; - for (i = 0; i < ARRAY_SIZE(supp_ranges); ++i) { - if (range <= supp_ranges[i]) { - *new_range = (unsigned int)supp_ranges[i]; + for (i = 0; i < ARRAY_SIZE(isl29018_int_utimes[chip->type]); ++i) { + if (utime == isl29018_int_utimes[chip->type][i]) { + new_int_time = i; break; } } - if (i >= ARRAY_SIZE(supp_ranges)) + if (i >= ARRAY_SIZE(isl29018_int_utimes[chip->type])) return -EINVAL; - return regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, - COMMANDII_RANGE_MASK, i << COMMANDII_RANGE_SHIFT); + ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, + COMMANDII_RESOLUTION_MASK, + i << COMMANDII_RESOLUTION_SHIFT); + if (ret < 0) + return ret; + + /* keep the same range when integration time changes */ + int_time = chip->int_time; + for (i = 0; i < ARRAY_SIZE(isl29018_scales[int_time]); ++i) { + if (chip->scale.scale == isl29018_scales[int_time][i].scale && + chip->scale.uscale == isl29018_scales[int_time][i].uscale) { + chip->scale = isl29018_scales[new_int_time][i]; + break; + } + } + chip->int_time = new_int_time; + + return 0; } -static int isl29018_set_resolution(struct isl29018_chip *chip, - unsigned long adcbit, unsigned int *conf_adc_bit) +static int isl29018_set_scale(struct isl29018_chip *chip, int scale, int uscale) { - static const unsigned long supp_adcbit[] = {16, 12, 8, 4}; - int i; + int i, ret; + struct isl29018_scale new_scale; - for (i = 0; i < ARRAY_SIZE(supp_adcbit); ++i) { - if (adcbit >= supp_adcbit[i]) { - *conf_adc_bit = (unsigned int)supp_adcbit[i]; + for (i = 0; i < ARRAY_SIZE(isl29018_scales[chip->int_time]); ++i) { + if (scale == isl29018_scales[chip->int_time][i].scale && + uscale == isl29018_scales[chip->int_time][i].uscale) { + new_scale = isl29018_scales[chip->int_time][i]; break; } } - if (i >= ARRAY_SIZE(supp_adcbit)) + if (i >= ARRAY_SIZE(isl29018_scales[chip->int_time])) return -EINVAL; - return regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, - COMMANDII_RESOLUTION_MASK, - i << COMMANDII_RESOLUTION_SHIFT); + ret = regmap_update_bits(chip->regmap, ISL29018_REG_ADD_COMMANDII, + COMMANDII_RANGE_MASK, + i << COMMANDII_RANGE_SHIFT); + if (ret < 0) + return ret; + + chip->scale = new_scale; + + return 0; } static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode) @@ -156,22 +211,17 @@ static int isl29018_read_sensor_input(struct isl29018_chip *chip, int mode) static int isl29018_read_lux(struct isl29018_chip *chip, int *lux) { int lux_data; - unsigned int data_x_range, lux_unshifted; + unsigned int data_x_range; lux_data = isl29018_read_sensor_input(chip, COMMMAND1_OPMODE_ALS_ONCE); if (lux_data < 0) return lux_data; - /* To support fractional scaling, separate the unshifted lux - * into two calculations: int scaling and micro-scaling. - * lux_uscale ranges from 0-999999, so about 20 bits. Split - * the /1,000,000 in two to reduce the risk of over/underflow. - */ - data_x_range = lux_data * chip->range; - lux_unshifted = data_x_range * chip->lux_scale; - lux_unshifted += data_x_range / 1000 * chip->lux_uscale / 1000; - *lux = lux_unshifted >> chip->adc_bit; + data_x_range = lux_data * chip->scale.scale + + lux_data * chip->scale.uscale / 1000000; + *lux = data_x_range * chip->calibscale + + data_x_range * chip->ucalibscale / 1000000; return 0; } @@ -229,86 +279,37 @@ static int isl29018_read_proximity_ir(struct isl29018_chip *chip, int scheme, return 0; } -/* Sysfs interface */ -/* range */ -static ssize_t show_range(struct device *dev, +static ssize_t show_scale_available(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct isl29018_chip *chip = iio_priv(indio_dev); + int i, len = 0; - return sprintf(buf, "%u\n", chip->range); -} + for (i = 0; i < ARRAY_SIZE(isl29018_scales[chip->int_time]); ++i) + len += sprintf(buf + len, "%d.%06d ", + isl29018_scales[chip->int_time][i].scale, + isl29018_scales[chip->int_time][i].uscale); -static ssize_t store_range(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct isl29018_chip *chip = iio_priv(indio_dev); - int status; - unsigned long lval; - unsigned int new_range; - - if (kstrtoul(buf, 10, &lval)) - return -EINVAL; + buf[len - 1] = '\n'; - if (!(lval == 1000UL || lval == 4000UL || - lval == 16000UL || lval == 64000UL)) { - dev_err(dev, "The range is not supported\n"); - return -EINVAL; - } - - mutex_lock(&chip->lock); - status = isl29018_set_range(chip, lval, &new_range); - if (status < 0) { - mutex_unlock(&chip->lock); - dev_err(dev, - "Error in setting max range with err %d\n", status); - return status; - } - chip->range = new_range; - mutex_unlock(&chip->lock); - - return count; + return len; } -/* resolution */ -static ssize_t show_resolution(struct device *dev, +static ssize_t show_int_time_available(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct isl29018_chip *chip = iio_priv(indio_dev); + int i, len = 0; - return sprintf(buf, "%u\n", chip->adc_bit); -} - -static ssize_t store_resolution(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct isl29018_chip *chip = iio_priv(indio_dev); - int status; - unsigned int val; - unsigned int new_adc_bit; - - if (kstrtouint(buf, 10, &val)) - return -EINVAL; - if (!(val == 4 || val == 8 || val == 12 || val == 16)) { - dev_err(dev, "The resolution is not supported\n"); - return -EINVAL; - } + for (i = 0; i < ARRAY_SIZE(isl29018_int_utimes[chip->type]); ++i) + len += sprintf(buf + len, "0.%06d ", + isl29018_int_utimes[chip->type][i]); - mutex_lock(&chip->lock); - status = isl29018_set_resolution(chip, val, &new_adc_bit); - if (status < 0) { - mutex_unlock(&chip->lock); - dev_err(dev, "Error in setting resolution\n"); - return status; - } - chip->adc_bit = new_adc_bit; - mutex_unlock(&chip->lock); + buf[len - 1] = '\n'; - return count; + return len; } /* proximity scheme */ @@ -357,11 +358,29 @@ static int isl29018_write_raw(struct iio_dev *indio_dev, int ret = -EINVAL; mutex_lock(&chip->lock); - if (mask == IIO_CHAN_INFO_CALIBSCALE && chan->type == IIO_LIGHT) { - chip->lux_scale = val; - /* With no write_raw_get_fmt(), val2 is a MICRO fraction. */ - chip->lux_uscale = val2; - ret = 0; + switch (mask) { + case IIO_CHAN_INFO_CALIBSCALE: + if (chan->type == IIO_LIGHT) { + chip->calibscale = val; + chip->ucalibscale = val2; + ret = 0; + } + break; + case IIO_CHAN_INFO_INT_TIME: + if (chan->type == IIO_LIGHT) { + if (val) { + mutex_unlock(&chip->lock); + return -EINVAL; + } + ret = isl29018_set_integration_time(chip, val2); + } + break; + case IIO_CHAN_INFO_SCALE: + if (chan->type == IIO_LIGHT) + ret = isl29018_set_scale(chip, val, val2); + break; + default: + break; } mutex_unlock(&chip->lock); @@ -402,10 +421,24 @@ static int isl29018_read_raw(struct iio_dev *indio_dev, if (!ret) ret = IIO_VAL_INT; break; + case IIO_CHAN_INFO_INT_TIME: + if (chan->type == IIO_LIGHT) { + *val = 0; + *val2 = isl29018_int_utimes[chip->type][chip->int_time]; + ret = IIO_VAL_INT_PLUS_MICRO; + } + break; + case IIO_CHAN_INFO_SCALE: + if (chan->type == IIO_LIGHT) { + *val = chip->scale.scale; + *val2 = chip->scale.uscale; + ret = IIO_VAL_INT_PLUS_MICRO; + } + break; case IIO_CHAN_INFO_CALIBSCALE: if (chan->type == IIO_LIGHT) { - *val = chip->lux_scale; - *val2 = chip->lux_uscale; + *val = chip->calibscale; + *val2 = chip->ucalibscale; ret = IIO_VAL_INT_PLUS_MICRO; } break; @@ -421,7 +454,9 @@ static int isl29018_read_raw(struct iio_dev *indio_dev, .indexed = 1, \ .channel = 0, \ .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | \ - BIT(IIO_CHAN_INFO_CALIBSCALE), \ + BIT(IIO_CHAN_INFO_CALIBSCALE) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_INT_TIME), \ } #define ISL29018_IR_CHANNEL { \ @@ -447,32 +482,27 @@ static const struct iio_chan_spec isl29023_channels[] = { ISL29018_IR_CHANNEL, }; -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"); -static IIO_DEVICE_ATTR(adc_resolution, S_IRUGO | S_IWUSR, - show_resolution, store_resolution, 0); +static IIO_DEVICE_ATTR(in_illuminance_integration_time_available, S_IRUGO, + show_int_time_available, NULL, 0); +static IIO_DEVICE_ATTR(in_illuminance_scale_available, S_IRUGO, + show_scale_available, NULL, 0); static IIO_DEVICE_ATTR(proximity_on_chip_ambient_infrared_suppression, S_IRUGO | S_IWUSR, show_prox_infrared_suppression, store_prox_infrared_suppression, 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) + static struct attribute *isl29018_attributes[] = { - ISL29018_DEV_ATTR(range), - ISL29018_CONST_ATTR(range_available), - ISL29018_DEV_ATTR(adc_resolution), - ISL29018_CONST_ATTR(adc_resolution_available), + ISL29018_DEV_ATTR(in_illuminance_scale_available), + ISL29018_DEV_ATTR(in_illuminance_integration_time_available), ISL29018_DEV_ATTR(proximity_on_chip_ambient_infrared_suppression), NULL }; static struct attribute *isl29023_attributes[] = { - ISL29018_DEV_ATTR(range), - ISL29018_CONST_ATTR(range_available), - ISL29018_DEV_ATTR(adc_resolution), - ISL29018_CONST_ATTR(adc_resolution_available), + ISL29018_DEV_ATTR(in_illuminance_scale_available), + ISL29018_DEV_ATTR(in_illuminance_integration_time_available), NULL }; @@ -516,8 +546,6 @@ enum { static int isl29018_chip_init(struct isl29018_chip *chip) { int status; - unsigned int new_adc_bit; - unsigned int new_range; if (chip->type == isl29035) { status = isl29035_detect(chip); @@ -566,14 +594,19 @@ static int isl29018_chip_init(struct isl29018_chip *chip) usleep_range(1000, 2000); /* per data sheet, page 10 */ /* set defaults */ - status = isl29018_set_range(chip, chip->range, &new_range); + status = isl29018_set_scale(chip, chip->scale.scale, + chip->scale.uscale); if (status < 0) { dev_err(chip->dev, "Init of isl29018 fails\n"); return status; } - status = isl29018_set_resolution(chip, chip->adc_bit, - &new_adc_bit); + status = isl29018_set_integration_time(chip, + isl29018_int_utimes[chip->type][chip->int_time]); + if (status < 0) { + dev_err(chip->dev, "Init of isl29018 fails\n"); + return status; + } return 0; } @@ -681,7 +714,7 @@ static int isl29018_probe(struct i2c_client *client, int dev_id = 0; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); - if (indio_dev == NULL) { + if (!indio_dev) { dev_err(&client->dev, "iio allocation fails\n"); return -ENOMEM; } @@ -701,10 +734,10 @@ static int isl29018_probe(struct i2c_client *client, mutex_init(&chip->lock); chip->type = dev_id; - chip->lux_scale = 1; - chip->lux_uscale = 0; - chip->range = 1000; - chip->adc_bit = 16; + chip->calibscale = 1; + chip->ucalibscale = 0; + chip->int_time = ISL29018_INT_TIME_16; + chip->scale = isl29018_scales[chip->int_time][0]; chip->suspended = false; chip->regmap = devm_regmap_init_i2c(client, @@ -803,7 +836,6 @@ static struct i2c_driver isl29018_driver = { .name = "isl29018", .acpi_match_table = ACPI_PTR(isl29018_acpi_match), .pm = ISL29018_PM_OPS, - .owner = THIS_MODULE, .of_match_table = isl29018_of_match, }, .probe = isl29018_probe, diff --git a/kernel/drivers/staging/iio/light/isl29028.c b/kernel/drivers/staging/iio/light/isl29028.c index e5b2fdc23..32ae1127d 100644 --- a/kernel/drivers/staging/iio/light/isl29028.c +++ b/kernel/drivers/staging/iio/light/isl29028.c @@ -513,7 +513,7 @@ static int isl29028_probe(struct i2c_client *client, indio_dev->name = id->name; indio_dev->dev.parent = &client->dev; indio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); if (ret < 0) { dev_err(chip->dev, "iio registration fails with error %d\n", ret); @@ -522,14 +522,6 @@ static int isl29028_probe(struct i2c_client *client, return 0; } -static int isl29028_remove(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - - iio_device_unregister(indio_dev); - return 0; -} - static const struct i2c_device_id isl29028_id[] = { {"isl29028", 0}, {} @@ -547,11 +539,9 @@ static struct i2c_driver isl29028_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "isl29028", - .owner = THIS_MODULE, .of_match_table = isl29028_of_match, }, .probe = isl29028_probe, - .remove = isl29028_remove, .id_table = isl29028_id, }; diff --git a/kernel/drivers/staging/iio/light/tsl2583.c b/kernel/drivers/staging/iio/light/tsl2583.c index b5e1b8b0a..3100d960f 100644 --- a/kernel/drivers/staging/iio/light/tsl2583.c +++ b/kernel/drivers/staging/iio/light/tsl2583.c @@ -263,7 +263,7 @@ static int taos_get_lux(struct iio_dev *indio_dev) if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation)) goto return_max; - if (ch0 == 0) { + if (!ch0) { /* have no data, so return LAST VALUE */ ret = chip->als_cur_info.lux = 0; goto out_unlock; @@ -415,7 +415,7 @@ static int taos_chip_on(struct iio_dev *indio_dev) /* determine als integration register */ als_count = (chip->taos_settings.als_time * 100 + 135) / 270; - if (als_count == 0) + if (!als_count) als_count = 1; /* ensure at least one cycle */ /* convert back to time (encompasses overrides) */ @@ -499,7 +499,7 @@ static ssize_t taos_power_state_store(struct device *dev, if (kstrtoint(buf, 0, &value)) return -EINVAL; - if (value == 0) + if (!value) taos_chip_off(indio_dev); else taos_chip_on(indio_dev); @@ -862,7 +862,7 @@ static int taos_probe(struct i2c_client *clientp, indio_dev->dev.parent = &clientp->dev; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->name = chip->client->name; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); if (ret) { dev_err(&clientp->dev, "iio registration failed\n"); return ret; @@ -917,13 +917,6 @@ static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume); #define TAOS_PM_OPS NULL #endif -static int taos_remove(struct i2c_client *client) -{ - iio_device_unregister(i2c_get_clientdata(client)); - - return 0; -} - static struct i2c_device_id taos_idtable[] = { { "tsl2580", 0 }, { "tsl2581", 1 }, @@ -940,7 +933,6 @@ static struct i2c_driver taos_driver = { }, .id_table = taos_idtable, .probe = taos_probe, - .remove = taos_remove, }; module_i2c_driver(taos_driver); diff --git a/kernel/drivers/staging/iio/light/tsl2x7x_core.c b/kernel/drivers/staging/iio/light/tsl2x7x_core.c index 010e607dd..9dfd04855 100644 --- a/kernel/drivers/staging/iio/light/tsl2x7x_core.c +++ b/kernel/drivers/staging/iio/light/tsl2x7x_core.c @@ -403,7 +403,7 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) goto return_max; } - if (ch0 == 0) { + if (!ch0) { /* have no data, so return LAST VALUE */ ret = chip->als_cur_info.lux; goto out_unlock; @@ -418,9 +418,9 @@ static int tsl2x7x_get_lux(struct iio_dev *indio_dev) if (p->ratio == 0) { lux = 0; } else { - ch0lux = DIV_ROUND_UP((ch0 * p->ch0), + ch0lux = DIV_ROUND_UP(ch0 * p->ch0, tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]); - ch1lux = DIV_ROUND_UP((ch1 * p->ch1), + ch1lux = DIV_ROUND_UP(ch1 * p->ch1, tsl2X7X_als_gainadj[chip->tsl2x7x_settings.als_gain]); lux = ch0lux - ch1lux; } @@ -678,7 +678,7 @@ static int tsl2x7x_chip_on(struct iio_dev *indio_dev) /* determine als integration register */ als_count = (chip->tsl2x7x_settings.als_time * 100 + 135) / 270; - if (als_count == 0) + if (!als_count) als_count = 1; /* ensure at least one cycle */ /* convert back to time (encompasses overrides) */ @@ -825,7 +825,7 @@ void tsl2x7x_prox_calculate(int *data, int length, int sample_sum; int tmp; - if (length == 0) + if (!length) length = 1; sample_sum = 0; @@ -1057,7 +1057,7 @@ static ssize_t tsl2x7x_als_persistence_store(struct device *dev, z = y * TSL2X7X_MIN_ITIME; filter_delay = - DIV_ROUND_UP(((result.integer * 1000) + result.fract), z); + DIV_ROUND_UP((result.integer * 1000) + result.fract, z); chip->tsl2x7x_settings.persistence &= 0xF0; chip->tsl2x7x_settings.persistence |= (filter_delay & 0x0F); @@ -1103,7 +1103,7 @@ static ssize_t tsl2x7x_prox_persistence_store(struct device *dev, z = y * TSL2X7X_MIN_ITIME; filter_delay = - DIV_ROUND_UP(((result.integer * 1000) + result.fract), z); + DIV_ROUND_UP((result.integer * 1000) + result.fract, z); chip->tsl2x7x_settings.persistence &= 0x0F; chip->tsl2x7x_settings.persistence |= ((filter_delay << 4) & 0xF0); |