Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'iio-for-4.17a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:

First round of new devices, features and cleanups for IIO in the 4.17 cycle.

Outside of IIO
* Strongly typed 64bit int_sqrt function needed by the mlx90632

New device support
* adc081s
- New driver supporting adc081s, adc101s and adc121s TI ADCs.
* ad5272
- New driver supproting the ad5272 and ad5274 ADI digital potentiometers
with DT bindings.
* axp20x_adc
- support the AXP813 ADC - includes rework patches to prepare for this.
* mlx90632
- New driver with dt bindings for this IR temperature sensor.

Features
* axp20x_adc
- Add DT bindings and probing.
* dht11
- The sensor has a wider range than advertised in the datasheet - support it.
* st_lsm6dsx
- Add hardware timestamp su9pport.

Cleanups
* ABI docs
- Update email contact for Matt Ranostay
* SPDX changes
- Matt Ranostay has moved his drivers over to SPDX. Currently we are making
this an author choice in IIO.
* ad7192
- Disable burnout current on misconfiguration. No actually effect as
they simply won't work otherwise.
* ad7476
- Drop a license definition that was replicating information in SPDX tag.
* ade7758
- Expand buf_lock to cover both buffer and state protection allowing
unintented uses of mlock in the core to be removed.
* ade7759
- Align parameters to opening parenthesis.
* at91_adc
- Depend on sysfs instead of selecting it - for try wide consistency.
* ccs811
- trivial naming type for a define.
* ep93xx
- Drop a redundant return as a result checking platform_get_resource.
* hts221
- Regmap conversion which simplifies the driver somewhat.
- Clean up some restricted endian cast warnings.
- Drop a trailing whitespace from a comment
- Drop an unnecessary get_unaligned by changing to the right 16bit data type.
* ms5611
- Fix coding style in the probe function (whitespace)
* st_accel
- Use strlcpy instead of strncpy to avoid potentially truncating a string.

+1807 -527
+1 -1
Documentation/ABI/testing/sysfs-bus-iio-chemical-vz89x
··· 1 1 What: /sys/bus/iio/devices/iio:deviceX/in_concentration_VOC_short_raw 2 2 Date: September 2015 3 3 KernelVersion: 4.3 4 - Contact: Matt Ranostay <mranostay@gmail.com> 4 + Contact: Matt Ranostay <matt.ranostay@konsulko.com> 5 5 Description: 6 6 Get the raw calibration VOC value from the sensor. 7 7 This value has little application outside of calibration.
+2 -2
Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
··· 1 1 What /sys/bus/iio/devices/iio:deviceX/in_proximity_input 2 2 Date: March 2014 3 3 KernelVersion: 3.15 4 - Contact: Matt Ranostay <mranostay@gmail.com> 4 + Contact: Matt Ranostay <matt.ranostay@konsulko.com> 5 5 Description: 6 6 Get the current distance in meters of storm (1km steps) 7 7 1000-40000 = distance in meters ··· 9 9 What /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity 10 10 Date: March 2014 11 11 KernelVersion: 3.15 12 - Contact: Matt Ranostay <mranostay@gmail.com> 12 + Contact: Matt Ranostay <matt.ranostay@konsulko.com> 13 13 Description: 14 14 Show or set the gain boost of the amp, from 0-31 range. 15 15 18 = indoors (default)
+48
Documentation/devicetree/bindings/iio/adc/axp20x_adc.txt
··· 1 + * X-Powers AXP ADC bindings 2 + 3 + Required properties: 4 + - compatible: should be one of: 5 + - "x-powers,axp209-adc", 6 + - "x-powers,axp221-adc", 7 + - "x-powers,axp813-adc", 8 + - #io-channel-cells: should be 1, 9 + 10 + Example: 11 + 12 + &axp22x { 13 + adc { 14 + compatible = "x-powers,axp221-adc"; 15 + #io-channel-cells = <1>; 16 + }; 17 + }; 18 + 19 + ADC channels and their indexes per variant: 20 + 21 + AXP209 22 + ------ 23 + 0 | acin_v 24 + 1 | acin_i 25 + 2 | vbus_v 26 + 3 | vbus_i 27 + 4 | pmic_temp 28 + 5 | gpio0_v 29 + 6 | gpio1_v 30 + 7 | ipsout_v 31 + 8 | batt_v 32 + 9 | batt_chrg_i 33 + 10 | batt_dischrg_i 34 + 35 + AXP22x 36 + ------ 37 + 0 | pmic_temp 38 + 1 | batt_v 39 + 2 | batt_chrg_i 40 + 3 | batt_dischrg_i 41 + 42 + AXP813 43 + ------ 44 + 0 | pmic_temp 45 + 1 | gpio0_v 46 + 2 | batt_v 47 + 3 | batt_chrg_i 48 + 4 | batt_dischrg_i
+27
Documentation/devicetree/bindings/iio/potentiometer/ad5272.txt
··· 1 + * Analog Devices AD5272 digital potentiometer 2 + 3 + The node for this device must be a child node of a I2C controller, hence 4 + all mandatory properties for your controller must be specified. See directory: 5 + 6 + Documentation/devicetree/bindings/i2c 7 + 8 + for more details. 9 + 10 + Required properties: 11 + - compatible: Must be one of the following, depending on the model: 12 + adi,ad5272-020 13 + adi,ad5272-050 14 + adi,ad5272-100 15 + adi,ad5274-020 16 + adi,ad5274-100 17 + 18 + Optional properties: 19 + - reset-gpios: GPIO specification for the RESET input. This is an 20 + active low signal to the AD5272. 21 + 22 + Example: 23 + ad5272: potentiometer@2f { 24 + reg = <0x2F>; 25 + compatible = "adi,ad5272-020"; 26 + reset-gpios = <&gpio3 6 GPIO_ACTIVE_HIGH>; 27 + };
+28
Documentation/devicetree/bindings/iio/temperature/mlx90632.txt
··· 1 + * Melexis MLX90632 contactless Infra Red temperature sensor 2 + 3 + Link to datasheet: https://www.melexis.com/en/documents/documentation/datasheets/datasheet-mlx90632 4 + 5 + There are various applications for the Infra Red contactless temperature sensor 6 + and MLX90632 is most suitable for consumer applications where measured object 7 + temperature is in range between -20 to 200 degrees Celsius with relative error 8 + of measurement below 1 degree Celsius in object temperature range for 9 + industrial applications. Since it can operate and measure ambient temperature 10 + in range of -20 to 85 degrees Celsius it is suitable also for outdoor use. 11 + 12 + Be aware that electronics surrounding the sensor can increase ambient 13 + temperature. MLX90632 can be calibrated to reduce the housing effect via 14 + already existing EEPROM parameters. 15 + 16 + Since measured object emissivity effects Infra Red energy emitted, emissivity 17 + should be set before requesting the object temperature. 18 + 19 + Required properties: 20 + - compatible: should be "melexis,mlx90632" 21 + - reg: the I2C address of the sensor (default 0x3a) 22 + 23 + Example: 24 + 25 + mlx90632@3a { 26 + compatible = "melexis,mlx90632"; 27 + reg = <0x3a>; 28 + };
+7
MAINTAINERS
··· 8878 8878 S: Supported 8879 8879 F: drivers/iio/temperature/mlx90614.c 8880 8880 8881 + MELEXIS MLX90632 DRIVER 8882 + M: Crt Mori <cmo@melexis.com> 8883 + L: linux-iio@vger.kernel.org 8884 + W: http://www.melexis.com 8885 + S: Supported 8886 + F: drivers/iio/temperature/mlx90632.c 8887 + 8881 8888 MELFAS MIP4 TOUCHSCREEN DRIVER 8882 8889 M: Sangwon Jee <jeesw@melfas.com> 8883 8890 W: http://www.melfas.com
+1 -2
drivers/iio/accel/st_accel_i2c.c
··· 159 159 if ((ret < 0) || (ret >= ST_ACCEL_MAX)) 160 160 return -ENODEV; 161 161 162 - strncpy(client->name, st_accel_id_table[ret].name, 162 + strlcpy(client->name, st_accel_id_table[ret].name, 163 163 sizeof(client->name)); 164 - client->name[sizeof(client->name) - 1] = '\0'; 165 164 } else if (!id) 166 165 return -ENODEV; 167 166
+1 -2
drivers/iio/adc/Kconfig
··· 144 144 config AT91_ADC 145 145 tristate "Atmel AT91 ADC" 146 146 depends on ARCH_AT91 147 - depends on INPUT 147 + depends on INPUT && SYSFS 148 148 select IIO_BUFFER 149 149 select IIO_TRIGGERED_BUFFER 150 - select SYSFS 151 150 help 152 151 Say yes here to build support for Atmel AT91 ADC. 153 152
+23 -3
drivers/iio/adc/ad7476.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 - * AD7466/7/8 AD7476/5/7/8 (A) SPI ADC driver 3 + * Analog Devices AD7466/7/8 AD7476/5/7/8 (A) SPI ADC driver 4 + * TI ADC081S/ADC101S/ADC121S 8/10/12-bit SPI ADC driver 3 5 * 4 6 * Copyright 2010 Analog Devices Inc. 5 - * 6 - * Licensed under the GPL-2 or later. 7 7 */ 8 8 9 9 #include <linux/device.h> ··· 56 56 ID_AD7468, 57 57 ID_AD7495, 58 58 ID_AD7940, 59 + ID_ADC081S, 60 + ID_ADC101S, 61 + ID_ADC121S, 59 62 }; 60 63 61 64 static irqreturn_t ad7476_trigger_handler(int irq, void *p) ··· 150 147 }, \ 151 148 } 152 149 150 + #define ADC081S_CHAN(bits) _AD7476_CHAN((bits), 12 - (bits), \ 151 + BIT(IIO_CHAN_INFO_RAW)) 153 152 #define AD7476_CHAN(bits) _AD7476_CHAN((bits), 13 - (bits), \ 154 153 BIT(IIO_CHAN_INFO_RAW)) 155 154 #define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \ ··· 195 190 }, 196 191 [ID_AD7940] = { 197 192 .channel[0] = AD7940_CHAN(14), 193 + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), 194 + }, 195 + [ID_ADC081S] = { 196 + .channel[0] = ADC081S_CHAN(8), 197 + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), 198 + }, 199 + [ID_ADC101S] = { 200 + .channel[0] = ADC081S_CHAN(10), 201 + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), 202 + }, 203 + [ID_ADC121S] = { 204 + .channel[0] = ADC081S_CHAN(12), 198 205 .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), 199 206 }, 200 207 }; ··· 311 294 {"ad7910", ID_AD7467}, 312 295 {"ad7920", ID_AD7466}, 313 296 {"ad7940", ID_AD7940}, 297 + {"adc081s", ID_ADC081S}, 298 + {"adc101s", ID_ADC101S}, 299 + {"adc121s", ID_ADC121S}, 314 300 {} 315 301 }; 316 302 MODULE_DEVICE_TABLE(spi, ad7476_id);
+152 -8
drivers/iio/adc/axp20x_adc.c
··· 35 35 #define AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(x) (((x) & BIT(0)) << 1) 36 36 37 37 #define AXP20X_ADC_RATE_MASK GENMASK(7, 6) 38 + #define AXP813_V_I_ADC_RATE_MASK GENMASK(5, 4) 39 + #define AXP813_ADC_RATE_MASK (AXP20X_ADC_RATE_MASK | AXP813_V_I_ADC_RATE_MASK) 38 40 #define AXP20X_ADC_RATE_HZ(x) ((ilog2((x) / 25) << 6) & AXP20X_ADC_RATE_MASK) 39 41 #define AXP22X_ADC_RATE_HZ(x) ((ilog2((x) / 100) << 6) & AXP20X_ADC_RATE_MASK) 42 + #define AXP813_TS_GPIO0_ADC_RATE_HZ(x) AXP20X_ADC_RATE_HZ(x) 43 + #define AXP813_V_I_ADC_RATE_HZ(x) ((ilog2((x) / 100) << 4) & AXP813_V_I_ADC_RATE_MASK) 44 + #define AXP813_ADC_RATE_HZ(x) (AXP20X_ADC_RATE_HZ(x) | AXP813_V_I_ADC_RATE_HZ(x)) 40 45 41 46 #define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg) \ 42 47 { \ ··· 98 93 enum axp22x_adc_channel_i { 99 94 AXP22X_BATT_CHRG_I = 1, 100 95 AXP22X_BATT_DISCHRG_I, 96 + }; 97 + 98 + enum axp813_adc_channel_v { 99 + AXP813_TS_IN = 0, 100 + AXP813_GPIO0_V, 101 + AXP813_BATT_V, 101 102 }; 102 103 103 104 static struct iio_map axp20x_maps[] = { ··· 208 197 AXP20X_BATT_DISCHRG_I_H), 209 198 }; 210 199 200 + static const struct iio_chan_spec axp813_adc_channels[] = { 201 + { 202 + .type = IIO_TEMP, 203 + .address = AXP22X_PMIC_TEMP_H, 204 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 205 + BIT(IIO_CHAN_INFO_SCALE) | 206 + BIT(IIO_CHAN_INFO_OFFSET), 207 + .datasheet_name = "pmic_temp", 208 + }, 209 + AXP20X_ADC_CHANNEL(AXP813_GPIO0_V, "gpio0_v", IIO_VOLTAGE, 210 + AXP288_GP_ADC_H), 211 + AXP20X_ADC_CHANNEL(AXP813_BATT_V, "batt_v", IIO_VOLTAGE, 212 + AXP20X_BATT_V_H), 213 + AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT, 214 + AXP20X_BATT_CHRG_I_H), 215 + AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT, 216 + AXP20X_BATT_DISCHRG_I_H), 217 + }; 218 + 211 219 static int axp20x_adc_raw(struct iio_dev *indio_dev, 212 220 struct iio_chan_spec const *chan, int *val) 213 221 { ··· 273 243 return IIO_VAL_INT; 274 244 } 275 245 246 + static int axp813_adc_raw(struct iio_dev *indio_dev, 247 + struct iio_chan_spec const *chan, int *val) 248 + { 249 + struct axp20x_adc_iio *info = iio_priv(indio_dev); 250 + 251 + *val = axp20x_read_variable_width(info->regmap, chan->address, 12); 252 + if (*val < 0) 253 + return *val; 254 + 255 + return IIO_VAL_INT; 256 + } 257 + 276 258 static int axp20x_adc_scale_voltage(int channel, int *val, int *val2) 277 259 { 278 260 switch (channel) { ··· 308 266 case AXP20X_IPSOUT_V: 309 267 *val = 1; 310 268 *val2 = 400000; 269 + return IIO_VAL_INT_PLUS_MICRO; 270 + 271 + default: 272 + return -EINVAL; 273 + } 274 + } 275 + 276 + static int axp813_adc_scale_voltage(int channel, int *val, int *val2) 277 + { 278 + switch (channel) { 279 + case AXP813_GPIO0_V: 280 + *val = 0; 281 + *val2 = 800000; 282 + return IIO_VAL_INT_PLUS_MICRO; 283 + 284 + case AXP813_BATT_V: 285 + *val = 1; 286 + *val2 = 100000; 311 287 return IIO_VAL_INT_PLUS_MICRO; 312 288 313 289 default: ··· 392 332 *val = 0; 393 333 *val2 = 500000; 394 334 return IIO_VAL_INT_PLUS_MICRO; 335 + 336 + case IIO_TEMP: 337 + *val = 100; 338 + return IIO_VAL_INT; 339 + 340 + default: 341 + return -EINVAL; 342 + } 343 + } 344 + 345 + static int axp813_adc_scale(struct iio_chan_spec const *chan, int *val, 346 + int *val2) 347 + { 348 + switch (chan->type) { 349 + case IIO_VOLTAGE: 350 + return axp813_adc_scale_voltage(chan->channel, val, val2); 351 + 352 + case IIO_CURRENT: 353 + *val = 1; 354 + return IIO_VAL_INT; 395 355 396 356 case IIO_TEMP: 397 357 *val = 100; ··· 505 425 } 506 426 } 507 427 428 + static int axp813_read_raw(struct iio_dev *indio_dev, 429 + struct iio_chan_spec const *chan, int *val, 430 + int *val2, long mask) 431 + { 432 + switch (mask) { 433 + case IIO_CHAN_INFO_OFFSET: 434 + *val = -2667; 435 + return IIO_VAL_INT; 436 + 437 + case IIO_CHAN_INFO_SCALE: 438 + return axp813_adc_scale(chan, val, val2); 439 + 440 + case IIO_CHAN_INFO_RAW: 441 + return axp813_adc_raw(indio_dev, chan, val); 442 + 443 + default: 444 + return -EINVAL; 445 + } 446 + } 447 + 508 448 static int axp20x_write_raw(struct iio_dev *indio_dev, 509 449 struct iio_chan_spec const *chan, int val, int val2, 510 450 long mask) ··· 570 470 .read_raw = axp22x_read_raw, 571 471 }; 572 472 573 - static int axp20x_adc_rate(int rate) 473 + static const struct iio_info axp813_adc_iio_info = { 474 + .read_raw = axp813_read_raw, 475 + }; 476 + 477 + static int axp20x_adc_rate(struct axp20x_adc_iio *info, int rate) 574 478 { 575 - return AXP20X_ADC_RATE_HZ(rate); 479 + return regmap_update_bits(info->regmap, AXP20X_ADC_RATE, 480 + AXP20X_ADC_RATE_MASK, 481 + AXP20X_ADC_RATE_HZ(rate)); 576 482 } 577 483 578 - static int axp22x_adc_rate(int rate) 484 + static int axp22x_adc_rate(struct axp20x_adc_iio *info, int rate) 579 485 { 580 - return AXP22X_ADC_RATE_HZ(rate); 486 + return regmap_update_bits(info->regmap, AXP20X_ADC_RATE, 487 + AXP20X_ADC_RATE_MASK, 488 + AXP22X_ADC_RATE_HZ(rate)); 489 + } 490 + 491 + static int axp813_adc_rate(struct axp20x_adc_iio *info, int rate) 492 + { 493 + return regmap_update_bits(info->regmap, AXP813_ADC_RATE, 494 + AXP813_ADC_RATE_MASK, 495 + AXP813_ADC_RATE_HZ(rate)); 581 496 } 582 497 583 498 struct axp_data { ··· 600 485 int num_channels; 601 486 struct iio_chan_spec const *channels; 602 487 unsigned long adc_en1_mask; 603 - int (*adc_rate)(int rate); 488 + int (*adc_rate)(struct axp20x_adc_iio *info, 489 + int rate); 604 490 bool adc_en2; 605 491 struct iio_map *maps; 606 492 }; ··· 626 510 .maps = axp22x_maps, 627 511 }; 628 512 513 + static const struct axp_data axp813_data = { 514 + .iio_info = &axp813_adc_iio_info, 515 + .num_channels = ARRAY_SIZE(axp813_adc_channels), 516 + .channels = axp813_adc_channels, 517 + .adc_en1_mask = AXP22X_ADC_EN1_MASK, 518 + .adc_rate = axp813_adc_rate, 519 + .adc_en2 = false, 520 + .maps = axp22x_maps, 521 + }; 522 + 523 + static const struct of_device_id axp20x_adc_of_match[] = { 524 + { .compatible = "x-powers,axp209-adc", .data = (void *)&axp20x_data, }, 525 + { .compatible = "x-powers,axp221-adc", .data = (void *)&axp22x_data, }, 526 + { .compatible = "x-powers,axp813-adc", .data = (void *)&axp813_data, }, 527 + { /* sentinel */ } 528 + }; 529 + MODULE_DEVICE_TABLE(of, axp20x_adc_of_match); 530 + 629 531 static const struct platform_device_id axp20x_adc_id_match[] = { 630 532 { .name = "axp20x-adc", .driver_data = (kernel_ulong_t)&axp20x_data, }, 631 533 { .name = "axp22x-adc", .driver_data = (kernel_ulong_t)&axp22x_data, }, 534 + { .name = "axp813-adc", .driver_data = (kernel_ulong_t)&axp813_data, }, 632 535 { /* sentinel */ }, 633 536 }; 634 537 MODULE_DEVICE_TABLE(platform, axp20x_adc_id_match); ··· 673 538 indio_dev->dev.of_node = pdev->dev.of_node; 674 539 indio_dev->modes = INDIO_DIRECT_MODE; 675 540 676 - info->data = (struct axp_data *)platform_get_device_id(pdev)->driver_data; 541 + if (!pdev->dev.of_node) { 542 + const struct platform_device_id *id; 543 + 544 + id = platform_get_device_id(pdev); 545 + info->data = (struct axp_data *)id->driver_data; 546 + } else { 547 + struct device *dev = &pdev->dev; 548 + 549 + info->data = (struct axp_data *)of_device_get_match_data(dev); 550 + } 677 551 678 552 indio_dev->name = platform_get_device_id(pdev)->name; 679 553 indio_dev->info = info->data->iio_info; ··· 698 554 AXP20X_ADC_EN2_MASK, AXP20X_ADC_EN2_MASK); 699 555 700 556 /* Configure ADCs rate */ 701 - regmap_update_bits(info->regmap, AXP20X_ADC_RATE, AXP20X_ADC_RATE_MASK, 702 - info->data->adc_rate(100)); 557 + info->data->adc_rate(info, 100); 703 558 704 559 ret = iio_map_array_register(indio_dev, info->data->maps); 705 560 if (ret < 0) { ··· 745 602 static struct platform_driver axp20x_adc_driver = { 746 603 .driver = { 747 604 .name = "axp20x-adc", 605 + .of_match_table = of_match_ptr(axp20x_adc_of_match), 748 606 }, 749 607 .id_table = axp20x_adc_id_match, 750 608 .probe = axp20x_probe,
-4
drivers/iio/adc/ep93xx_adc.c
··· 167 167 priv = iio_priv(iiodev); 168 168 169 169 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 170 - if (!res) { 171 - dev_err(&pdev->dev, "Cannot obtain memory resource\n"); 172 - return -ENXIO; 173 - } 174 170 priv->base = devm_ioremap_resource(&pdev->dev, res); 175 171 if (IS_ERR(priv->base)) { 176 172 dev_err(&pdev->dev, "Cannot map memory resource\n");
+4 -12
drivers/iio/adc/ti-adc161s626.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * ti-adc161s626.c - Texas Instruments ADC161S626 1-channel differential ADC 3 4 * ··· 6 5 * adc141s626 - 14-bit ADC 7 6 * adc161s626 - 16-bit ADC 8 7 * 9 - * Copyright (C) 2016 Matt Ranostay <mranostay@gmail.com> 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of the GNU General Public License as published by 13 - * the Free Software Foundation; either version 2 of the License, or 14 - * (at your option) any later version. 15 - * 16 - * This program is distributed in the hope that it will be useful, 17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 - * GNU General Public License for more details. 8 + * Copyright (C) 2016-2018 9 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 20 10 */ 21 11 22 12 #include <linux/module.h> ··· 267 275 }; 268 276 module_spi_driver(ti_adc_driver); 269 277 270 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 278 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 271 279 MODULE_DESCRIPTION("Texas Instruments ADC1x1S 1-channel differential ADC"); 272 280 MODULE_LICENSE("GPL");
+4 -13
drivers/iio/chemical/ams-iaq-core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * ams-iaq-core.c - Support for AMS iAQ-Core VOC sensors 3 4 * 4 - * Copyright (C) 2015 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 5 + * Copyright (C) 2015, 2018 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 16 7 */ 17 8 18 9 #include <linux/module.h> ··· 185 194 }; 186 195 module_i2c_driver(ams_iaqcore_driver); 187 196 188 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 197 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 189 198 MODULE_DESCRIPTION("AMS iAQ-Core VOC sensors"); 190 199 MODULE_LICENSE("GPL v2");
+4 -12
drivers/iio/chemical/atlas-ph-sensor.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * atlas-ph-sensor.c - Support for Atlas Scientific OEM pH-SM sensor 3 4 * 4 - * Copyright (C) 2015 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 5 + * Copyright (C) 2015-2018 Matt Ranostay 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 15 7 */ 16 8 17 9 #include <linux/module.h> ··· 681 689 }; 682 690 module_i2c_driver(atlas_driver); 683 691 684 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 692 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 685 693 MODULE_DESCRIPTION("Atlas Scientific pH-SM sensor"); 686 694 MODULE_LICENSE("GPL");
+2 -2
drivers/iio/chemical/ccs811.c
··· 32 32 #define CCS811_ALG_RESULT_DATA 0x02 33 33 #define CCS811_RAW_DATA 0x03 34 34 #define CCS811_HW_ID 0x20 35 - #define CCS881_HW_ID_VALUE 0x81 35 + #define CCS811_HW_ID_VALUE 0x81 36 36 #define CCS811_HW_VERSION 0x21 37 37 #define CCS811_HW_VERSION_VALUE 0x10 38 38 #define CCS811_HW_VERSION_MASK 0xF0 ··· 353 353 if (ret < 0) 354 354 return ret; 355 355 356 - if (ret != CCS881_HW_ID_VALUE) { 356 + if (ret != CCS811_HW_ID_VALUE) { 357 357 dev_err(&client->dev, "hardware id doesn't match CCS81x\n"); 358 358 return -ENODEV; 359 359 }
+4 -13
drivers/iio/chemical/vz89x.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * vz89x.c - Support for SGX Sensortech MiCS VZ89X VOC sensors 3 4 * 4 - * Copyright (C) 2015 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 5 + * Copyright (C) 2015-2018 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 16 7 */ 17 8 18 9 #include <linux/module.h> ··· 410 419 }; 411 420 module_i2c_driver(vz89x_driver); 412 421 413 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 422 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 414 423 MODULE_DESCRIPTION("SGX Sensortech MiCS VZ89X VOC sensors"); 415 424 MODULE_LICENSE("GPL v2");
+4 -12
drivers/iio/health/max30100.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * max30100.c - Support for MAX30100 heart rate and pulse oximeter sensor 3 4 * 4 - * Copyright (C) 2015 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 5 + * Copyright (C) 2015, 2018 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 15 7 * 16 8 * TODO: enable pulse length controls via device tree properties 17 9 */ ··· 510 518 }; 511 519 module_i2c_driver(max30100_driver); 512 520 513 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 521 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 514 522 MODULE_DESCRIPTION("MAX30100 heart rate and pulse oximeter sensor"); 515 523 MODULE_LICENSE("GPL");
+2
drivers/iio/humidity/Kconfig
··· 68 68 config HTS221_I2C 69 69 tristate 70 70 depends on HTS221 71 + select REGMAP_I2C 71 72 72 73 config HTS221_SPI 73 74 tristate 74 75 depends on HTS221 76 + select REGMAP_SPI 75 77 76 78 config HTU21 77 79 tristate "Measurement Specialties HTU21 humidity & temperature sensor"
+1 -1
drivers/iio/humidity/dht11.c
··· 159 159 } 160 160 161 161 dht11->timestamp = ktime_get_boot_ns(); 162 - if (hum_int < 20) { /* DHT22 */ 162 + if (hum_int < 4) { /* DHT22: 100000 = (3*256+232)*100 */ 163 163 dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) * 164 164 ((temp_int & 0x80) ? -100 : 100); 165 165 dht11->humidity = ((hum_int << 8) + hum_dec) * 100;
+4 -12
drivers/iio/humidity/hdc100x.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * hdc100x.c - Support for the TI HDC100x temperature + humidity sensors 3 4 * 4 - * Copyright (C) 2015 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 5 + * Copyright (C) 2015, 2018 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 15 7 * 16 8 * Datasheets: 17 9 * http://www.ti.com/product/HDC1000/datasheet ··· 441 449 }; 442 450 module_i2c_driver(hdc100x_driver); 443 451 444 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 452 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 445 453 MODULE_DESCRIPTION("TI HDC100x humidity and temperature sensor driver"); 446 454 MODULE_LICENSE("GPL");
+2 -19
drivers/iio/humidity/hts221.h
··· 15 15 16 16 #include <linux/iio/iio.h> 17 17 18 - #define HTS221_RX_MAX_LENGTH 8 19 - #define HTS221_TX_MAX_LENGTH 8 20 - 21 18 #define HTS221_DATA_SIZE 2 22 - 23 - struct hts221_transfer_buffer { 24 - u8 rx_buf[HTS221_RX_MAX_LENGTH]; 25 - u8 tx_buf[HTS221_TX_MAX_LENGTH] ____cacheline_aligned; 26 - }; 27 - 28 - struct hts221_transfer_function { 29 - int (*read)(struct device *dev, u8 addr, int len, u8 *data); 30 - int (*write)(struct device *dev, u8 addr, int len, u8 *data); 31 - }; 32 19 33 20 enum hts221_sensor_type { 34 21 HTS221_SENSOR_H, ··· 31 44 struct hts221_hw { 32 45 const char *name; 33 46 struct device *dev; 47 + struct regmap *regmap; 34 48 35 - struct mutex lock; 36 49 struct iio_trigger *trig; 37 50 int irq; 38 51 ··· 40 53 41 54 bool enabled; 42 55 u8 odr; 43 - 44 - const struct hts221_transfer_function *tf; 45 - struct hts221_transfer_buffer tb; 46 56 }; 47 57 48 58 extern const struct dev_pm_ops hts221_pm_ops; 49 59 50 - int hts221_write_with_mask(struct hts221_hw *hw, u8 addr, u8 mask, u8 val); 51 60 int hts221_probe(struct device *dev, int irq, const char *name, 52 - const struct hts221_transfer_function *tf_ops); 61 + struct regmap *regmap); 53 62 int hts221_set_enable(struct hts221_hw *hw, bool enable); 54 63 int hts221_allocate_buffers(struct hts221_hw *hw); 55 64 int hts221_allocate_trigger(struct hts221_hw *hw);
+20 -19
drivers/iio/humidity/hts221_buffer.c
··· 12 12 #include <linux/device.h> 13 13 #include <linux/interrupt.h> 14 14 #include <linux/irqreturn.h> 15 + #include <linux/regmap.h> 16 + #include <linux/bitfield.h> 15 17 16 18 #include <linux/iio/iio.h> 17 19 #include <linux/iio/trigger.h> ··· 40 38 { 41 39 struct iio_dev *iio_dev = iio_trigger_get_drvdata(trig); 42 40 struct hts221_hw *hw = iio_priv(iio_dev); 43 - int err; 44 41 45 - err = hts221_write_with_mask(hw, HTS221_REG_DRDY_EN_ADDR, 46 - HTS221_REG_DRDY_EN_MASK, state); 47 - 48 - return err < 0 ? err : 0; 42 + return regmap_update_bits(hw->regmap, HTS221_REG_DRDY_EN_ADDR, 43 + HTS221_REG_DRDY_EN_MASK, 44 + FIELD_PREP(HTS221_REG_DRDY_EN_MASK, state)); 49 45 } 50 46 51 47 static const struct iio_trigger_ops hts221_trigger_ops = { ··· 53 53 static irqreturn_t hts221_trigger_handler_thread(int irq, void *private) 54 54 { 55 55 struct hts221_hw *hw = private; 56 - u8 status; 57 - int err; 56 + int err, status; 58 57 59 - err = hw->tf->read(hw->dev, HTS221_REG_STATUS_ADDR, sizeof(status), 60 - &status); 58 + err = regmap_read(hw->regmap, HTS221_REG_STATUS_ADDR, &status); 61 59 if (err < 0) 62 60 return IRQ_HANDLED; 63 61 64 - /* 62 + /* 65 63 * H_DA bit (humidity data available) is routed to DRDY line. 66 64 * Humidity sample is computed after temperature one. 67 65 * Here we can assume data channels are both available if H_DA bit ··· 100 102 break; 101 103 } 102 104 103 - err = hts221_write_with_mask(hw, HTS221_REG_DRDY_HL_ADDR, 104 - HTS221_REG_DRDY_HL_MASK, irq_active_low); 105 + err = regmap_update_bits(hw->regmap, HTS221_REG_DRDY_HL_ADDR, 106 + HTS221_REG_DRDY_HL_MASK, 107 + FIELD_PREP(HTS221_REG_DRDY_HL_MASK, 108 + irq_active_low)); 105 109 if (err < 0) 106 110 return err; 107 111 ··· 114 114 open_drain = true; 115 115 } 116 116 117 - err = hts221_write_with_mask(hw, HTS221_REG_DRDY_PP_OD_ADDR, 118 - HTS221_REG_DRDY_PP_OD_MASK, 119 - open_drain); 117 + err = regmap_update_bits(hw->regmap, HTS221_REG_DRDY_PP_OD_ADDR, 118 + HTS221_REG_DRDY_PP_OD_MASK, 119 + FIELD_PREP(HTS221_REG_DRDY_PP_OD_MASK, 120 + open_drain)); 120 121 if (err < 0) 121 122 return err; 122 123 ··· 172 171 173 172 /* humidity data */ 174 173 ch = &iio_dev->channels[HTS221_SENSOR_H]; 175 - err = hw->tf->read(hw->dev, ch->address, HTS221_DATA_SIZE, 176 - buffer); 174 + err = regmap_bulk_read(hw->regmap, ch->address, 175 + buffer, HTS221_DATA_SIZE); 177 176 if (err < 0) 178 177 goto out; 179 178 180 179 /* temperature data */ 181 180 ch = &iio_dev->channels[HTS221_SENSOR_T]; 182 - err = hw->tf->read(hw->dev, ch->address, HTS221_DATA_SIZE, 183 - buffer + HTS221_DATA_SIZE); 181 + err = regmap_bulk_read(hw->regmap, ch->address, 182 + buffer + HTS221_DATA_SIZE, HTS221_DATA_SIZE); 184 183 if (err < 0) 185 184 goto out; 186 185
+52 -80
drivers/iio/humidity/hts221_core.c
··· 14 14 #include <linux/iio/sysfs.h> 15 15 #include <linux/delay.h> 16 16 #include <linux/pm.h> 17 - #include <asm/unaligned.h> 17 + #include <linux/regmap.h> 18 + #include <linux/bitfield.h> 18 19 19 20 #include "hts221.h" 20 21 ··· 132 131 IIO_CHAN_SOFT_TIMESTAMP(2), 133 132 }; 134 133 135 - int hts221_write_with_mask(struct hts221_hw *hw, u8 addr, u8 mask, u8 val) 136 - { 137 - u8 data; 138 - int err; 139 - 140 - mutex_lock(&hw->lock); 141 - 142 - err = hw->tf->read(hw->dev, addr, sizeof(data), &data); 143 - if (err < 0) { 144 - dev_err(hw->dev, "failed to read %02x register\n", addr); 145 - goto unlock; 146 - } 147 - 148 - data = (data & ~mask) | ((val << __ffs(mask)) & mask); 149 - 150 - err = hw->tf->write(hw->dev, addr, sizeof(data), &data); 151 - if (err < 0) 152 - dev_err(hw->dev, "failed to write %02x register\n", addr); 153 - 154 - unlock: 155 - mutex_unlock(&hw->lock); 156 - 157 - return err; 158 - } 159 - 160 134 static int hts221_check_whoami(struct hts221_hw *hw) 161 135 { 162 - u8 data; 163 - int err; 136 + int err, data; 164 137 165 - err = hw->tf->read(hw->dev, HTS221_REG_WHOAMI_ADDR, sizeof(data), 166 - &data); 138 + err = regmap_read(hw->regmap, HTS221_REG_WHOAMI_ADDR, &data); 167 139 if (err < 0) { 168 140 dev_err(hw->dev, "failed to read whoami register\n"); 169 141 return err; ··· 162 188 if (i == ARRAY_SIZE(hts221_odr_table)) 163 189 return -EINVAL; 164 190 165 - err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR, 166 - HTS221_ODR_MASK, hts221_odr_table[i].val); 191 + err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR, 192 + HTS221_ODR_MASK, 193 + FIELD_PREP(HTS221_ODR_MASK, 194 + hts221_odr_table[i].val)); 167 195 if (err < 0) 168 196 return err; 169 197 ··· 178 202 enum hts221_sensor_type type, 179 203 u16 val) 180 204 { 181 - int i, err; 182 205 const struct hts221_avg *avg = &hts221_avg_list[type]; 206 + int i, err, data; 183 207 184 208 for (i = 0; i < HTS221_AVG_DEPTH; i++) 185 209 if (avg->avg_avl[i] == val) ··· 188 212 if (i == HTS221_AVG_DEPTH) 189 213 return -EINVAL; 190 214 191 - err = hts221_write_with_mask(hw, avg->addr, avg->mask, i); 215 + data = ((i << __ffs(avg->mask)) & avg->mask); 216 + err = regmap_update_bits(hw->regmap, avg->addr, 217 + avg->mask, data); 192 218 if (err < 0) 193 219 return err; 194 220 ··· 252 274 { 253 275 int err; 254 276 255 - err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR, 256 - HTS221_ENABLE_MASK, enable); 277 + err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR, 278 + HTS221_ENABLE_MASK, 279 + FIELD_PREP(HTS221_ENABLE_MASK, enable)); 257 280 if (err < 0) 258 281 return err; 259 282 ··· 265 286 266 287 static int hts221_parse_temp_caldata(struct hts221_hw *hw) 267 288 { 268 - int err, *slope, *b_gen; 289 + int err, *slope, *b_gen, cal0, cal1; 269 290 s16 cal_x0, cal_x1, cal_y0, cal_y1; 270 - u8 cal0, cal1; 291 + __le16 val; 271 292 272 - err = hw->tf->read(hw->dev, HTS221_REG_0T_CAL_Y_H, 273 - sizeof(cal0), &cal0); 293 + err = regmap_read(hw->regmap, HTS221_REG_0T_CAL_Y_H, &cal0); 274 294 if (err < 0) 275 295 return err; 276 296 277 - err = hw->tf->read(hw->dev, HTS221_REG_T1_T0_CAL_Y_H, 278 - sizeof(cal1), &cal1); 297 + err = regmap_read(hw->regmap, HTS221_REG_T1_T0_CAL_Y_H, &cal1); 279 298 if (err < 0) 280 299 return err; 281 - cal_y0 = (le16_to_cpu(cal1 & 0x3) << 8) | cal0; 300 + cal_y0 = ((cal1 & 0x3) << 8) | cal0; 282 301 283 - err = hw->tf->read(hw->dev, HTS221_REG_1T_CAL_Y_H, 284 - sizeof(cal0), &cal0); 302 + err = regmap_read(hw->regmap, HTS221_REG_1T_CAL_Y_H, &cal0); 285 303 if (err < 0) 286 304 return err; 287 305 cal_y1 = (((cal1 & 0xc) >> 2) << 8) | cal0; 288 306 289 - err = hw->tf->read(hw->dev, HTS221_REG_0T_CAL_X_L, sizeof(cal_x0), 290 - (u8 *)&cal_x0); 307 + err = regmap_bulk_read(hw->regmap, HTS221_REG_0T_CAL_X_L, 308 + &val, sizeof(val)); 291 309 if (err < 0) 292 310 return err; 293 - cal_x0 = le16_to_cpu(cal_x0); 311 + cal_x0 = le16_to_cpu(val); 294 312 295 - err = hw->tf->read(hw->dev, HTS221_REG_1T_CAL_X_L, sizeof(cal_x1), 296 - (u8 *)&cal_x1); 313 + err = regmap_bulk_read(hw->regmap, HTS221_REG_1T_CAL_X_L, 314 + &val, sizeof(val)); 297 315 if (err < 0) 298 316 return err; 299 - cal_x1 = le16_to_cpu(cal_x1); 317 + cal_x1 = le16_to_cpu(val); 300 318 301 319 slope = &hw->sensors[HTS221_SENSOR_T].slope; 302 320 b_gen = &hw->sensors[HTS221_SENSOR_T].b_gen; ··· 308 332 309 333 static int hts221_parse_rh_caldata(struct hts221_hw *hw) 310 334 { 311 - int err, *slope, *b_gen; 335 + int err, *slope, *b_gen, data; 312 336 s16 cal_x0, cal_x1, cal_y0, cal_y1; 313 - u8 data; 337 + __le16 val; 314 338 315 - err = hw->tf->read(hw->dev, HTS221_REG_0RH_CAL_Y_H, sizeof(data), 316 - &data); 339 + err = regmap_read(hw->regmap, HTS221_REG_0RH_CAL_Y_H, &data); 317 340 if (err < 0) 318 341 return err; 319 342 cal_y0 = data; 320 343 321 - err = hw->tf->read(hw->dev, HTS221_REG_1RH_CAL_Y_H, sizeof(data), 322 - &data); 344 + err = regmap_read(hw->regmap, HTS221_REG_1RH_CAL_Y_H, &data); 323 345 if (err < 0) 324 346 return err; 325 347 cal_y1 = data; 326 348 327 - err = hw->tf->read(hw->dev, HTS221_REG_0RH_CAL_X_H, sizeof(cal_x0), 328 - (u8 *)&cal_x0); 349 + err = regmap_bulk_read(hw->regmap, HTS221_REG_0RH_CAL_X_H, 350 + &val, sizeof(val)); 329 351 if (err < 0) 330 352 return err; 331 - cal_x0 = le16_to_cpu(cal_x0); 353 + cal_x0 = le16_to_cpu(val); 332 354 333 - err = hw->tf->read(hw->dev, HTS221_REG_1RH_CAL_X_H, sizeof(cal_x1), 334 - (u8 *)&cal_x1); 355 + err = regmap_bulk_read(hw->regmap, HTS221_REG_1RH_CAL_X_H, 356 + &val, sizeof(val)); 335 357 if (err < 0) 336 358 return err; 337 - cal_x1 = le16_to_cpu(cal_x1); 359 + cal_x1 = le16_to_cpu(val); 338 360 339 361 slope = &hw->sensors[HTS221_SENSOR_H].slope; 340 362 b_gen = &hw->sensors[HTS221_SENSOR_H].b_gen; ··· 405 431 406 432 static int hts221_read_oneshot(struct hts221_hw *hw, u8 addr, int *val) 407 433 { 408 - u8 data[HTS221_DATA_SIZE]; 434 + __le16 data; 409 435 int err; 410 436 411 437 err = hts221_set_enable(hw, true); ··· 414 440 415 441 msleep(50); 416 442 417 - err = hw->tf->read(hw->dev, addr, sizeof(data), data); 443 + err = regmap_bulk_read(hw->regmap, addr, &data, sizeof(data)); 418 444 if (err < 0) 419 445 return err; 420 446 421 447 hts221_set_enable(hw, false); 422 448 423 - *val = (s16)get_unaligned_le16(data); 449 + *val = (s16)le16_to_cpu(data); 424 450 425 451 return IIO_VAL_INT; 426 452 } ··· 556 582 static const unsigned long hts221_scan_masks[] = {0x3, 0x0}; 557 583 558 584 int hts221_probe(struct device *dev, int irq, const char *name, 559 - const struct hts221_transfer_function *tf_ops) 585 + struct regmap *regmap) 560 586 { 561 587 struct iio_dev *iio_dev; 562 588 struct hts221_hw *hw; ··· 573 599 hw->name = name; 574 600 hw->dev = dev; 575 601 hw->irq = irq; 576 - hw->tf = tf_ops; 577 - 578 - mutex_init(&hw->lock); 602 + hw->regmap = regmap; 579 603 580 604 err = hts221_check_whoami(hw); 581 605 if (err < 0) ··· 588 616 iio_dev->info = &hts221_info; 589 617 590 618 /* enable Block Data Update */ 591 - err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR, 592 - HTS221_BDU_MASK, 1); 619 + err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR, 620 + HTS221_BDU_MASK, 621 + FIELD_PREP(HTS221_BDU_MASK, 1)); 593 622 if (err < 0) 594 623 return err; 595 624 ··· 646 673 { 647 674 struct iio_dev *iio_dev = dev_get_drvdata(dev); 648 675 struct hts221_hw *hw = iio_priv(iio_dev); 649 - int err; 650 676 651 - err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR, 652 - HTS221_ENABLE_MASK, false); 653 - 654 - return err < 0 ? err : 0; 677 + return regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR, 678 + HTS221_ENABLE_MASK, 679 + FIELD_PREP(HTS221_ENABLE_MASK, false)); 655 680 } 656 681 657 682 static int __maybe_unused hts221_resume(struct device *dev) ··· 659 688 int err = 0; 660 689 661 690 if (hw->enabled) 662 - err = hts221_write_with_mask(hw, HTS221_REG_CNTRL1_ADDR, 663 - HTS221_ENABLE_MASK, true); 664 - 691 + err = regmap_update_bits(hw->regmap, HTS221_REG_CNTRL1_ADDR, 692 + HTS221_ENABLE_MASK, 693 + FIELD_PREP(HTS221_ENABLE_MASK, 694 + true)); 665 695 return err; 666 696 } 667 697
+18 -46
drivers/iio/humidity/hts221_i2c.c
··· 13 13 #include <linux/acpi.h> 14 14 #include <linux/i2c.h> 15 15 #include <linux/slab.h> 16 + #include <linux/regmap.h> 17 + 16 18 #include "hts221.h" 17 19 18 - #define I2C_AUTO_INCREMENT 0x80 20 + #define HTS221_I2C_AUTO_INCREMENT BIT(7) 19 21 20 - static int hts221_i2c_read(struct device *dev, u8 addr, int len, u8 *data) 21 - { 22 - struct i2c_msg msg[2]; 23 - struct i2c_client *client = to_i2c_client(dev); 24 - 25 - if (len > 1) 26 - addr |= I2C_AUTO_INCREMENT; 27 - 28 - msg[0].addr = client->addr; 29 - msg[0].flags = client->flags; 30 - msg[0].len = 1; 31 - msg[0].buf = &addr; 32 - 33 - msg[1].addr = client->addr; 34 - msg[1].flags = client->flags | I2C_M_RD; 35 - msg[1].len = len; 36 - msg[1].buf = data; 37 - 38 - return i2c_transfer(client->adapter, msg, 2); 39 - } 40 - 41 - static int hts221_i2c_write(struct device *dev, u8 addr, int len, u8 *data) 42 - { 43 - u8 send[len + 1]; 44 - struct i2c_msg msg; 45 - struct i2c_client *client = to_i2c_client(dev); 46 - 47 - if (len > 1) 48 - addr |= I2C_AUTO_INCREMENT; 49 - 50 - send[0] = addr; 51 - memcpy(&send[1], data, len * sizeof(u8)); 52 - 53 - msg.addr = client->addr; 54 - msg.flags = client->flags; 55 - msg.len = len + 1; 56 - msg.buf = send; 57 - 58 - return i2c_transfer(client->adapter, &msg, 1); 59 - } 60 - 61 - static const struct hts221_transfer_function hts221_transfer_fn = { 62 - .read = hts221_i2c_read, 63 - .write = hts221_i2c_write, 22 + static const struct regmap_config hts221_i2c_regmap_config = { 23 + .reg_bits = 8, 24 + .val_bits = 8, 25 + .write_flag_mask = HTS221_I2C_AUTO_INCREMENT, 26 + .read_flag_mask = HTS221_I2C_AUTO_INCREMENT, 64 27 }; 65 28 66 29 static int hts221_i2c_probe(struct i2c_client *client, 67 30 const struct i2c_device_id *id) 68 31 { 32 + struct regmap *regmap; 33 + 34 + regmap = devm_regmap_init_i2c(client, &hts221_i2c_regmap_config); 35 + if (IS_ERR(regmap)) { 36 + dev_err(&client->dev, "Failed to register i2c regmap %d\n", 37 + (int)PTR_ERR(regmap)); 38 + return PTR_ERR(regmap); 39 + } 40 + 69 41 return hts221_probe(&client->dev, client->irq, 70 - client->name, &hts221_transfer_fn); 42 + client->name, regmap); 71 43 } 72 44 73 45 static const struct acpi_device_id hts221_acpi_match[] = {
+19 -62
drivers/iio/humidity/hts221_spi.c
··· 12 12 #include <linux/module.h> 13 13 #include <linux/spi/spi.h> 14 14 #include <linux/slab.h> 15 + #include <linux/regmap.h> 16 + 15 17 #include "hts221.h" 16 18 17 - #define SENSORS_SPI_READ 0x80 18 - #define SPI_AUTO_INCREMENT 0x40 19 + #define HTS221_SPI_READ BIT(7) 20 + #define HTS221_SPI_AUTO_INCREMENT BIT(6) 19 21 20 - static int hts221_spi_read(struct device *dev, u8 addr, int len, u8 *data) 21 - { 22 - int err; 23 - struct spi_device *spi = to_spi_device(dev); 24 - struct iio_dev *iio_dev = spi_get_drvdata(spi); 25 - struct hts221_hw *hw = iio_priv(iio_dev); 26 - 27 - struct spi_transfer xfers[] = { 28 - { 29 - .tx_buf = hw->tb.tx_buf, 30 - .bits_per_word = 8, 31 - .len = 1, 32 - }, 33 - { 34 - .rx_buf = hw->tb.rx_buf, 35 - .bits_per_word = 8, 36 - .len = len, 37 - } 38 - }; 39 - 40 - if (len > 1) 41 - addr |= SPI_AUTO_INCREMENT; 42 - hw->tb.tx_buf[0] = addr | SENSORS_SPI_READ; 43 - 44 - err = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers)); 45 - if (err < 0) 46 - return err; 47 - 48 - memcpy(data, hw->tb.rx_buf, len * sizeof(u8)); 49 - 50 - return len; 51 - } 52 - 53 - static int hts221_spi_write(struct device *dev, u8 addr, int len, u8 *data) 54 - { 55 - struct spi_device *spi = to_spi_device(dev); 56 - struct iio_dev *iio_dev = spi_get_drvdata(spi); 57 - struct hts221_hw *hw = iio_priv(iio_dev); 58 - 59 - struct spi_transfer xfers = { 60 - .tx_buf = hw->tb.tx_buf, 61 - .bits_per_word = 8, 62 - .len = len + 1, 63 - }; 64 - 65 - if (len >= HTS221_TX_MAX_LENGTH) 66 - return -ENOMEM; 67 - 68 - if (len > 1) 69 - addr |= SPI_AUTO_INCREMENT; 70 - hw->tb.tx_buf[0] = addr; 71 - memcpy(&hw->tb.tx_buf[1], data, len); 72 - 73 - return spi_sync_transfer(spi, &xfers, 1); 74 - } 75 - 76 - static const struct hts221_transfer_function hts221_transfer_fn = { 77 - .read = hts221_spi_read, 78 - .write = hts221_spi_write, 22 + static const struct regmap_config hts221_spi_regmap_config = { 23 + .reg_bits = 8, 24 + .val_bits = 8, 25 + .write_flag_mask = HTS221_SPI_AUTO_INCREMENT, 26 + .read_flag_mask = HTS221_SPI_READ | HTS221_SPI_AUTO_INCREMENT, 79 27 }; 80 28 81 29 static int hts221_spi_probe(struct spi_device *spi) 82 30 { 31 + struct regmap *regmap; 32 + 33 + regmap = devm_regmap_init_spi(spi, &hts221_spi_regmap_config); 34 + if (IS_ERR(regmap)) { 35 + dev_err(&spi->dev, "Failed to register spi regmap %d\n", 36 + (int)PTR_ERR(regmap)); 37 + return PTR_ERR(regmap); 38 + } 39 + 83 40 return hts221_probe(&spi->dev, spi->irq, 84 - spi->modalias, &hts221_transfer_fn); 41 + spi->modalias, regmap); 85 42 } 86 43 87 44 static const struct of_device_id hts221_spi_of_match[] = {
+22 -7
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
··· 27 27 ST_LSM6DSX_MAX_ID, 28 28 }; 29 29 30 - #define ST_LSM6DSX_BUFF_SIZE 256 30 + #define ST_LSM6DSX_BUFF_SIZE 400 31 31 #define ST_LSM6DSX_CHAN_SIZE 2 32 32 #define ST_LSM6DSX_SAMPLE_SIZE 6 33 33 #define ST_LSM6DSX_MAX_WORD_LEN ((32 / ST_LSM6DSX_SAMPLE_SIZE) * \ ··· 58 58 }; 59 59 60 60 /** 61 + * struct st_lsm6dsx_hw_ts_settings - ST IMU hw timer settings 62 + * @timer_en: Hw timer enable register info (addr + mask). 63 + * @hr_timer: Hw timer resolution register info (addr + mask). 64 + * @fifo_en: Hw timer FIFO enable register info (addr + mask). 65 + * @decimator: Hw timer FIFO decimator register info (addr + mask). 66 + */ 67 + struct st_lsm6dsx_hw_ts_settings { 68 + struct st_lsm6dsx_reg timer_en; 69 + struct st_lsm6dsx_reg hr_timer; 70 + struct st_lsm6dsx_reg fifo_en; 71 + struct st_lsm6dsx_reg decimator; 72 + }; 73 + 74 + /** 61 75 * struct st_lsm6dsx_settings - ST IMU sensor settings 62 76 * @wai: Sensor WhoAmI default value. 63 77 * @max_fifo_size: Sensor max fifo length in FIFO words. 64 78 * @id: List of hw id supported by the driver configuration. 65 79 * @decimator: List of decimator register info (addr + mask). 66 80 * @fifo_ops: Sensor hw FIFO parameters. 81 + * @ts_settings: Hw timer related settings. 67 82 */ 68 83 struct st_lsm6dsx_settings { 69 84 u8 wai; ··· 86 71 enum st_lsm6dsx_hw_id id[ST_LSM6DSX_MAX_ID]; 87 72 struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID]; 88 73 struct st_lsm6dsx_fifo_ops fifo_ops; 74 + struct st_lsm6dsx_hw_ts_settings ts_settings; 89 75 }; 90 76 91 77 enum st_lsm6dsx_sensor_id { ··· 110 94 * @watermark: Sensor watermark level. 111 95 * @sip: Number of samples in a given pattern. 112 96 * @decimator: FIFO decimation factor. 113 - * @delta_ts: Delta time between two consecutive interrupts. 114 - * @ts: Latest timestamp from the interrupt handler. 97 + * @ts_ref: Sensor timestamp reference for hw one. 115 98 */ 116 99 struct st_lsm6dsx_sensor { 117 100 char name[32]; ··· 123 108 u16 watermark; 124 109 u8 sip; 125 110 u8 decimator; 126 - 127 - s64 delta_ts; 128 - s64 ts; 111 + s64 ts_ref; 129 112 }; 130 113 131 114 /** ··· 135 122 * @conf_lock: Mutex to prevent concurrent FIFO configuration update. 136 123 * @fifo_mode: FIFO operating mode supported by the device. 137 124 * @enable_mask: Enabled sensor bitmask. 138 - * @sip: Total number of samples (acc/gyro) in a given pattern. 125 + * @ts_sip: Total number of timestamp samples in a given pattern. 126 + * @sip: Total number of samples (acc/gyro/ts) in a given pattern. 139 127 * @buff: Device read buffer. 140 128 * @iio_devs: Pointers to acc/gyro iio_dev instances. 141 129 * @settings: Pointer to the specific sensor settings in use. ··· 151 137 152 138 enum st_lsm6dsx_fifo_mode fifo_mode; 153 139 u8 enable_mask; 140 + u8 ts_sip; 154 141 u8 sip; 155 142 156 143 u8 *buff;
+102 -59
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
··· 46 46 #define ST_LSM6DSX_FIFO_ODR_MASK GENMASK(6, 3) 47 47 #define ST_LSM6DSX_FIFO_EMPTY_MASK BIT(12) 48 48 #define ST_LSM6DSX_REG_FIFO_OUTL_ADDR 0x3e 49 + #define ST_LSM6DSX_REG_TS_RESET_ADDR 0x42 49 50 50 51 #define ST_LSM6DSX_MAX_FIFO_ODR_VAL 0x08 52 + 53 + #define ST_LSM6DSX_TS_SENSITIVITY 25000UL /* 25us */ 54 + #define ST_LSM6DSX_TS_RESET_VAL 0xaa 51 55 52 56 struct st_lsm6dsx_decimator_entry { 53 57 u8 decimator; ··· 102 98 103 99 static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) 104 100 { 101 + u16 max_odr, min_odr, sip = 0, ts_sip = 0; 102 + const struct st_lsm6dsx_reg *ts_dec_reg; 105 103 struct st_lsm6dsx_sensor *sensor; 106 - u16 max_odr, min_odr, sip = 0; 107 - int err, i; 104 + int err = 0, i; 108 105 u8 data; 109 106 110 107 st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr); ··· 124 119 sensor->decimator = 0; 125 120 data = 0; 126 121 } 122 + ts_sip = max_t(u16, ts_sip, sensor->sip); 127 123 128 124 dec_reg = &hw->settings->decimator[sensor->id]; 129 125 if (dec_reg->addr) { ··· 137 131 } 138 132 sip += sensor->sip; 139 133 } 140 - hw->sip = sip; 134 + hw->sip = sip + ts_sip; 135 + hw->ts_sip = ts_sip; 141 136 142 - return 0; 137 + /* 138 + * update hw ts decimator if necessary. Decimator for hw timestamp 139 + * is always 1 or 0 in order to have a ts sample for each data 140 + * sample in FIFO 141 + */ 142 + ts_dec_reg = &hw->settings->ts_settings.decimator; 143 + if (ts_dec_reg->addr) { 144 + int val, ts_dec = !!hw->ts_sip; 145 + 146 + val = ST_LSM6DSX_SHIFT_VAL(ts_dec, ts_dec_reg->mask); 147 + err = regmap_update_bits(hw->regmap, ts_dec_reg->addr, 148 + ts_dec_reg->mask, val); 149 + } 150 + return err; 143 151 } 144 152 145 153 int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, ··· 228 208 &wdata, sizeof(wdata)); 229 209 } 230 210 211 + static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw) 212 + { 213 + struct st_lsm6dsx_sensor *sensor; 214 + int i, err; 215 + 216 + /* reset hw ts counter */ 217 + err = regmap_write(hw->regmap, ST_LSM6DSX_REG_TS_RESET_ADDR, 218 + ST_LSM6DSX_TS_RESET_VAL); 219 + if (err < 0) 220 + return err; 221 + 222 + for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 223 + sensor = iio_priv(hw->iio_devs[i]); 224 + /* 225 + * store enable buffer timestamp as reference for 226 + * hw timestamp 227 + */ 228 + sensor->ts_ref = iio_get_time_ns(hw->iio_devs[i]); 229 + } 230 + return 0; 231 + } 232 + 231 233 /* 232 234 * Set max bulk read to ST_LSM6DSX_MAX_WORD_LEN in order to avoid 233 235 * a kmalloc for each bus access ··· 273 231 return 0; 274 232 } 275 233 234 + #define ST_LSM6DSX_IIO_BUFF_SIZE (ALIGN(ST_LSM6DSX_SAMPLE_SIZE, \ 235 + sizeof(s64)) + sizeof(s64)) 276 236 /** 277 237 * st_lsm6dsx_read_fifo() - LSM6DS3-LSM6DS3H-LSM6DSL-LSM6DSM read FIFO routine 278 238 * @hw: Pointer to instance of struct st_lsm6dsx_hw. ··· 287 243 { 288 244 u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; 289 245 u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; 290 - int err, acc_sip, gyro_sip, read_len, samples, offset; 246 + int err, acc_sip, gyro_sip, ts_sip, read_len, offset; 291 247 struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor; 292 - s64 acc_ts, acc_delta_ts, gyro_ts, gyro_delta_ts; 293 - u8 iio_buff[ALIGN(ST_LSM6DSX_SAMPLE_SIZE, sizeof(s64)) + sizeof(s64)]; 248 + u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; 249 + u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; 250 + bool reset_ts = false; 294 251 __le16 fifo_status; 252 + s64 ts = 0; 295 253 296 254 err = regmap_bulk_read(hw->regmap, 297 255 hw->settings->fifo_ops.fifo_diff.addr, ··· 306 260 307 261 fifo_len = (le16_to_cpu(fifo_status) & fifo_diff_mask) * 308 262 ST_LSM6DSX_CHAN_SIZE; 309 - samples = fifo_len / ST_LSM6DSX_SAMPLE_SIZE; 310 263 fifo_len = (fifo_len / pattern_len) * pattern_len; 311 264 312 - /* 313 - * compute delta timestamp between two consecutive samples 314 - * in order to estimate queueing time of data generated 315 - * by the sensor 316 - */ 317 265 acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 318 - acc_ts = acc_sensor->ts - acc_sensor->delta_ts; 319 - acc_delta_ts = div_s64(acc_sensor->delta_ts * acc_sensor->decimator, 320 - samples); 321 - 322 266 gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]); 323 - gyro_ts = gyro_sensor->ts - gyro_sensor->delta_ts; 324 - gyro_delta_ts = div_s64(gyro_sensor->delta_ts * gyro_sensor->decimator, 325 - samples); 326 267 327 268 for (read_len = 0; read_len < fifo_len; read_len += pattern_len) { 328 269 err = st_lsm6dsx_read_block(hw, hw->buff, pattern_len); ··· 320 287 * Data are written to the FIFO with a specific pattern 321 288 * depending on the configured ODRs. The first sequence of data 322 289 * stored in FIFO contains the data of all enabled sensors 323 - * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated 290 + * (e.g. Gx, Gy, Gz, Ax, Ay, Az, Ts), then data are repeated 324 291 * depending on the value of the decimation factor set for each 325 292 * sensor. 326 293 * ··· 329 296 * - gyroscope ODR = 208Hz, accelerometer ODR = 104Hz 330 297 * Since the gyroscope ODR is twice the accelerometer one, the 331 298 * following pattern is repeated every 9 samples: 332 - * - Gx, Gy, Gz, Ax, Ay, Az, Gx, Gy, Gz 299 + * - Gx, Gy, Gz, Ax, Ay, Az, Ts, Gx, Gy, Gz, Ts, Gx, .. 333 300 */ 334 301 gyro_sip = gyro_sensor->sip; 335 302 acc_sip = acc_sensor->sip; 303 + ts_sip = hw->ts_sip; 336 304 offset = 0; 337 305 338 306 while (acc_sip > 0 || gyro_sip > 0) { 339 - if (gyro_sip-- > 0) { 340 - memcpy(iio_buff, &hw->buff[offset], 307 + if (gyro_sip > 0) { 308 + memcpy(gyro_buff, &hw->buff[offset], 341 309 ST_LSM6DSX_SAMPLE_SIZE); 342 - iio_push_to_buffers_with_timestamp( 343 - hw->iio_devs[ST_LSM6DSX_ID_GYRO], 344 - iio_buff, gyro_ts); 345 310 offset += ST_LSM6DSX_SAMPLE_SIZE; 346 - gyro_ts += gyro_delta_ts; 311 + } 312 + if (acc_sip > 0) { 313 + memcpy(acc_buff, &hw->buff[offset], 314 + ST_LSM6DSX_SAMPLE_SIZE); 315 + offset += ST_LSM6DSX_SAMPLE_SIZE; 347 316 } 348 317 349 - if (acc_sip-- > 0) { 350 - memcpy(iio_buff, &hw->buff[offset], 351 - ST_LSM6DSX_SAMPLE_SIZE); 318 + if (ts_sip-- > 0) { 319 + u8 data[ST_LSM6DSX_SAMPLE_SIZE]; 320 + 321 + memcpy(data, &hw->buff[offset], sizeof(data)); 322 + /* 323 + * hw timestamp is 3B long and it is stored 324 + * in FIFO using 6B as 4th FIFO data set 325 + * according to this schema: 326 + * B0 = ts[15:8], B1 = ts[23:16], B3 = ts[7:0] 327 + */ 328 + ts = data[1] << 16 | data[0] << 8 | data[3]; 329 + /* 330 + * check if hw timestamp engine is going to 331 + * reset (the sensor generates an interrupt 332 + * to signal the hw timestamp will reset in 333 + * 1.638s) 334 + */ 335 + if (!reset_ts && ts >= 0xff0000) 336 + reset_ts = true; 337 + ts *= ST_LSM6DSX_TS_SENSITIVITY; 338 + 339 + offset += ST_LSM6DSX_SAMPLE_SIZE; 340 + } 341 + 342 + if (gyro_sip-- > 0) 343 + iio_push_to_buffers_with_timestamp( 344 + hw->iio_devs[ST_LSM6DSX_ID_GYRO], 345 + gyro_buff, gyro_sensor->ts_ref + ts); 346 + if (acc_sip-- > 0) 352 347 iio_push_to_buffers_with_timestamp( 353 348 hw->iio_devs[ST_LSM6DSX_ID_ACC], 354 - iio_buff, acc_ts); 355 - offset += ST_LSM6DSX_SAMPLE_SIZE; 356 - acc_ts += acc_delta_ts; 357 - } 349 + acc_buff, acc_sensor->ts_ref + ts); 358 350 } 359 351 } 360 352 353 + if (unlikely(reset_ts)) { 354 + err = st_lsm6dsx_reset_hw_ts(hw); 355 + if (err < 0) 356 + return err; 357 + } 361 358 return read_len; 362 359 } 363 360 ··· 442 379 goto out; 443 380 444 381 if (hw->enable_mask) { 445 - err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT); 382 + /* reset hw ts counter */ 383 + err = st_lsm6dsx_reset_hw_ts(hw); 446 384 if (err < 0) 447 385 goto out; 448 386 449 - /* 450 - * store enable buffer timestamp as reference to compute 451 - * first delta timestamp 452 - */ 453 - sensor->ts = iio_get_time_ns(iio_dev); 387 + err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT); 454 388 } 455 389 456 390 out: ··· 459 399 static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private) 460 400 { 461 401 struct st_lsm6dsx_hw *hw = private; 462 - struct st_lsm6dsx_sensor *sensor; 463 - int i; 464 402 465 - if (!hw->sip) 466 - return IRQ_NONE; 467 - 468 - for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 469 - sensor = iio_priv(hw->iio_devs[i]); 470 - 471 - if (sensor->sip > 0) { 472 - s64 timestamp; 473 - 474 - timestamp = iio_get_time_ns(hw->iio_devs[i]); 475 - sensor->delta_ts = timestamp - sensor->ts; 476 - sensor->ts = timestamp; 477 - } 478 - } 479 - 480 - return IRQ_WAKE_THREAD; 403 + return hw->sip > 0 ? IRQ_WAKE_THREAD : IRQ_NONE; 481 404 } 482 405 483 406 static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
+100 -4
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
··· 181 181 }, 182 182 .th_wl = 3, /* 1LSB = 2B */ 183 183 }, 184 + .ts_settings = { 185 + .timer_en = { 186 + .addr = 0x58, 187 + .mask = BIT(7), 188 + }, 189 + .hr_timer = { 190 + .addr = 0x5c, 191 + .mask = BIT(4), 192 + }, 193 + .fifo_en = { 194 + .addr = 0x07, 195 + .mask = BIT(7), 196 + }, 197 + .decimator = { 198 + .addr = 0x09, 199 + .mask = GENMASK(5, 3), 200 + }, 201 + }, 184 202 }, 185 203 { 186 204 .wai = 0x69, ··· 226 208 .mask = GENMASK(11, 0), 227 209 }, 228 210 .th_wl = 3, /* 1LSB = 2B */ 211 + }, 212 + .ts_settings = { 213 + .timer_en = { 214 + .addr = 0x58, 215 + .mask = BIT(7), 216 + }, 217 + .hr_timer = { 218 + .addr = 0x5c, 219 + .mask = BIT(4), 220 + }, 221 + .fifo_en = { 222 + .addr = 0x07, 223 + .mask = BIT(7), 224 + }, 225 + .decimator = { 226 + .addr = 0x09, 227 + .mask = GENMASK(5, 3), 228 + }, 229 229 }, 230 230 }, 231 231 { ··· 273 237 .mask = GENMASK(11, 0), 274 238 }, 275 239 .th_wl = 3, /* 1LSB = 2B */ 240 + }, 241 + .ts_settings = { 242 + .timer_en = { 243 + .addr = 0x19, 244 + .mask = BIT(5), 245 + }, 246 + .hr_timer = { 247 + .addr = 0x5c, 248 + .mask = BIT(4), 249 + }, 250 + .fifo_en = { 251 + .addr = 0x07, 252 + .mask = BIT(7), 253 + }, 254 + .decimator = { 255 + .addr = 0x09, 256 + .mask = GENMASK(5, 3), 257 + }, 276 258 }, 277 259 }, 278 260 }; ··· 684 630 return err; 685 631 } 686 632 633 + static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw) 634 + { 635 + const struct st_lsm6dsx_hw_ts_settings *ts_settings; 636 + int err, val; 637 + 638 + ts_settings = &hw->settings->ts_settings; 639 + /* enable hw timestamp generation if necessary */ 640 + if (ts_settings->timer_en.addr) { 641 + val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask); 642 + err = regmap_update_bits(hw->regmap, 643 + ts_settings->timer_en.addr, 644 + ts_settings->timer_en.mask, val); 645 + if (err < 0) 646 + return err; 647 + } 648 + 649 + /* enable high resolution for hw ts timer if necessary */ 650 + if (ts_settings->hr_timer.addr) { 651 + val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask); 652 + err = regmap_update_bits(hw->regmap, 653 + ts_settings->hr_timer.addr, 654 + ts_settings->hr_timer.mask, val); 655 + if (err < 0) 656 + return err; 657 + } 658 + 659 + /* enable ts queueing in FIFO if necessary */ 660 + if (ts_settings->fifo_en.addr) { 661 + val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask); 662 + err = regmap_update_bits(hw->regmap, 663 + ts_settings->fifo_en.addr, 664 + ts_settings->fifo_en.mask, val); 665 + if (err < 0) 666 + return err; 667 + } 668 + return 0; 669 + } 670 + 687 671 static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) 688 672 { 689 673 u8 drdy_int_reg; ··· 746 654 if (err < 0) 747 655 return err; 748 656 749 - return regmap_update_bits(hw->regmap, drdy_int_reg, 750 - ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 751 - FIELD_PREP(ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 752 - 1)); 657 + err = regmap_update_bits(hw->regmap, drdy_int_reg, 658 + ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 659 + FIELD_PREP(ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 660 + 1)); 661 + if (err < 0) 662 + return err; 663 + 664 + return st_lsm6dsx_init_hw_timer(hw); 753 665 } 754 666 755 667 static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
+4 -12
drivers/iio/light/apds9960.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * apds9960.c - Support for Avago APDS9960 gesture/RGB/ALS/proximity sensor 3 4 * 4 - * Copyright (C) 2015 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 5 + * Copyright (C) 2015, 2018 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 15 7 * 16 8 * TODO: gesture + proximity calib offsets 17 9 */ ··· 1133 1141 }; 1134 1142 module_i2c_driver(apds9960_driver); 1135 1143 1136 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 1144 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 1137 1145 MODULE_DESCRIPTION("ADPS9960 Gesture/RGB/ALS/Proximity sensor"); 1138 1146 MODULE_LICENSE("GPL");
+10
drivers/iio/potentiometer/Kconfig
··· 5 5 6 6 menu "Digital potentiometers" 7 7 8 + config AD5272 9 + tristate "Analog Devices AD5272 and similar Digital Potentiometer driver" 10 + depends on I2C 11 + help 12 + Say yes here to build support for the Analog Devices AD5272 and AD5274 13 + digital potentiometer chip. 14 + 15 + To compile this driver as a module, choose M here: the 16 + module will be called ad5272. 17 + 8 18 config DS1803 9 19 tristate "Maxim Integrated DS1803 Digital Potentiometer driver" 10 20 depends on I2C
+1
drivers/iio/potentiometer/Makefile
··· 4 4 # 5 5 6 6 # When adding new entries keep the list in alphabetical order 7 + obj-$(CONFIG_AD5272) += ad5272.o 7 8 obj-$(CONFIG_DS1803) += ds1803.o 8 9 obj-$(CONFIG_MAX5481) += max5481.o 9 10 obj-$(CONFIG_MAX5487) += max5487.o
+231
drivers/iio/potentiometer/ad5272.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Analog Devices AD5272 digital potentiometer driver 4 + * Copyright (C) 2018 Phil Reid <preid@electromag.com.au> 5 + * 6 + * Datasheet: http://www.analog.com/media/en/technical-documentation/data-sheets/AD5272_5274.pdf 7 + * 8 + * DEVID #Wipers #Positions Resistor Opts (kOhm) i2c address 9 + * ad5272 1 1024 20, 50, 100 01011xx 10 + * ad5274 1 256 20, 100 01011xx 11 + */ 12 + 13 + #include <linux/delay.h> 14 + #include <linux/gpio/consumer.h> 15 + #include <linux/i2c.h> 16 + #include <linux/iio/iio.h> 17 + #include <linux/module.h> 18 + 19 + #define AD5272_RDAC_WR 1 20 + #define AD5272_RDAC_RD 2 21 + #define AD5272_RESET 4 22 + #define AD5272_CTL 7 23 + 24 + #define AD5272_RDAC_WR_EN BIT(1) 25 + 26 + struct ad5272_cfg { 27 + int max_pos; 28 + int kohms; 29 + int shift; 30 + }; 31 + 32 + enum ad5272_type { 33 + AD5272_020, 34 + AD5272_050, 35 + AD5272_100, 36 + AD5274_020, 37 + AD5274_100, 38 + }; 39 + 40 + static const struct ad5272_cfg ad5272_cfg[] = { 41 + [AD5272_020] = { .max_pos = 1024, .kohms = 20 }, 42 + [AD5272_050] = { .max_pos = 1024, .kohms = 50 }, 43 + [AD5272_100] = { .max_pos = 1024, .kohms = 100 }, 44 + [AD5274_020] = { .max_pos = 256, .kohms = 20, .shift = 2 }, 45 + [AD5274_100] = { .max_pos = 256, .kohms = 100, .shift = 2 }, 46 + }; 47 + 48 + struct ad5272_data { 49 + struct i2c_client *client; 50 + struct mutex lock; 51 + const struct ad5272_cfg *cfg; 52 + u8 buf[2] ____cacheline_aligned; 53 + }; 54 + 55 + static const struct iio_chan_spec ad5272_channel = { 56 + .type = IIO_RESISTANCE, 57 + .output = 1, 58 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 59 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), 60 + }; 61 + 62 + static int ad5272_write(struct ad5272_data *data, int reg, int val) 63 + { 64 + int ret; 65 + 66 + data->buf[0] = (reg << 2) | ((val >> 8) & 0x3); 67 + data->buf[1] = (u8)val; 68 + 69 + mutex_lock(&data->lock); 70 + ret = i2c_master_send(data->client, data->buf, sizeof(data->buf)); 71 + mutex_unlock(&data->lock); 72 + return ret < 0 ? ret : 0; 73 + } 74 + 75 + static int ad5272_read(struct ad5272_data *data, int reg, int *val) 76 + { 77 + int ret; 78 + 79 + data->buf[0] = reg << 2; 80 + data->buf[1] = 0; 81 + 82 + mutex_lock(&data->lock); 83 + ret = i2c_master_send(data->client, data->buf, sizeof(data->buf)); 84 + if (ret < 0) 85 + goto error; 86 + 87 + ret = i2c_master_recv(data->client, data->buf, sizeof(data->buf)); 88 + if (ret < 0) 89 + goto error; 90 + 91 + *val = ((data->buf[0] & 0x3) << 8) | data->buf[1]; 92 + ret = 0; 93 + error: 94 + mutex_unlock(&data->lock); 95 + return ret; 96 + } 97 + 98 + static int ad5272_read_raw(struct iio_dev *indio_dev, 99 + struct iio_chan_spec const *chan, 100 + int *val, int *val2, long mask) 101 + { 102 + struct ad5272_data *data = iio_priv(indio_dev); 103 + int ret; 104 + 105 + switch (mask) { 106 + case IIO_CHAN_INFO_RAW: { 107 + ret = ad5272_read(data, AD5272_RDAC_RD, val); 108 + *val = *val >> data->cfg->shift; 109 + return ret ? ret : IIO_VAL_INT; 110 + } 111 + case IIO_CHAN_INFO_SCALE: 112 + *val = 1000 * data->cfg->kohms; 113 + *val2 = data->cfg->max_pos; 114 + return IIO_VAL_FRACTIONAL; 115 + } 116 + 117 + return -EINVAL; 118 + } 119 + 120 + static int ad5272_write_raw(struct iio_dev *indio_dev, 121 + struct iio_chan_spec const *chan, 122 + int val, int val2, long mask) 123 + { 124 + struct ad5272_data *data = iio_priv(indio_dev); 125 + 126 + if (mask != IIO_CHAN_INFO_RAW) 127 + return -EINVAL; 128 + 129 + if (val >= data->cfg->max_pos || val < 0 || val2) 130 + return -EINVAL; 131 + 132 + return ad5272_write(data, AD5272_RDAC_WR, val << data->cfg->shift); 133 + } 134 + 135 + static const struct iio_info ad5272_info = { 136 + .read_raw = ad5272_read_raw, 137 + .write_raw = ad5272_write_raw, 138 + }; 139 + 140 + static int ad5272_reset(struct ad5272_data *data) 141 + { 142 + struct gpio_desc *reset_gpio; 143 + 144 + reset_gpio = devm_gpiod_get_optional(&data->client->dev, "reset", 145 + GPIOD_OUT_LOW); 146 + if (IS_ERR(reset_gpio)) 147 + return PTR_ERR(reset_gpio); 148 + 149 + if (reset_gpio) { 150 + udelay(1); 151 + gpiod_set_value(reset_gpio, 1); 152 + } else { 153 + ad5272_write(data, AD5272_RESET, 0); 154 + } 155 + usleep_range(1000, 2000); 156 + 157 + return 0; 158 + } 159 + 160 + static int ad5272_probe(struct i2c_client *client, 161 + const struct i2c_device_id *id) 162 + { 163 + struct device *dev = &client->dev; 164 + struct iio_dev *indio_dev; 165 + struct ad5272_data *data; 166 + int ret; 167 + 168 + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 169 + if (!indio_dev) 170 + return -ENOMEM; 171 + 172 + i2c_set_clientdata(client, indio_dev); 173 + 174 + data = iio_priv(indio_dev); 175 + data->client = client; 176 + mutex_init(&data->lock); 177 + data->cfg = &ad5272_cfg[id->driver_data]; 178 + 179 + ret = ad5272_reset(data); 180 + if (ret) 181 + return ret; 182 + 183 + ret = ad5272_write(data, AD5272_CTL, AD5272_RDAC_WR_EN); 184 + if (ret < 0) 185 + return -ENODEV; 186 + 187 + indio_dev->dev.parent = dev; 188 + indio_dev->info = &ad5272_info; 189 + indio_dev->channels = &ad5272_channel; 190 + indio_dev->num_channels = 1; 191 + indio_dev->name = client->name; 192 + 193 + return devm_iio_device_register(dev, indio_dev); 194 + } 195 + 196 + #if defined(CONFIG_OF) 197 + static const struct of_device_id ad5272_dt_ids[] = { 198 + { .compatible = "adi,ad5272-020", .data = (void *)AD5272_020 }, 199 + { .compatible = "adi,ad5272-050", .data = (void *)AD5272_050 }, 200 + { .compatible = "adi,ad5272-100", .data = (void *)AD5272_100 }, 201 + { .compatible = "adi,ad5274-020", .data = (void *)AD5274_020 }, 202 + { .compatible = "adi,ad5274-100", .data = (void *)AD5274_100 }, 203 + {} 204 + }; 205 + MODULE_DEVICE_TABLE(of, ad5272_dt_ids); 206 + #endif /* CONFIG_OF */ 207 + 208 + static const struct i2c_device_id ad5272_id[] = { 209 + { "ad5272-020", AD5272_020 }, 210 + { "ad5272-050", AD5272_050 }, 211 + { "ad5272-100", AD5272_100 }, 212 + { "ad5274-020", AD5274_020 }, 213 + { "ad5274-100", AD5274_100 }, 214 + {} 215 + }; 216 + MODULE_DEVICE_TABLE(i2c, ad5272_id); 217 + 218 + static struct i2c_driver ad5272_driver = { 219 + .driver = { 220 + .name = "ad5272", 221 + .of_match_table = of_match_ptr(ad5272_dt_ids), 222 + }, 223 + .probe = ad5272_probe, 224 + .id_table = ad5272_id, 225 + }; 226 + 227 + module_i2c_driver(ad5272_driver); 228 + 229 + MODULE_AUTHOR("Phil Reid <preid@eletromag.com.au>"); 230 + MODULE_DESCRIPTION("AD5272 digital potentiometer"); 231 + MODULE_LICENSE("GPL v2");
+4 -12
drivers/iio/potentiometer/tpl0102.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * tpl0102.c - Support for Texas Instruments digital potentiometers 3 4 * 4 - * Copyright (C) 2016 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 5 + * Copyright (C) 2016, 2018 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 15 7 * 16 8 * TODO: enable/disable hi-z output control 17 9 */ ··· 148 156 149 157 module_i2c_driver(tpl0102_driver); 150 158 151 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 159 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 152 160 MODULE_DESCRIPTION("TPL0102 digital potentiometer"); 153 161 MODULE_LICENSE("GPL");
+4 -12
drivers/iio/potentiostat/lmp91000.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * lmp91000.c - Support for Texas Instruments digital potentiostats 3 4 * 4 - * Copyright (C) 2016 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 5 + * Copyright (C) 2016, 2018 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 15 7 * 16 8 * TODO: bias voltage + polarity control, and multiple chip support 17 9 */ ··· 432 440 }; 433 441 module_i2c_driver(lmp91000_driver); 434 442 435 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 443 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 436 444 MODULE_DESCRIPTION("LMP91000 digital potentiostat"); 437 445 MODULE_LICENSE("GPL");
+1 -1
drivers/iio/pressure/ms5611.h
··· 63 63 }; 64 64 65 65 int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, 66 - const char* name, int type); 66 + const char *name, int type); 67 67 int ms5611_remove(struct iio_dev *indio_dev); 68 68 69 69 #endif /* _MS5611_H */
+4 -13
drivers/iio/proximity/as3935.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * as3935.c - Support for AS3935 Franklin lightning sensor 3 4 * 4 - * Copyright (C) 2014 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 15 - * 5 + * Copyright (C) 2014, 2017-2018 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 16 7 */ 17 8 18 9 #include <linux/module.h> ··· 493 502 }; 494 503 module_spi_driver(as3935_driver); 495 504 496 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 505 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 497 506 MODULE_DESCRIPTION("AS3935 lightning sensor"); 498 507 MODULE_LICENSE("GPL");
+4 -12
drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * pulsedlight-lidar-lite-v2.c - Support for PulsedLight LIDAR sensor 3 4 * 4 - * Copyright (C) 2015 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 5 + * Copyright (C) 2015, 2017-2018 6 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> 15 7 * 16 8 * TODO: interrupt mode, and signal strength reporting 17 9 */ ··· 369 377 }; 370 378 module_i2c_driver(lidar_driver); 371 379 372 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 380 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 373 381 MODULE_DESCRIPTION("PulsedLight LIDAR sensor"); 374 382 MODULE_LICENSE("GPL");
+12
drivers/iio/temperature/Kconfig
··· 43 43 This driver can also be built as a module. If so, the module will 44 44 be called mlx90614. 45 45 46 + config MLX90632 47 + tristate "MLX90632 contact-less infrared sensor with medical accuracy" 48 + depends on I2C 49 + select REGMAP_I2C 50 + help 51 + If you say yes here you get support for the Melexis 52 + MLX90632 contact-less infrared sensor with medical accuracy 53 + connected with I2C. 54 + 55 + This driver can also be built as a module. If so, the module will 56 + be called mlx90632. 57 + 46 58 config TMP006 47 59 tristate "TMP006 infrared thermopile sensor" 48 60 depends on I2C
+1
drivers/iio/temperature/Makefile
··· 6 6 obj-$(CONFIG_HID_SENSOR_TEMP) += hid-sensor-temperature.o 7 7 obj-$(CONFIG_MAXIM_THERMOCOUPLE) += maxim_thermocouple.o 8 8 obj-$(CONFIG_MLX90614) += mlx90614.o 9 + obj-$(CONFIG_MLX90632) += mlx90632.o 9 10 obj-$(CONFIG_TMP006) += tmp006.o 10 11 obj-$(CONFIG_TMP007) += tmp007.o 11 12 obj-$(CONFIG_TSYS01) += tsys01.o
+4 -12
drivers/iio/temperature/maxim_thermocouple.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * maxim_thermocouple.c - Support for Maxim thermocouple chips 3 4 * 4 - * Copyright (C) 2016 Matt Ranostay <mranostay@gmail.com> 5 - * 6 - * This program is free software; you can redistribute it and/or modify 7 - * it under the terms of the GNU General Public License as published by 8 - * the Free Software Foundation; either version 2 of the License, or 9 - * (at your option) any later version. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 5 + * Copyright (C) 2016-2018 Matt Ranostay 6 + * Author: <matt.ranostay@konsulko.com> 15 7 */ 16 8 17 9 #include <linux/module.h> ··· 273 281 }; 274 282 module_spi_driver(maxim_thermocouple_driver); 275 283 276 - MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); 284 + MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 277 285 MODULE_DESCRIPTION("Maxim thermocouple sensors"); 278 286 MODULE_LICENSE("GPL");
+750
drivers/iio/temperature/mlx90632.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * mlx90632.c - Melexis MLX90632 contactless IR temperature sensor 4 + * 5 + * Copyright (c) 2017 Melexis <cmo@melexis.com> 6 + * 7 + * Driver for the Melexis MLX90632 I2C 16-bit IR thermopile sensor 8 + */ 9 + #include <linux/delay.h> 10 + #include <linux/err.h> 11 + #include <linux/gpio/consumer.h> 12 + #include <linux/i2c.h> 13 + #include <linux/kernel.h> 14 + #include <linux/module.h> 15 + #include <linux/math64.h> 16 + #include <linux/of.h> 17 + #include <linux/pm_runtime.h> 18 + #include <linux/regmap.h> 19 + 20 + #include <linux/iio/iio.h> 21 + #include <linux/iio/sysfs.h> 22 + 23 + /* Memory sections addresses */ 24 + #define MLX90632_ADDR_RAM 0x4000 /* Start address of ram */ 25 + #define MLX90632_ADDR_EEPROM 0x2480 /* Start address of user eeprom */ 26 + 27 + /* EEPROM addresses - used at startup */ 28 + #define MLX90632_EE_CTRL 0x24d4 /* Control register initial value */ 29 + #define MLX90632_EE_I2C_ADDR 0x24d5 /* I2C address register initial value */ 30 + #define MLX90632_EE_VERSION 0x240b /* EEPROM version reg address */ 31 + #define MLX90632_EE_P_R 0x240c /* P_R calibration register 32bit */ 32 + #define MLX90632_EE_P_G 0x240e /* P_G calibration register 32bit */ 33 + #define MLX90632_EE_P_T 0x2410 /* P_T calibration register 32bit */ 34 + #define MLX90632_EE_P_O 0x2412 /* P_O calibration register 32bit */ 35 + #define MLX90632_EE_Aa 0x2414 /* Aa calibration register 32bit */ 36 + #define MLX90632_EE_Ab 0x2416 /* Ab calibration register 32bit */ 37 + #define MLX90632_EE_Ba 0x2418 /* Ba calibration register 32bit */ 38 + #define MLX90632_EE_Bb 0x241a /* Bb calibration register 32bit */ 39 + #define MLX90632_EE_Ca 0x241c /* Ca calibration register 32bit */ 40 + #define MLX90632_EE_Cb 0x241e /* Cb calibration register 32bit */ 41 + #define MLX90632_EE_Da 0x2420 /* Da calibration register 32bit */ 42 + #define MLX90632_EE_Db 0x2422 /* Db calibration register 32bit */ 43 + #define MLX90632_EE_Ea 0x2424 /* Ea calibration register 32bit */ 44 + #define MLX90632_EE_Eb 0x2426 /* Eb calibration register 32bit */ 45 + #define MLX90632_EE_Fa 0x2428 /* Fa calibration register 32bit */ 46 + #define MLX90632_EE_Fb 0x242a /* Fb calibration register 32bit */ 47 + #define MLX90632_EE_Ga 0x242c /* Ga calibration register 32bit */ 48 + 49 + #define MLX90632_EE_Gb 0x242e /* Gb calibration register 16bit */ 50 + #define MLX90632_EE_Ka 0x242f /* Ka calibration register 16bit */ 51 + 52 + #define MLX90632_EE_Ha 0x2481 /* Ha customer calib value reg 16bit */ 53 + #define MLX90632_EE_Hb 0x2482 /* Hb customer calib value reg 16bit */ 54 + 55 + /* Register addresses - volatile */ 56 + #define MLX90632_REG_I2C_ADDR 0x3000 /* Chip I2C address register */ 57 + 58 + /* Control register address - volatile */ 59 + #define MLX90632_REG_CONTROL 0x3001 /* Control Register address */ 60 + #define MLX90632_CFG_PWR_MASK GENMASK(2, 1) /* PowerMode Mask */ 61 + /* PowerModes statuses */ 62 + #define MLX90632_PWR_STATUS(ctrl_val) (ctrl_val << 1) 63 + #define MLX90632_PWR_STATUS_HALT MLX90632_PWR_STATUS(0) /* hold */ 64 + #define MLX90632_PWR_STATUS_SLEEP_STEP MLX90632_PWR_STATUS(1) /* sleep step*/ 65 + #define MLX90632_PWR_STATUS_STEP MLX90632_PWR_STATUS(2) /* step */ 66 + #define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /* continuous*/ 67 + 68 + /* Device status register - volatile */ 69 + #define MLX90632_REG_STATUS 0x3fff /* Device status register */ 70 + #define MLX90632_STAT_BUSY BIT(10) /* Device busy indicator */ 71 + #define MLX90632_STAT_EE_BUSY BIT(9) /* EEPROM busy indicator */ 72 + #define MLX90632_STAT_BRST BIT(8) /* Brown out reset indicator */ 73 + #define MLX90632_STAT_CYCLE_POS GENMASK(6, 2) /* Data position */ 74 + #define MLX90632_STAT_DATA_RDY BIT(0) /* Data ready indicator */ 75 + 76 + /* RAM_MEAS address-es for each channel */ 77 + #define MLX90632_RAM_1(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num) 78 + #define MLX90632_RAM_2(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 1) 79 + #define MLX90632_RAM_3(meas_num) (MLX90632_ADDR_RAM + 3 * meas_num + 2) 80 + 81 + /* Magic constants */ 82 + #define MLX90632_ID_MEDICAL 0x0105 /* EEPROM DSPv5 Medical device id */ 83 + #define MLX90632_ID_CONSUMER 0x0205 /* EEPROM DSPv5 Consumer device id */ 84 + #define MLX90632_RESET_CMD 0x0006 /* Reset sensor (address or global) */ 85 + #define MLX90632_REF_12 12LL /**< ResCtrlRef value of Ch 1 or Ch 2 */ 86 + #define MLX90632_REF_3 12LL /**< ResCtrlRef value of Channel 3 */ 87 + #define MLX90632_MAX_MEAS_NUM 31 /**< Maximum measurements in list */ 88 + #define MLX90632_SLEEP_DELAY_MS 3000 /**< Autosleep delay */ 89 + 90 + struct mlx90632_data { 91 + struct i2c_client *client; 92 + struct mutex lock; /* Multiple reads for single measurement */ 93 + struct regmap *regmap; 94 + u16 emissivity; 95 + }; 96 + 97 + static const struct regmap_range mlx90632_volatile_reg_range[] = { 98 + regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), 99 + regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), 100 + regmap_reg_range(MLX90632_RAM_1(0), 101 + MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)), 102 + }; 103 + 104 + static const struct regmap_access_table mlx90632_volatile_regs_tbl = { 105 + .yes_ranges = mlx90632_volatile_reg_range, 106 + .n_yes_ranges = ARRAY_SIZE(mlx90632_volatile_reg_range), 107 + }; 108 + 109 + static const struct regmap_range mlx90632_read_reg_range[] = { 110 + regmap_reg_range(MLX90632_EE_VERSION, MLX90632_EE_Ka), 111 + regmap_reg_range(MLX90632_EE_CTRL, MLX90632_EE_I2C_ADDR), 112 + regmap_reg_range(MLX90632_EE_Ha, MLX90632_EE_Hb), 113 + regmap_reg_range(MLX90632_REG_I2C_ADDR, MLX90632_REG_CONTROL), 114 + regmap_reg_range(MLX90632_REG_STATUS, MLX90632_REG_STATUS), 115 + regmap_reg_range(MLX90632_RAM_1(0), 116 + MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)), 117 + }; 118 + 119 + static const struct regmap_access_table mlx90632_readable_regs_tbl = { 120 + .yes_ranges = mlx90632_read_reg_range, 121 + .n_yes_ranges = ARRAY_SIZE(mlx90632_read_reg_range), 122 + }; 123 + 124 + static const struct regmap_range mlx90632_no_write_reg_range[] = { 125 + regmap_reg_range(MLX90632_EE_VERSION, MLX90632_EE_Ka), 126 + regmap_reg_range(MLX90632_RAM_1(0), 127 + MLX90632_RAM_3(MLX90632_MAX_MEAS_NUM)), 128 + }; 129 + 130 + static const struct regmap_access_table mlx90632_writeable_regs_tbl = { 131 + .no_ranges = mlx90632_no_write_reg_range, 132 + .n_no_ranges = ARRAY_SIZE(mlx90632_no_write_reg_range), 133 + }; 134 + 135 + static const struct regmap_config mlx90632_regmap = { 136 + .reg_bits = 16, 137 + .val_bits = 16, 138 + 139 + .volatile_table = &mlx90632_volatile_regs_tbl, 140 + .rd_table = &mlx90632_readable_regs_tbl, 141 + .wr_table = &mlx90632_writeable_regs_tbl, 142 + 143 + .use_single_rw = true, 144 + .reg_format_endian = REGMAP_ENDIAN_BIG, 145 + .val_format_endian = REGMAP_ENDIAN_BIG, 146 + .cache_type = REGCACHE_RBTREE, 147 + }; 148 + 149 + static s32 mlx90632_pwr_set_sleep_step(struct regmap *regmap) 150 + { 151 + return regmap_update_bits(regmap, MLX90632_REG_CONTROL, 152 + MLX90632_CFG_PWR_MASK, 153 + MLX90632_PWR_STATUS_SLEEP_STEP); 154 + } 155 + 156 + static s32 mlx90632_pwr_continuous(struct regmap *regmap) 157 + { 158 + return regmap_update_bits(regmap, MLX90632_REG_CONTROL, 159 + MLX90632_CFG_PWR_MASK, 160 + MLX90632_PWR_STATUS_CONTINUOUS); 161 + } 162 + 163 + /** 164 + * mlx90632_perform_measurement - Trigger and retrieve current measurement cycle 165 + * @*data: pointer to mlx90632_data object containing regmap information 166 + * 167 + * Perform a measurement and return latest measurement cycle position reported 168 + * by sensor. This is a blocking function for 500ms, as that is default sensor 169 + * refresh rate. 170 + */ 171 + static int mlx90632_perform_measurement(struct mlx90632_data *data) 172 + { 173 + int ret, tries = 100; 174 + unsigned int reg_status; 175 + 176 + ret = regmap_update_bits(data->regmap, MLX90632_REG_STATUS, 177 + MLX90632_STAT_DATA_RDY, 0); 178 + if (ret < 0) 179 + return ret; 180 + 181 + while (tries-- > 0) { 182 + ret = regmap_read(data->regmap, MLX90632_REG_STATUS, 183 + &reg_status); 184 + if (ret < 0) 185 + return ret; 186 + if (reg_status & MLX90632_STAT_DATA_RDY) 187 + break; 188 + usleep_range(10000, 11000); 189 + } 190 + 191 + if (tries < 0) { 192 + dev_err(&data->client->dev, "data not ready"); 193 + return -ETIMEDOUT; 194 + } 195 + 196 + return (reg_status & MLX90632_STAT_CYCLE_POS) >> 2; 197 + } 198 + 199 + static int mlx90632_channel_new_select(int perform_ret, uint8_t *channel_new, 200 + uint8_t *channel_old) 201 + { 202 + switch (perform_ret) { 203 + case 1: 204 + *channel_new = 1; 205 + *channel_old = 2; 206 + break; 207 + case 2: 208 + *channel_new = 2; 209 + *channel_old = 1; 210 + break; 211 + default: 212 + return -EINVAL; 213 + } 214 + 215 + return 0; 216 + } 217 + 218 + static int mlx90632_read_ambient_raw(struct regmap *regmap, 219 + s16 *ambient_new_raw, s16 *ambient_old_raw) 220 + { 221 + int ret; 222 + unsigned int read_tmp; 223 + 224 + ret = regmap_read(regmap, MLX90632_RAM_3(1), &read_tmp); 225 + if (ret < 0) 226 + return ret; 227 + *ambient_new_raw = (s16)read_tmp; 228 + 229 + ret = regmap_read(regmap, MLX90632_RAM_3(2), &read_tmp); 230 + if (ret < 0) 231 + return ret; 232 + *ambient_old_raw = (s16)read_tmp; 233 + 234 + return ret; 235 + } 236 + 237 + static int mlx90632_read_object_raw(struct regmap *regmap, 238 + int perform_measurement_ret, 239 + s16 *object_new_raw, s16 *object_old_raw) 240 + { 241 + int ret; 242 + unsigned int read_tmp; 243 + s16 read; 244 + u8 channel = 0; 245 + u8 channel_old = 0; 246 + 247 + ret = mlx90632_channel_new_select(perform_measurement_ret, &channel, 248 + &channel_old); 249 + if (ret != 0) 250 + return ret; 251 + 252 + ret = regmap_read(regmap, MLX90632_RAM_2(channel), &read_tmp); 253 + if (ret < 0) 254 + return ret; 255 + 256 + read = (s16)read_tmp; 257 + 258 + ret = regmap_read(regmap, MLX90632_RAM_1(channel), &read_tmp); 259 + if (ret < 0) 260 + return ret; 261 + *object_new_raw = (read + (s16)read_tmp) / 2; 262 + 263 + ret = regmap_read(regmap, MLX90632_RAM_2(channel_old), &read_tmp); 264 + if (ret < 0) 265 + return ret; 266 + read = (s16)read_tmp; 267 + 268 + ret = regmap_read(regmap, MLX90632_RAM_1(channel_old), &read_tmp); 269 + if (ret < 0) 270 + return ret; 271 + *object_old_raw = (read + (s16)read_tmp) / 2; 272 + 273 + return ret; 274 + } 275 + 276 + static int mlx90632_read_all_channel(struct mlx90632_data *data, 277 + s16 *ambient_new_raw, s16 *ambient_old_raw, 278 + s16 *object_new_raw, s16 *object_old_raw) 279 + { 280 + s32 ret, measurement; 281 + 282 + mutex_lock(&data->lock); 283 + measurement = mlx90632_perform_measurement(data); 284 + if (measurement < 0) { 285 + ret = measurement; 286 + goto read_unlock; 287 + } 288 + ret = mlx90632_read_ambient_raw(data->regmap, ambient_new_raw, 289 + ambient_old_raw); 290 + if (ret < 0) 291 + goto read_unlock; 292 + 293 + ret = mlx90632_read_object_raw(data->regmap, measurement, 294 + object_new_raw, object_old_raw); 295 + read_unlock: 296 + mutex_unlock(&data->lock); 297 + return ret; 298 + } 299 + 300 + static int mlx90632_read_ee_register(struct regmap *regmap, u16 reg_lsb, 301 + s32 *reg_value) 302 + { 303 + s32 ret; 304 + unsigned int read; 305 + u32 value; 306 + 307 + ret = regmap_read(regmap, reg_lsb, &read); 308 + if (ret < 0) 309 + return ret; 310 + 311 + value = read; 312 + 313 + ret = regmap_read(regmap, reg_lsb + 1, &read); 314 + if (ret < 0) 315 + return ret; 316 + 317 + *reg_value = (read << 16) | (value & 0xffff); 318 + 319 + return 0; 320 + } 321 + 322 + static s64 mlx90632_preprocess_temp_amb(s16 ambient_new_raw, 323 + s16 ambient_old_raw, s16 Gb) 324 + { 325 + s64 VR_Ta, kGb, tmp; 326 + 327 + kGb = ((s64)Gb * 1000LL) >> 10ULL; 328 + VR_Ta = (s64)ambient_old_raw * 1000000LL + 329 + kGb * div64_s64(((s64)ambient_new_raw * 1000LL), 330 + (MLX90632_REF_3)); 331 + tmp = div64_s64( 332 + div64_s64(((s64)ambient_new_raw * 1000000000000LL), 333 + (MLX90632_REF_3)), VR_Ta); 334 + return div64_s64(tmp << 19ULL, 1000LL); 335 + } 336 + 337 + static s64 mlx90632_preprocess_temp_obj(s16 object_new_raw, s16 object_old_raw, 338 + s16 ambient_new_raw, 339 + s16 ambient_old_raw, s16 Ka) 340 + { 341 + s64 VR_IR, kKa, tmp; 342 + 343 + kKa = ((s64)Ka * 1000LL) >> 10ULL; 344 + VR_IR = (s64)ambient_old_raw * 1000000LL + 345 + kKa * div64_s64(((s64)ambient_new_raw * 1000LL), 346 + (MLX90632_REF_3)); 347 + tmp = div64_s64( 348 + div64_s64(((s64)((object_new_raw + object_old_raw) / 2) 349 + * 1000000000000LL), (MLX90632_REF_12)), 350 + VR_IR); 351 + return div64_s64((tmp << 19ULL), 1000LL); 352 + } 353 + 354 + static s32 mlx90632_calc_temp_ambient(s16 ambient_new_raw, s16 ambient_old_raw, 355 + s32 P_T, s32 P_R, s32 P_G, s32 P_O, 356 + s16 Gb) 357 + { 358 + s64 Asub, Bsub, Ablock, Bblock, Cblock, AMB, sum; 359 + 360 + AMB = mlx90632_preprocess_temp_amb(ambient_new_raw, ambient_old_raw, 361 + Gb); 362 + Asub = ((s64)P_T * 10000000000LL) >> 44ULL; 363 + Bsub = AMB - (((s64)P_R * 1000LL) >> 8ULL); 364 + Ablock = Asub * (Bsub * Bsub); 365 + Bblock = (div64_s64(Bsub * 10000000LL, P_G)) << 20ULL; 366 + Cblock = ((s64)P_O * 10000000000LL) >> 8ULL; 367 + 368 + sum = div64_s64(Ablock, 1000000LL) + Bblock + Cblock; 369 + 370 + return div64_s64(sum, 10000000LL); 371 + } 372 + 373 + static s32 mlx90632_calc_temp_object_iteration(s32 prev_object_temp, s64 object, 374 + s64 TAdut, s32 Fa, s32 Fb, 375 + s32 Ga, s16 Ha, s16 Hb, 376 + u16 emissivity) 377 + { 378 + s64 calcedKsTO, calcedKsTA, ir_Alpha, TAdut4, Alpha_corr; 379 + s64 Ha_customer, Hb_customer; 380 + 381 + Ha_customer = ((s64)Ha * 1000000LL) >> 14ULL; 382 + Hb_customer = ((s64)Hb * 100) >> 10ULL; 383 + 384 + calcedKsTO = ((s64)((s64)Ga * (prev_object_temp - 25 * 1000LL) 385 + * 1000LL)) >> 36LL; 386 + calcedKsTA = ((s64)(Fb * (TAdut - 25 * 1000000LL))) >> 36LL; 387 + Alpha_corr = div64_s64((((s64)(Fa * 10000000000LL) >> 46LL) 388 + * Ha_customer), 1000LL); 389 + Alpha_corr *= ((s64)(1 * 1000000LL + calcedKsTO + calcedKsTA)); 390 + Alpha_corr = emissivity * div64_s64(Alpha_corr, 100000LL); 391 + Alpha_corr = div64_s64(Alpha_corr, 1000LL); 392 + ir_Alpha = div64_s64((s64)object * 10000000LL, Alpha_corr); 393 + TAdut4 = (div64_s64(TAdut, 10000LL) + 27315) * 394 + (div64_s64(TAdut, 10000LL) + 27315) * 395 + (div64_s64(TAdut, 10000LL) + 27315) * 396 + (div64_s64(TAdut, 10000LL) + 27315); 397 + 398 + return (int_sqrt64(int_sqrt64(ir_Alpha * 1000000000000LL + TAdut4)) 399 + - 27315 - Hb_customer) * 10; 400 + } 401 + 402 + static s32 mlx90632_calc_temp_object(s64 object, s64 ambient, s32 Ea, s32 Eb, 403 + s32 Fa, s32 Fb, s32 Ga, s16 Ha, s16 Hb, 404 + u16 tmp_emi) 405 + { 406 + s64 kTA, kTA0, TAdut; 407 + s64 temp = 25000; 408 + s8 i; 409 + 410 + kTA = (Ea * 1000LL) >> 16LL; 411 + kTA0 = (Eb * 1000LL) >> 8LL; 412 + TAdut = div64_s64(((ambient - kTA0) * 1000000LL), kTA) + 25 * 1000000LL; 413 + 414 + /* Iterations of calculation as described in datasheet */ 415 + for (i = 0; i < 5; ++i) { 416 + temp = mlx90632_calc_temp_object_iteration(temp, object, TAdut, 417 + Fa, Fb, Ga, Ha, Hb, 418 + tmp_emi); 419 + } 420 + return temp; 421 + } 422 + 423 + static int mlx90632_calc_object_dsp105(struct mlx90632_data *data, int *val) 424 + { 425 + s32 ret; 426 + s32 Ea, Eb, Fa, Fb, Ga; 427 + unsigned int read_tmp; 428 + s16 Ha, Hb, Gb, Ka; 429 + s16 ambient_new_raw, ambient_old_raw, object_new_raw, object_old_raw; 430 + s64 object, ambient; 431 + 432 + ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Ea, &Ea); 433 + if (ret < 0) 434 + return ret; 435 + ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Eb, &Eb); 436 + if (ret < 0) 437 + return ret; 438 + ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Fa, &Fa); 439 + if (ret < 0) 440 + return ret; 441 + ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Fb, &Fb); 442 + if (ret < 0) 443 + return ret; 444 + ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_Ga, &Ga); 445 + if (ret < 0) 446 + return ret; 447 + ret = regmap_read(data->regmap, MLX90632_EE_Ha, &read_tmp); 448 + if (ret < 0) 449 + return ret; 450 + Ha = (s16)read_tmp; 451 + ret = regmap_read(data->regmap, MLX90632_EE_Hb, &read_tmp); 452 + if (ret < 0) 453 + return ret; 454 + Hb = (s16)read_tmp; 455 + ret = regmap_read(data->regmap, MLX90632_EE_Gb, &read_tmp); 456 + if (ret < 0) 457 + return ret; 458 + Gb = (s16)read_tmp; 459 + ret = regmap_read(data->regmap, MLX90632_EE_Ka, &read_tmp); 460 + if (ret < 0) 461 + return ret; 462 + Ka = (s16)read_tmp; 463 + 464 + ret = mlx90632_read_all_channel(data, 465 + &ambient_new_raw, &ambient_old_raw, 466 + &object_new_raw, &object_old_raw); 467 + if (ret < 0) 468 + return ret; 469 + 470 + ambient = mlx90632_preprocess_temp_amb(ambient_new_raw, 471 + ambient_old_raw, Gb); 472 + object = mlx90632_preprocess_temp_obj(object_new_raw, 473 + object_old_raw, 474 + ambient_new_raw, 475 + ambient_old_raw, Ka); 476 + 477 + *val = mlx90632_calc_temp_object(object, ambient, Ea, Eb, Fa, Fb, Ga, 478 + Ha, Hb, data->emissivity); 479 + return 0; 480 + } 481 + 482 + static int mlx90632_calc_ambient_dsp105(struct mlx90632_data *data, int *val) 483 + { 484 + s32 ret; 485 + unsigned int read_tmp; 486 + s32 PT, PR, PG, PO; 487 + s16 Gb; 488 + s16 ambient_new_raw, ambient_old_raw; 489 + 490 + ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_R, &PR); 491 + if (ret < 0) 492 + return ret; 493 + ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_G, &PG); 494 + if (ret < 0) 495 + return ret; 496 + ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_T, &PT); 497 + if (ret < 0) 498 + return ret; 499 + ret = mlx90632_read_ee_register(data->regmap, MLX90632_EE_P_O, &PO); 500 + if (ret < 0) 501 + return ret; 502 + ret = regmap_read(data->regmap, MLX90632_EE_Gb, &read_tmp); 503 + if (ret < 0) 504 + return ret; 505 + Gb = (s16)read_tmp; 506 + 507 + ret = mlx90632_read_ambient_raw(data->regmap, &ambient_new_raw, 508 + &ambient_old_raw); 509 + *val = mlx90632_calc_temp_ambient(ambient_new_raw, ambient_old_raw, 510 + PT, PR, PG, PO, Gb); 511 + return ret; 512 + } 513 + 514 + static int mlx90632_read_raw(struct iio_dev *indio_dev, 515 + struct iio_chan_spec const *channel, int *val, 516 + int *val2, long mask) 517 + { 518 + struct mlx90632_data *data = iio_priv(indio_dev); 519 + int ret; 520 + 521 + switch (mask) { 522 + case IIO_CHAN_INFO_PROCESSED: 523 + switch (channel->channel2) { 524 + case IIO_MOD_TEMP_AMBIENT: 525 + ret = mlx90632_calc_ambient_dsp105(data, val); 526 + if (ret < 0) 527 + return ret; 528 + return IIO_VAL_INT; 529 + case IIO_MOD_TEMP_OBJECT: 530 + ret = mlx90632_calc_object_dsp105(data, val); 531 + if (ret < 0) 532 + return ret; 533 + return IIO_VAL_INT; 534 + default: 535 + return -EINVAL; 536 + } 537 + case IIO_CHAN_INFO_CALIBEMISSIVITY: 538 + if (data->emissivity == 1000) { 539 + *val = 1; 540 + *val2 = 0; 541 + } else { 542 + *val = 0; 543 + *val2 = data->emissivity * 1000; 544 + } 545 + return IIO_VAL_INT_PLUS_MICRO; 546 + 547 + default: 548 + return -EINVAL; 549 + } 550 + } 551 + 552 + static int mlx90632_write_raw(struct iio_dev *indio_dev, 553 + struct iio_chan_spec const *channel, int val, 554 + int val2, long mask) 555 + { 556 + struct mlx90632_data *data = iio_priv(indio_dev); 557 + 558 + switch (mask) { 559 + case IIO_CHAN_INFO_CALIBEMISSIVITY: 560 + /* Confirm we are within 0 and 1.0 */ 561 + if (val < 0 || val2 < 0 || val > 1 || 562 + (val == 1 && val2 != 0)) 563 + return -EINVAL; 564 + data->emissivity = val * 1000 + val2 / 1000; 565 + return 0; 566 + default: 567 + return -EINVAL; 568 + } 569 + } 570 + 571 + static const struct iio_chan_spec mlx90632_channels[] = { 572 + { 573 + .type = IIO_TEMP, 574 + .modified = 1, 575 + .channel2 = IIO_MOD_TEMP_AMBIENT, 576 + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), 577 + }, 578 + { 579 + .type = IIO_TEMP, 580 + .modified = 1, 581 + .channel2 = IIO_MOD_TEMP_OBJECT, 582 + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | 583 + BIT(IIO_CHAN_INFO_CALIBEMISSIVITY), 584 + }, 585 + }; 586 + 587 + static const struct iio_info mlx90632_info = { 588 + .read_raw = mlx90632_read_raw, 589 + .write_raw = mlx90632_write_raw, 590 + }; 591 + 592 + static int mlx90632_sleep(struct mlx90632_data *data) 593 + { 594 + regcache_mark_dirty(data->regmap); 595 + 596 + dev_dbg(&data->client->dev, "Requesting sleep"); 597 + return mlx90632_pwr_set_sleep_step(data->regmap); 598 + } 599 + 600 + static int mlx90632_wakeup(struct mlx90632_data *data) 601 + { 602 + int ret; 603 + 604 + ret = regcache_sync(data->regmap); 605 + if (ret < 0) { 606 + dev_err(&data->client->dev, 607 + "Failed to sync regmap registers: %d\n", ret); 608 + return ret; 609 + } 610 + 611 + dev_dbg(&data->client->dev, "Requesting wake-up\n"); 612 + return mlx90632_pwr_continuous(data->regmap); 613 + } 614 + 615 + static int mlx90632_probe(struct i2c_client *client, 616 + const struct i2c_device_id *id) 617 + { 618 + struct iio_dev *indio_dev; 619 + struct mlx90632_data *mlx90632; 620 + struct regmap *regmap; 621 + int ret; 622 + unsigned int read; 623 + 624 + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*mlx90632)); 625 + if (!indio_dev) { 626 + dev_err(&client->dev, "Failed to allocate device\n"); 627 + return -ENOMEM; 628 + } 629 + 630 + regmap = devm_regmap_init_i2c(client, &mlx90632_regmap); 631 + if (IS_ERR(regmap)) { 632 + ret = PTR_ERR(regmap); 633 + dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret); 634 + return ret; 635 + } 636 + 637 + mlx90632 = iio_priv(indio_dev); 638 + i2c_set_clientdata(client, indio_dev); 639 + mlx90632->client = client; 640 + mlx90632->regmap = regmap; 641 + 642 + mutex_init(&mlx90632->lock); 643 + indio_dev->dev.parent = &client->dev; 644 + indio_dev->name = id->name; 645 + indio_dev->modes = INDIO_DIRECT_MODE; 646 + indio_dev->info = &mlx90632_info; 647 + indio_dev->channels = mlx90632_channels; 648 + indio_dev->num_channels = ARRAY_SIZE(mlx90632_channels); 649 + 650 + ret = mlx90632_wakeup(mlx90632); 651 + if (ret < 0) { 652 + dev_err(&client->dev, "Wakeup failed: %d\n", ret); 653 + return ret; 654 + } 655 + 656 + ret = regmap_read(mlx90632->regmap, MLX90632_EE_VERSION, &read); 657 + if (ret < 0) { 658 + dev_err(&client->dev, "read of version failed: %d\n", ret); 659 + return ret; 660 + } 661 + if (read == MLX90632_ID_MEDICAL) { 662 + dev_dbg(&client->dev, 663 + "Detected Medical EEPROM calibration %x\n", read); 664 + } else if (read == MLX90632_ID_CONSUMER) { 665 + dev_dbg(&client->dev, 666 + "Detected Consumer EEPROM calibration %x\n", read); 667 + } else { 668 + dev_err(&client->dev, 669 + "EEPROM version mismatch %x (expected %x or %x)\n", 670 + read, MLX90632_ID_CONSUMER, MLX90632_ID_MEDICAL); 671 + return -EPROTONOSUPPORT; 672 + } 673 + 674 + mlx90632->emissivity = 1000; 675 + 676 + pm_runtime_disable(&client->dev); 677 + ret = pm_runtime_set_active(&client->dev); 678 + if (ret < 0) { 679 + mlx90632_sleep(mlx90632); 680 + return ret; 681 + } 682 + pm_runtime_enable(&client->dev); 683 + pm_runtime_set_autosuspend_delay(&client->dev, MLX90632_SLEEP_DELAY_MS); 684 + pm_runtime_use_autosuspend(&client->dev); 685 + 686 + return iio_device_register(indio_dev); 687 + } 688 + 689 + static int mlx90632_remove(struct i2c_client *client) 690 + { 691 + struct iio_dev *indio_dev = i2c_get_clientdata(client); 692 + struct mlx90632_data *data = iio_priv(indio_dev); 693 + 694 + iio_device_unregister(indio_dev); 695 + 696 + pm_runtime_disable(&client->dev); 697 + pm_runtime_set_suspended(&client->dev); 698 + pm_runtime_put_noidle(&client->dev); 699 + 700 + mlx90632_sleep(data); 701 + 702 + return 0; 703 + } 704 + 705 + static const struct i2c_device_id mlx90632_id[] = { 706 + { "mlx90632", 0 }, 707 + { } 708 + }; 709 + MODULE_DEVICE_TABLE(i2c, mlx90632_id); 710 + 711 + static const struct of_device_id mlx90632_of_match[] = { 712 + { .compatible = "melexis,mlx90632" }, 713 + { } 714 + }; 715 + MODULE_DEVICE_TABLE(of, mlx90632_of_match); 716 + 717 + static int __maybe_unused mlx90632_pm_suspend(struct device *dev) 718 + { 719 + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 720 + struct mlx90632_data *data = iio_priv(indio_dev); 721 + 722 + return mlx90632_sleep(data); 723 + } 724 + 725 + static int __maybe_unused mlx90632_pm_resume(struct device *dev) 726 + { 727 + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 728 + struct mlx90632_data *data = iio_priv(indio_dev); 729 + 730 + return mlx90632_wakeup(data); 731 + } 732 + 733 + static UNIVERSAL_DEV_PM_OPS(mlx90632_pm_ops, mlx90632_pm_suspend, 734 + mlx90632_pm_resume, NULL); 735 + 736 + static struct i2c_driver mlx90632_driver = { 737 + .driver = { 738 + .name = "mlx90632", 739 + .of_match_table = mlx90632_of_match, 740 + .pm = &mlx90632_pm_ops, 741 + }, 742 + .probe = mlx90632_probe, 743 + .remove = mlx90632_remove, 744 + .id_table = mlx90632_id, 745 + }; 746 + module_i2c_driver(mlx90632_driver); 747 + 748 + MODULE_AUTHOR("Crt Mori <cmo@melexis.com>"); 749 + MODULE_DESCRIPTION("Melexis MLX90632 contactless Infra Red temperature sensor driver"); 750 + MODULE_LICENSE("GPL v2");
+5 -1
drivers/staging/iio/adc/ad7192.c
··· 290 290 if (pdata->unipolar_en) 291 291 st->conf |= AD7192_CONF_UNIPOLAR; 292 292 293 - if (pdata->burnout_curr_en) 293 + if (pdata->burnout_curr_en && pdata->buf_en && !pdata->chop_en) { 294 294 st->conf |= AD7192_CONF_BURN; 295 + } else if (pdata->burnout_curr_en) { 296 + dev_warn(&st->sd.spi->dev, 297 + "Can't enable burnout currents: see CHOP or buffer\n"); 298 + } 295 299 296 300 ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); 297 301 if (ret)
+1 -1
drivers/staging/iio/meter/ade7758.h
··· 111 111 * @trig: data ready trigger registered with iio 112 112 * @tx: transmit buffer 113 113 * @rx: receive buffer 114 - * @buf_lock: mutex to protect tx and rx 114 + * @buf_lock: mutex to protect tx, rx, read and write frequency 115 115 **/ 116 116 struct ade7758_state { 117 117 struct spi_device *us;
+38 -14
drivers/staging/iio/meter/ade7758_core.c
··· 24 24 #include "meter.h" 25 25 #include "ade7758.h" 26 26 27 + static int __ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) 28 + { 29 + struct iio_dev *indio_dev = dev_to_iio_dev(dev); 30 + struct ade7758_state *st = iio_priv(indio_dev); 31 + 32 + st->tx[0] = ADE7758_WRITE_REG(reg_address); 33 + st->tx[1] = val; 34 + 35 + return spi_write(st->us, st->tx, 2); 36 + } 37 + 27 38 int ade7758_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val) 28 39 { 29 40 int ret; ··· 42 31 struct ade7758_state *st = iio_priv(indio_dev); 43 32 44 33 mutex_lock(&st->buf_lock); 45 - st->tx[0] = ADE7758_WRITE_REG(reg_address); 46 - st->tx[1] = val; 47 - 48 - ret = spi_write(st->us, st->tx, 2); 34 + ret = __ade7758_spi_write_reg_8(dev, reg_address, val); 49 35 mutex_unlock(&st->buf_lock); 50 36 51 37 return ret; ··· 99 91 return ret; 100 92 } 101 93 102 - int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) 94 + static int __ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) 103 95 { 104 96 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 105 97 struct ade7758_state *st = iio_priv(indio_dev); ··· 119 111 }, 120 112 }; 121 113 122 - mutex_lock(&st->buf_lock); 123 114 st->tx[0] = ADE7758_READ_REG(reg_address); 124 115 st->tx[1] = 0; 125 116 ··· 131 124 *val = st->rx[0]; 132 125 133 126 error_ret: 127 + return ret; 128 + } 129 + 130 + int ade7758_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val) 131 + { 132 + struct iio_dev *indio_dev = dev_to_iio_dev(dev); 133 + struct ade7758_state *st = iio_priv(indio_dev); 134 + int ret; 135 + 136 + mutex_lock(&st->buf_lock); 137 + ret = __ade7758_spi_read_reg_8(dev, reg_address, val); 134 138 mutex_unlock(&st->buf_lock); 139 + 135 140 return ret; 136 141 } 137 142 ··· 503 484 { 504 485 int ret; 505 486 u8 reg, t; 487 + struct iio_dev *indio_dev = dev_to_iio_dev(dev); 488 + struct ade7758_state *st = iio_priv(indio_dev); 506 489 507 490 switch (val) { 508 491 case 26040: ··· 520 499 t = 3; 521 500 break; 522 501 default: 523 - ret = -EINVAL; 524 - goto out; 502 + return -EINVAL; 525 503 } 526 504 527 - ret = ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &reg); 505 + mutex_lock(&st->buf_lock); 506 + 507 + ret = __ade7758_spi_read_reg_8(dev, ADE7758_WAVMODE, &reg); 528 508 if (ret) 529 509 goto out; 530 510 531 511 reg &= ~(5 << 3); 532 512 reg |= t << 5; 533 513 534 - ret = ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg); 514 + ret = __ade7758_spi_write_reg_8(dev, ADE7758_WAVMODE, reg); 535 515 536 516 out: 517 + mutex_unlock(&st->buf_lock); 518 + 537 519 return ret; 538 520 } 539 521 ··· 550 526 551 527 switch (mask) { 552 528 case IIO_CHAN_INFO_SAMP_FREQ: 553 - mutex_lock(&indio_dev->mlock); 529 + 554 530 ret = ade7758_read_samp_freq(&indio_dev->dev, val); 555 - mutex_unlock(&indio_dev->mlock); 531 + 556 532 return ret; 557 533 default: 558 534 return -EINVAL; ··· 571 547 case IIO_CHAN_INFO_SAMP_FREQ: 572 548 if (val2) 573 549 return -EINVAL; 574 - mutex_lock(&indio_dev->mlock); 550 + 575 551 ret = ade7758_write_samp_freq(&indio_dev->dev, val); 576 - mutex_unlock(&indio_dev->mlock); 552 + 577 553 return ret; 578 554 default: 579 555 return -EINVAL;
+38 -42
drivers/staging/iio/meter/ade7759.c
··· 72 72 }; 73 73 74 74 static int ade7759_spi_write_reg_8(struct device *dev, 75 - u8 reg_address, 76 - u8 val) 75 + u8 reg_address, 76 + u8 val) 77 77 { 78 78 int ret; 79 79 struct iio_dev *indio_dev = dev_to_iio_dev(dev); ··· 91 91 92 92 /*Unlocked version of ade7759_spi_write_reg_16 function */ 93 93 static int __ade7759_spi_write_reg_16(struct device *dev, 94 - u8 reg_address, 95 - u16 value) 94 + u8 reg_address, 95 + u16 value) 96 96 { 97 97 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 98 98 struct ade7759_state *st = iio_priv(indio_dev); ··· 104 104 } 105 105 106 106 static int ade7759_spi_write_reg_16(struct device *dev, 107 - u8 reg_address, 108 - u16 value) 107 + u8 reg_address, 108 + u16 value) 109 109 { 110 110 int ret; 111 111 struct iio_dev *indio_dev = dev_to_iio_dev(dev); ··· 119 119 } 120 120 121 121 static int ade7759_spi_read_reg_8(struct device *dev, 122 - u8 reg_address, 123 - u8 *val) 122 + u8 reg_address, 123 + u8 *val) 124 124 { 125 125 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 126 126 struct ade7759_state *st = iio_priv(indio_dev); ··· 128 128 129 129 ret = spi_w8r8(st->us, ADE7759_READ_REG(reg_address)); 130 130 if (ret < 0) { 131 - dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", 132 - reg_address); 131 + dev_err(&st->us->dev, 132 + "problem when reading 8 bit register 0x%02X", 133 + reg_address); 133 134 return ret; 134 135 } 135 136 *val = ret; ··· 139 138 } 140 139 141 140 static int ade7759_spi_read_reg_16(struct device *dev, 142 - u8 reg_address, 143 - u16 *val) 141 + u8 reg_address, 142 + u16 *val) 144 143 { 145 144 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 146 145 struct ade7759_state *st = iio_priv(indio_dev); ··· 159 158 } 160 159 161 160 static int ade7759_spi_read_reg_40(struct device *dev, 162 - u8 reg_address, 163 - u64 *val) 161 + u8 reg_address, 162 + u64 *val) 164 163 { 165 164 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 166 165 struct ade7759_state *st = iio_priv(indio_dev); ··· 180 179 181 180 ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers)); 182 181 if (ret) { 183 - dev_err(&st->us->dev, "problem when reading 40 bit register 0x%02X", 184 - reg_address); 182 + dev_err(&st->us->dev, 183 + "problem when reading 40 bit register 0x%02X", 184 + reg_address); 185 185 goto error_ret; 186 186 } 187 187 *val = ((u64)st->rx[1] << 32) | ((u64)st->rx[2] << 24) | ··· 194 192 } 195 193 196 194 static ssize_t ade7759_read_8bit(struct device *dev, 197 - struct device_attribute *attr, 198 - char *buf) 195 + struct device_attribute *attr, 196 + char *buf) 199 197 { 200 198 int ret; 201 199 u8 val = 0; ··· 209 207 } 210 208 211 209 static ssize_t ade7759_read_16bit(struct device *dev, 212 - struct device_attribute *attr, 213 - char *buf) 210 + struct device_attribute *attr, 211 + char *buf) 214 212 { 215 213 int ret; 216 214 u16 val = 0; ··· 224 222 } 225 223 226 224 static ssize_t ade7759_read_40bit(struct device *dev, 227 - struct device_attribute *attr, 228 - char *buf) 225 + struct device_attribute *attr, 226 + char *buf) 229 227 { 230 228 int ret; 231 229 u64 val = 0; ··· 239 237 } 240 238 241 239 static ssize_t ade7759_write_8bit(struct device *dev, 242 - struct device_attribute *attr, 243 - const char *buf, 244 - size_t len) 240 + struct device_attribute *attr, 241 + const char *buf, 242 + size_t len) 245 243 { 246 244 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 247 245 int ret; ··· 257 255 } 258 256 259 257 static ssize_t ade7759_write_16bit(struct device *dev, 260 - struct device_attribute *attr, 261 - const char *buf, 262 - size_t len) 258 + struct device_attribute *attr, 259 + const char *buf, 260 + size_t len) 263 261 { 264 262 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 265 263 int ret; ··· 279 277 int ret; 280 278 u16 val; 281 279 282 - ret = ade7759_spi_read_reg_16(dev, 283 - ADE7759_MODE, 284 - &val); 280 + ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &val); 285 281 if (ret < 0) 286 282 return ret; 287 283 ··· 365 365 int ret; 366 366 u16 val; 367 367 368 - ret = ade7759_spi_read_reg_16(dev, 369 - ADE7759_MODE, 370 - &val); 368 + ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &val); 371 369 if (ret < 0) { 372 370 dev_err(dev, "unable to power down the device, error: %d\n", 373 371 ret); ··· 402 404 } 403 405 404 406 static ssize_t ade7759_read_frequency(struct device *dev, 405 - struct device_attribute *attr, 406 - char *buf) 407 + struct device_attribute *attr, 408 + char *buf) 407 409 { 408 410 int ret; 409 411 u16 t; 410 412 int sps; 411 413 412 - ret = ade7759_spi_read_reg_16(dev, 413 - ADE7759_MODE, 414 - &t); 414 + ret = ade7759_spi_read_reg_16(dev, ADE7759_MODE, &t); 415 415 if (ret) 416 416 return ret; 417 417 ··· 420 424 } 421 425 422 426 static ssize_t ade7759_write_frequency(struct device *dev, 423 - struct device_attribute *attr, 424 - const char *buf, 425 - size_t len) 427 + struct device_attribute *attr, 428 + const char *buf, 429 + size_t len) 426 430 { 427 431 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 428 432 struct ade7759_state *st = iio_priv(indio_dev);
+9
include/linux/kernel.h
··· 479 479 480 480 unsigned long int_sqrt(unsigned long); 481 481 482 + #if BITS_PER_LONG < 64 483 + u32 int_sqrt64(u64 x); 484 + #else 485 + static inline u32 int_sqrt64(u64 x) 486 + { 487 + return (u32)int_sqrt(x); 488 + } 489 + #endif 490 + 482 491 extern void bust_spinlocks(int yes); 483 492 extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */ 484 493 extern int panic_timeout;
+2
include/linux/mfd/axp20x.h
··· 266 266 #define AXP288_RT_BATT_V_H 0xa0 267 267 #define AXP288_RT_BATT_V_L 0xa1 268 268 269 + #define AXP813_ADC_RATE 0x85 270 + 269 271 /* Fuel Gauge */ 270 272 #define AXP288_FG_RDC1_REG 0xba 271 273 #define AXP288_FG_RDC0_REG 0xbb
+30
lib/int_sqrt.c
··· 38 38 return y; 39 39 } 40 40 EXPORT_SYMBOL(int_sqrt); 41 + 42 + #if BITS_PER_LONG < 64 43 + /** 44 + * int_sqrt64 - strongly typed int_sqrt function when minimum 64 bit input 45 + * is expected. 46 + * @x: 64bit integer of which to calculate the sqrt 47 + */ 48 + u32 int_sqrt64(u64 x) 49 + { 50 + u64 b, m, y = 0; 51 + 52 + if (x <= ULONG_MAX) 53 + return int_sqrt((unsigned long) x); 54 + 55 + m = 1ULL << (fls64(x) & ~1ULL); 56 + while (m != 0) { 57 + b = y + m; 58 + y >>= 1; 59 + 60 + if (x >= b) { 61 + x -= b; 62 + y += m; 63 + } 64 + m >>= 2; 65 + } 66 + 67 + return y; 68 + } 69 + EXPORT_SYMBOL(int_sqrt64); 70 + #endif