Преглед изворни кода

Merge tag 'staging-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging tree merge from Greg KH:
 "Here's the bit staging tree pull request for 3.12-rc1.

  Lots of staging driver updates, and fixes.  Lustre is finally enabled
  in the build, and lots of cleanup started happening in it.  There's a
  new wireless driver in here, and 2 new TTY drivers, which cause the
  overall lines added/removed to be quite large on the "added" side.

  The IIO driver updates are also coming through here, as they are tied
  to the staging iio drivers"

* tag 'staging-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (942 commits)
  staging: dwc2: make dwc2_core_params documentation more complete
  staging: dwc2: validate the value for phy_utmi_width
  staging: dwc2: interpret all hwcfg and related register at init time
  staging: dwc2: properly mask the GRXFSIZ register
  staging: dwc2: remove redundant register reads
  staging: dwc2: re-use hptxfsiz variable
  staging: dwc2: simplify debug output in dwc_hc_init
  staging: dwc2: add missing shift
  staging: dwc2: simplify register shift expressions
  staging: dwc2: only read the snpsid register once
  staging: dwc2: unshift non-bool register value constants
  staging: dwc2: fix off-by-one in check for max_packet_count parameter
  staging: dwc2: remove specific fifo size constants
  Staging:BCM:DDRInit.c:Renaming __FUNCTION__
  staging: bcm: remove Version.h file.
  staging: rtl8188eu: off by one in rtw_set_802_11_add_wep()
  staging: r8188eu: copying one byte too much
  staging: rtl8188eu: || vs && typo
  staging: r8188eu: off by one bugs
  staging: crystalhd: Resolve sparse 'different base types' warnings.
  ...
Linus Torvalds пре 12 година
родитељ
комит
751144271f
100 измењених фајлова са 3950 додато и 1127 уклоњено
  1. 19 0
      Documentation/ABI/testing/sysfs-bus-iio
  2. 0 8
      Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523
  3. 1 1
      Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350
  4. 2 5
      Documentation/devicetree/bindings/arm/atmel-adc.txt
  5. 24 0
      Documentation/devicetree/bindings/iio/accel/bma180.txt
  6. 18 0
      Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt
  7. 22 0
      Documentation/devicetree/bindings/iio/light/apds9300.txt
  8. 1 0
      Documentation/devicetree/bindings/vendor-prefixes.txt
  9. 6 0
      Documentation/driver-model/devres.txt
  10. 3 3
      MAINTAINERS
  11. 14 2
      arch/arm/mach-at91/include/mach/at91_adc.h
  12. 4 4
      drivers/iio/Kconfig
  13. 2 1
      drivers/iio/Makefile
  14. 23 9
      drivers/iio/accel/Kconfig
  15. 3 2
      drivers/iio/accel/Makefile
  16. 676 0
      drivers/iio/accel/bma180.c
  17. 18 25
      drivers/iio/accel/hid-sensor-accel-3d.c
  18. 5 12
      drivers/iio/accel/kxsd9.c
  19. 10 1
      drivers/iio/accel/st_accel.h
  20. 19 9
      drivers/iio/accel/st_accel_core.c
  21. 5 12
      drivers/iio/accel/st_accel_i2c.c
  22. 5 12
      drivers/iio/accel/st_accel_spi.c
  23. 43 18
      drivers/iio/adc/Kconfig
  24. 3 0
      drivers/iio/adc/Makefile
  25. 4 12
      drivers/iio/adc/ad7266.c
  26. 8 16
      drivers/iio/adc/ad7298.c
  27. 8 18
      drivers/iio/adc/ad7476.c
  28. 5 14
      drivers/iio/adc/ad7791.c
  29. 6 17
      drivers/iio/adc/ad7793.c
  30. 7 16
      drivers/iio/adc/ad7887.c
  31. 7 13
      drivers/iio/adc/ad7923.c
  32. 57 56
      drivers/iio/adc/at91_adc.c
  33. 8 15
      drivers/iio/adc/exynos_adc.c
  34. 2 5
      drivers/iio/adc/lp8788_adc.c
  35. 5 10
      drivers/iio/adc/max1363.c
  36. 5 13
      drivers/iio/adc/mcp320x.c
  37. 581 0
      drivers/iio/adc/nau7802.c
  38. 5 13
      drivers/iio/adc/ti-adc081c.c
  39. 4 9
      drivers/iio/adc/ti_am335x_adc.c
  40. 1013 0
      drivers/iio/adc/twl6030-gpadc.c
  41. 2 7
      drivers/iio/adc/viperboard_adc.c
  42. 2 0
      drivers/iio/amplifiers/Kconfig
  43. 1 0
      drivers/iio/amplifiers/Makefile
  44. 3 10
      drivers/iio/amplifiers/ad8366.c
  45. 1 0
      drivers/iio/common/Makefile
  46. 36 5
      drivers/iio/common/st_sensors/st_sensors_core.c
  47. 23 21
      drivers/iio/dac/Kconfig
  48. 1 0
      drivers/iio/dac/Makefile
  49. 6 15
      drivers/iio/dac/ad5064.c
  50. 4 11
      drivers/iio/dac/ad5360.c
  51. 4 14
      drivers/iio/dac/ad5380.c
  52. 4 15
      drivers/iio/dac/ad5421.c
  53. 5 14
      drivers/iio/dac/ad5446.c
  54. 4 11
      drivers/iio/dac/ad5449.c
  55. 8 23
      drivers/iio/dac/ad5504.c
  56. 6 16
      drivers/iio/dac/ad5624r_spi.c
  57. 4 13
      drivers/iio/dac/ad5686.c
  58. 4 10
      drivers/iio/dac/ad5755.c
  59. 5 15
      drivers/iio/dac/ad5764.c
  60. 9 26
      drivers/iio/dac/ad5791.c
  61. 8 23
      drivers/iio/dac/ad7303.c
  62. 4 13
      drivers/iio/dac/max517.c
  63. 154 23
      drivers/iio/dac/mcp4725.c
  64. 1 0
      drivers/iio/frequency/Kconfig
  65. 1 0
      drivers/iio/frequency/Makefile
  66. 4 13
      drivers/iio/frequency/ad9523.c
  67. 9 22
      drivers/iio/frequency/adf4350.c
  68. 16 2
      drivers/iio/gyro/Kconfig
  69. 2 0
      drivers/iio/gyro/Makefile
  70. 4 17
      drivers/iio/gyro/adis16080.c
  71. 4 19
      drivers/iio/gyro/adis16130.c
  72. 3 7
      drivers/iio/gyro/adis16136.c
  73. 157 162
      drivers/iio/gyro/adis16260.c
  74. 4 11
      drivers/iio/gyro/adxrs450.c
  75. 16 25
      drivers/iio/gyro/hid-sensor-gyro-3d.c
  76. 4 11
      drivers/iio/gyro/itg3200_core.c
  77. 10 1
      drivers/iio/gyro/st_gyro.h
  78. 7 7
      drivers/iio/gyro/st_gyro_core.c
  79. 6 12
      drivers/iio/gyro/st_gyro_i2c.c
  80. 6 12
      drivers/iio/gyro/st_gyro_spi.c
  81. 2 5
      drivers/iio/iio_core_trigger.h
  82. 2 0
      drivers/iio/imu/Kconfig
  83. 1 0
      drivers/iio/imu/Makefile
  84. 3 7
      drivers/iio/imu/adis16400_core.c
  85. 3 7
      drivers/iio/imu/adis16480.c
  86. 11 18
      drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
  87. 49 2
      drivers/iio/industrialio-core.c
  88. 68 4
      drivers/iio/industrialio-trigger.c
  89. 23 11
      drivers/iio/light/Kconfig
  90. 3 1
      drivers/iio/light/Makefile
  91. 15 28
      drivers/iio/light/adjd_s311.c
  92. 512 0
      drivers/iio/light/apds9300.c
  93. 16 25
      drivers/iio/light/hid-sensor-als.c
  94. 2 5
      drivers/iio/light/lm3533-als.c
  95. 8 17
      drivers/iio/light/tsl2563.c
  96. 4 12
      drivers/iio/light/vcnl4000.c
  97. 4 2
      drivers/iio/magnetometer/Kconfig
  98. 1 0
      drivers/iio/magnetometer/Makefile
  99. 18 25
      drivers/iio/magnetometer/hid-sensor-magn-3d.c
  100. 2 1
      drivers/iio/magnetometer/st_magn.h

+ 19 - 0
Documentation/ABI/testing/sysfs-bus-iio

@@ -351,6 +351,7 @@ Description:
 		6kohm_to_gnd: connected to ground via a 6kOhm resistor,
 		6kohm_to_gnd: connected to ground via a 6kOhm resistor,
 		20kohm_to_gnd: connected to ground via a 20kOhm resistor,
 		20kohm_to_gnd: connected to ground via a 20kOhm resistor,
 		100kohm_to_gnd: connected to ground via an 100kOhm resistor,
 		100kohm_to_gnd: connected to ground via an 100kOhm resistor,
+		500kohm_to_gnd: connected to ground via a 500kOhm resistor,
 		three_state: left floating.
 		three_state: left floating.
 		For a list of available output power down options read
 		For a list of available output power down options read
 		outX_powerdown_mode_available. If Y is not present the
 		outX_powerdown_mode_available. If Y is not present the
@@ -792,3 +793,21 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 Description:
 		This attribute is used to read the amount of quadrature error
 		This attribute is used to read the amount of quadrature error
 		present in the device at a given time.
 		present in the device at a given time.
+
+What:		/sys/.../iio:deviceX/in_accelX_power_mode
+KernelVersion:	3.11
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Specifies the chip power mode.
+		low_noise: reduce noise level from ADC,
+		low_power: enable low current consumption.
+		For a list of available output power modes read
+		in_accel_power_mode_available.
+
+What:		/sys/bus/iio/devices/iio:deviceX/store_eeprom
+KernelVersion:	3.4.0
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Writing '1' stores the current device configuration into
+		on-chip EEPROM. After power-up or chip reset the device will
+		automatically load the saved configuration.

+ 0 - 8
Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523

@@ -18,14 +18,6 @@ Description:
 		Reading returns either '1' or '0'. '1' means that the
 		Reading returns either '1' or '0'. '1' means that the
 		pllY is locked.
 		pllY is locked.
 
 
-What:		/sys/bus/iio/devices/iio:deviceX/store_eeprom
-KernelVersion:	3.4.0
-Contact:	linux-iio@vger.kernel.org
-Description:
-		Writing '1' stores the current device configuration into
-		on-chip EEPROM. After power-up or chip reset the device will
-		automatically load the saved configuration.
-
 What:		/sys/bus/iio/devices/iio:deviceX/sync_dividers
 What:		/sys/bus/iio/devices/iio:deviceX/sync_dividers
 KernelVersion:	3.4.0
 KernelVersion:	3.4.0
 Contact:	linux-iio@vger.kernel.org
 Contact:	linux-iio@vger.kernel.org

+ 1 - 1
Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350

@@ -18,4 +18,4 @@ Description:
 		adjust the reference frequency accordingly.
 		adjust the reference frequency accordingly.
 		The value written has no effect until out_altvoltageY_frequency
 		The value written has no effect until out_altvoltageY_frequency
 		is updated. Consider to use out_altvoltageY_powerdown to power
 		is updated. Consider to use out_altvoltageY_powerdown to power
-		down the PLL and it's RFOut buffers during REFin changes.
+		down the PLL and its RFOut buffers during REFin changes.

+ 2 - 5
Documentation/devicetree/bindings/arm/atmel-adc.txt

@@ -1,18 +1,15 @@
 * AT91's Analog to Digital Converter (ADC)
 * AT91's Analog to Digital Converter (ADC)
 
 
 Required properties:
 Required properties:
-  - compatible: Should be "atmel,at91sam9260-adc"
+  - compatible: Should be "atmel,<chip>-adc"
+    <chip> can be "at91sam9260", "at91sam9g45" or "at91sam9x5"
   - reg: Should contain ADC registers location and length
   - reg: Should contain ADC registers location and length
   - interrupts: Should contain the IRQ line for the ADC
   - interrupts: Should contain the IRQ line for the ADC
-  - atmel,adc-channel-base: Offset of the first channel data register
   - atmel,adc-channels-used: Bitmask of the channels muxed and enable for this
   - atmel,adc-channels-used: Bitmask of the channels muxed and enable for this
     device
     device
-  - atmel,adc-drdy-mask: Mask of the DRDY interruption in the ADC
   - atmel,adc-num-channels: Number of channels available in the ADC
   - atmel,adc-num-channels: Number of channels available in the ADC
   - atmel,adc-startup-time: Startup Time of the ADC in microseconds as
   - atmel,adc-startup-time: Startup Time of the ADC in microseconds as
     defined in the datasheet
     defined in the datasheet
-  - atmel,adc-status-register: Offset of the Interrupt Status Register
-  - atmel,adc-trigger-register: Offset of the Trigger Register
   - atmel,adc-vref: Reference voltage in millivolts for the conversions
   - atmel,adc-vref: Reference voltage in millivolts for the conversions
   - atmel,adc-res: List of resolution in bits supported by the ADC. List size
   - atmel,adc-res: List of resolution in bits supported by the ADC. List size
 		   must be two at least.
 		   must be two at least.

+ 24 - 0
Documentation/devicetree/bindings/iio/accel/bma180.txt

@@ -0,0 +1,24 @@
+* Bosch BMA180 triaxial acceleration sensor
+
+http://omapworld.com/BMA180_111_1002839.pdf
+
+Required properties:
+
+  - compatible : should be "bosch,bma180"
+  - reg : the I2C address of the sensor
+
+Optional properties:
+
+  - interrupt-parent : should be the phandle for the interrupt controller
+
+  - interrupts : interrupt mapping for GPIO IRQ, it should by configured with
+		flags IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING
+
+Example:
+
+bma180@40 {
+	compatible = "bosch,bma180";
+	reg = <0x40>;
+	interrupt-parent = <&gpio6>;
+	interrupts = <18 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>;
+};

+ 18 - 0
Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt

@@ -0,0 +1,18 @@
+* Nuvoton NAU7802 Analog to Digital Converter (ADC)
+
+Required properties:
+  - compatible: Should be "nuvoton,nau7802"
+  - reg: Should contain the ADC I2C address
+
+Optional properties:
+  - nuvoton,vldo: Internal reference voltage in millivolts to be
+    configured valid values are between 2400 mV and 4500 mV.
+  - interrupts: IRQ line for the ADC. If not used the driver will use
+    polling.
+
+Example:
+adc2: nau7802@2a {
+	compatible = "nuvoton,nau7802";
+	reg = <0x2a>;
+	nuvoton,vldo = <3000>;
+};

+ 22 - 0
Documentation/devicetree/bindings/iio/light/apds9300.txt

@@ -0,0 +1,22 @@
+* Avago APDS9300 ambient light sensor
+
+http://www.avagotech.com/docs/AV02-1077EN
+
+Required properties:
+
+  - compatible : should be "avago,apds9300"
+  - reg : the I2C address of the sensor
+
+Optional properties:
+
+  - interrupt-parent : should be the phandle for the interrupt controller
+  - interrupts : interrupt mapping for GPIO IRQ
+
+Example:
+
+apds9300@39 {
+	compatible = "avago,apds9300";
+	reg = <0x39>;
+	interrupt-parent = <&gpio2>;
+	interrupts = <29 8>;
+};

+ 1 - 0
Documentation/devicetree/bindings/vendor-prefixes.txt

@@ -11,6 +11,7 @@ amcc	Applied Micro Circuits Corporation (APM, formally AMCC)
 apm	Applied Micro Circuits Corporation (APM)
 apm	Applied Micro Circuits Corporation (APM)
 arm	ARM Ltd.
 arm	ARM Ltd.
 atmel	Atmel Corporation
 atmel	Atmel Corporation
+avago	Avago Technologies
 bosch	Bosch Sensortec GmbH
 bosch	Bosch Sensortec GmbH
 brcm	Broadcom Corporation
 brcm	Broadcom Corporation
 cavium	Cavium, Inc.
 cavium	Cavium, Inc.

+ 6 - 0
Documentation/driver-model/devres.txt

@@ -237,6 +237,12 @@ MEM
   devm_kzalloc()
   devm_kzalloc()
   devm_kfree()
   devm_kfree()
 
 
+IIO
+  devm_iio_device_alloc()
+  devm_iio_device_free()
+  devm_iio_trigger_alloc()
+  devm_iio_trigger_free()
+
 IO region
 IO region
   devm_request_region()
   devm_request_region()
   devm_request_mem_region()
   devm_request_mem_region()

+ 3 - 3
MAINTAINERS

@@ -7890,11 +7890,11 @@ S:	Maintained
 F:	drivers/staging/nvec/
 F:	drivers/staging/nvec/
 
 
 STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON)
 STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON)
-M:	Andres Salomon <dilinger@queued.net>
-M:	Chris Ball <cjb@laptop.org>
+M:	Jens Frederich <jfrederich@gmail.com>
+M:	Daniel Drake <dsd@laptop.org>
 M:	Jon Nettleton <jon.nettleton@gmail.com>
 M:	Jon Nettleton <jon.nettleton@gmail.com>
 W:	http://wiki.laptop.org/go/DCON
 W:	http://wiki.laptop.org/go/DCON
-S:	Odd Fixes
+S:	Maintained
 F:	drivers/staging/olpc_dcon/
 F:	drivers/staging/olpc_dcon/
 
 
 STAGING - OZMO DEVICES USB OVER WIFI DRIVER
 STAGING - OZMO DEVICES USB OVER WIFI DRIVER

+ 14 - 2
arch/arm/mach-at91/include/mach/at91_adc.h

@@ -28,9 +28,12 @@
 #define			AT91_ADC_TRGSEL_EXTERNAL	(6 << 1)
 #define			AT91_ADC_TRGSEL_EXTERNAL	(6 << 1)
 #define		AT91_ADC_LOWRES		(1 << 4)	/* Low Resolution */
 #define		AT91_ADC_LOWRES		(1 << 4)	/* Low Resolution */
 #define		AT91_ADC_SLEEP		(1 << 5)	/* Sleep Mode */
 #define		AT91_ADC_SLEEP		(1 << 5)	/* Sleep Mode */
-#define		AT91_ADC_PRESCAL	(0x3f << 8)	/* Prescalar Rate Selection */
+#define		AT91_ADC_PRESCAL_9260	(0x3f << 8)	/* Prescalar Rate Selection */
+#define		AT91_ADC_PRESCAL_9G45	(0xff << 8)
 #define			AT91_ADC_PRESCAL_(x)	((x) << 8)
 #define			AT91_ADC_PRESCAL_(x)	((x) << 8)
-#define		AT91_ADC_STARTUP	(0x1f << 16)	/* Startup Up Time */
+#define		AT91_ADC_STARTUP_9260	(0x1f << 16)	/* Startup Up Time */
+#define		AT91_ADC_STARTUP_9G45	(0x7f << 16)
+#define		AT91_ADC_STARTUP_9X5	(0xf << 16)
 #define			AT91_ADC_STARTUP_(x)	((x) << 16)
 #define			AT91_ADC_STARTUP_(x)	((x) << 16)
 #define		AT91_ADC_SHTIM		(0xf  << 24)	/* Sample & Hold Time */
 #define		AT91_ADC_SHTIM		(0xf  << 24)	/* Sample & Hold Time */
 #define			AT91_ADC_SHTIM_(x)	((x) << 24)
 #define			AT91_ADC_SHTIM_(x)	((x) << 24)
@@ -48,6 +51,9 @@
 #define		AT91_ADC_ENDRX		(1 << 18)	/* End of RX Buffer */
 #define		AT91_ADC_ENDRX		(1 << 18)	/* End of RX Buffer */
 #define		AT91_ADC_RXFUFF		(1 << 19)	/* RX Buffer Full */
 #define		AT91_ADC_RXFUFF		(1 << 19)	/* RX Buffer Full */
 
 
+#define AT91_ADC_SR_9X5		0x30		/* Status Register for 9x5 */
+#define		AT91_ADC_SR_DRDY_9X5	(1 << 24)	/* Data Ready */
+
 #define AT91_ADC_LCDR		0x20		/* Last Converted Data Register */
 #define AT91_ADC_LCDR		0x20		/* Last Converted Data Register */
 #define		AT91_ADC_LDATA		(0x3ff)
 #define		AT91_ADC_LDATA		(0x3ff)
 
 
@@ -58,4 +64,10 @@
 #define AT91_ADC_CHR(n)		(0x30 + ((n) * 4))	/* Channel Data Register N */
 #define AT91_ADC_CHR(n)		(0x30 + ((n) * 4))	/* Channel Data Register N */
 #define		AT91_ADC_DATA		(0x3ff)
 #define		AT91_ADC_DATA		(0x3ff)
 
 
+#define AT91_ADC_CDR0_9X5	(0x50)			/* Channel Data Register 0 for 9X5 */
+
+#define AT91_ADC_TRGR_9260	AT91_ADC_MR
+#define AT91_ADC_TRGR_9G45	0x08
+#define AT91_ADC_TRGR_9X5	0xC0
+
 #endif
 #endif

+ 4 - 4
drivers/iio/Kconfig

@@ -23,15 +23,14 @@ if IIO_BUFFER
 config IIO_BUFFER_CB
 config IIO_BUFFER_CB
 boolean "IIO callback buffer used for push in-kernel interfaces"
 boolean "IIO callback buffer used for push in-kernel interfaces"
 	help
 	help
-	  Should be selected by any drivers that do-inkernel push
+	  Should be selected by any drivers that do in-kernel push
 	  usage.  That is, those where the data is pushed to the consumer.
 	  usage.  That is, those where the data is pushed to the consumer.
 
 
 config IIO_KFIFO_BUF
 config IIO_KFIFO_BUF
 	select IIO_TRIGGER
 	select IIO_TRIGGER
 	tristate "Industrial I/O buffering based on kfifo"
 	tristate "Industrial I/O buffering based on kfifo"
 	help
 	help
-	  A simple fifo based on kfifo.  Use this if you want a fifo
-	  rather than a ring buffer. Note that this currently provides
+	  A simple fifo based on kfifo.  Note that this currently provides
 	  no buffer events so it is up to userspace to work out how
 	  no buffer events so it is up to userspace to work out how
 	  often to read from the buffer.
 	  often to read from the buffer.
 
 
@@ -49,7 +48,7 @@ config IIO_TRIGGER
 	help
 	help
 	  Provides IIO core support for triggers.  Currently these
 	  Provides IIO core support for triggers.  Currently these
 	  are used to initialize capture of samples to push into
 	  are used to initialize capture of samples to push into
-	  ring buffers.  The triggers are effectively a 'capture
+	  buffers.  The triggers are effectively a 'capture
 	  data now' interrupt.
 	  data now' interrupt.
 
 
 config IIO_CONSUMERS_PER_TRIGGER
 config IIO_CONSUMERS_PER_TRIGGER
@@ -74,5 +73,6 @@ if IIO_TRIGGER
    source "drivers/iio/trigger/Kconfig"
    source "drivers/iio/trigger/Kconfig"
 endif #IIO_TRIGGER
 endif #IIO_TRIGGER
 source "drivers/iio/pressure/Kconfig"
 source "drivers/iio/pressure/Kconfig"
+source "drivers/iio/temperature/Kconfig"
 
 
 endif # IIO
 endif # IIO

+ 2 - 1
drivers/iio/Makefile

@@ -21,5 +21,6 @@ obj-y += frequency/
 obj-y += imu/
 obj-y += imu/
 obj-y += light/
 obj-y += light/
 obj-y += magnetometer/
 obj-y += magnetometer/
-obj-y += trigger/
 obj-y += pressure/
 obj-y += pressure/
+obj-y += temperature/
+obj-y += trigger/

+ 23 - 9
drivers/iio/accel/Kconfig

@@ -1,8 +1,22 @@
 #
 #
 # Accelerometer drivers
 # Accelerometer drivers
 #
 #
+# When adding new entries keep the list in alphabetical order
+
 menu "Accelerometers"
 menu "Accelerometers"
 
 
+config BMA180
+	tristate "Bosch BMA180 3-Axis Accelerometer Driver"
+	depends on I2C
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	  Say Y here if you want to build a driver for the Bosch BMA180
+	  triaxial acceleration sensor.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bma180.
+
 config HID_SENSOR_ACCEL_3D
 config HID_SENSOR_ACCEL_3D
 	depends on HID_SENSOR_HUB
 	depends on HID_SENSOR_HUB
 	select IIO_BUFFER
 	select IIO_BUFFER
@@ -14,13 +28,6 @@ config HID_SENSOR_ACCEL_3D
 	  Say yes here to build support for the HID SENSOR
 	  Say yes here to build support for the HID SENSOR
 	  accelerometers 3D.
 	  accelerometers 3D.
 
 
-config KXSD9
-	tristate "Kionix KXSD9 Accelerometer Driver"
-	depends on SPI
-	help
-	  Say yes here to build support for the Kionix KXSD9 accelerometer.
-	  Currently this only supports the device via an SPI interface.
-
 config IIO_ST_ACCEL_3AXIS
 config IIO_ST_ACCEL_3AXIS
 	tristate "STMicroelectronics accelerometers 3-Axis Driver"
 	tristate "STMicroelectronics accelerometers 3-Axis Driver"
 	depends on (I2C || SPI_MASTER) && SYSFS
 	depends on (I2C || SPI_MASTER) && SYSFS
@@ -33,8 +40,8 @@ config IIO_ST_ACCEL_3AXIS
 	  LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
 	  LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
 	  LIS331DLH, LSM303DL, LSM303DLM, LSM330.
 	  LIS331DLH, LSM303DL, LSM303DLM, LSM330.
 
 
-	  This driver can also be built as a module. If so, will be created
-	  these modules:
+	  This driver can also be built as a module. If so, these modules
+	  will be created:
 	  - st_accel (core functions for the driver [it is mandatory]);
 	  - st_accel (core functions for the driver [it is mandatory]);
 	  - st_accel_i2c (necessary for the I2C devices [optional*]);
 	  - st_accel_i2c (necessary for the I2C devices [optional*]);
 	  - st_accel_spi (necessary for the SPI devices [optional*]);
 	  - st_accel_spi (necessary for the SPI devices [optional*]);
@@ -51,4 +58,11 @@ config IIO_ST_ACCEL_SPI_3AXIS
 	depends on IIO_ST_ACCEL_3AXIS
 	depends on IIO_ST_ACCEL_3AXIS
 	depends on IIO_ST_SENSORS_SPI
 	depends on IIO_ST_SENSORS_SPI
 
 
+config KXSD9
+	tristate "Kionix KXSD9 Accelerometer Driver"
+	depends on SPI
+	help
+	  Say yes here to build support for the Kionix KXSD9 accelerometer.
+	  Currently this only supports the device via an SPI interface.
+
 endmenu
 endmenu

+ 3 - 2
drivers/iio/accel/Makefile

@@ -2,7 +2,10 @@
 # Makefile for industrial I/O accelerometer drivers
 # Makefile for industrial I/O accelerometer drivers
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
 obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
+obj-$(CONFIG_KXSD9)	+= kxsd9.o
 
 
 obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o
 obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o
 st_accel-y := st_accel_core.o
 st_accel-y := st_accel_core.o
@@ -10,5 +13,3 @@ st_accel-$(CONFIG_IIO_BUFFER) += st_accel_buffer.o
 
 
 obj-$(CONFIG_IIO_ST_ACCEL_I2C_3AXIS) += st_accel_i2c.o
 obj-$(CONFIG_IIO_ST_ACCEL_I2C_3AXIS) += st_accel_i2c.o
 obj-$(CONFIG_IIO_ST_ACCEL_SPI_3AXIS) += st_accel_spi.o
 obj-$(CONFIG_IIO_ST_ACCEL_SPI_3AXIS) += st_accel_spi.o
-
-obj-$(CONFIG_KXSD9)	+= kxsd9.o

+ 676 - 0
drivers/iio/accel/bma180.c

@@ -0,0 +1,676 @@
+/*
+ * bma180.c - IIO driver for Bosch BMA180 triaxial acceleration sensor
+ *
+ * Copyright 2013 Oleksandr Kravchenko <x0199363@ti.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define BMA180_DRV_NAME "bma180"
+#define BMA180_IRQ_NAME "bma180_event"
+
+/* Register set */
+#define BMA180_CHIP_ID		0x00 /* Need to distinguish BMA180 from other */
+#define BMA180_ACC_X_LSB	0x02 /* First of 6 registers of accel data */
+#define BMA180_CTRL_REG0	0x0d
+#define BMA180_RESET		0x10
+#define BMA180_BW_TCS		0x20
+#define BMA180_CTRL_REG3	0x21
+#define BMA180_TCO_Z		0x30
+#define BMA180_OFFSET_LSB1	0x35
+
+/* BMA180_CTRL_REG0 bits */
+#define BMA180_DIS_WAKE_UP	BIT(0) /* Disable wake up mode */
+#define BMA180_SLEEP		BIT(1) /* 1 - chip will sleep */
+#define BMA180_EE_W		BIT(4) /* Unlock writing to addr from 0x20 */
+#define BMA180_RESET_INT	BIT(6) /* Reset pending interrupts */
+
+/* BMA180_CTRL_REG3 bits */
+#define BMA180_NEW_DATA_INT	BIT(1) /* Intr every new accel data is ready */
+
+/* BMA180_OFFSET_LSB1 skipping mode bit */
+#define BMA180_SMP_SKIP		BIT(0)
+
+/* Bit masks for registers bit fields */
+#define BMA180_RANGE		0x0e /* Range of measured accel values*/
+#define BMA180_BW		0xf0 /* Accel bandwidth */
+#define BMA180_MODE_CONFIG	0x03 /* Config operation modes */
+
+/* We have to write this value in reset register to do soft reset */
+#define BMA180_RESET_VAL	0xb6
+
+#define BMA_180_ID_REG_VAL	0x03
+
+/* Chip power modes */
+#define BMA180_LOW_NOISE	0x00
+#define BMA180_LOW_POWER	0x03
+
+#define BMA180_LOW_NOISE_STR	"low_noise"
+#define BMA180_LOW_POWER_STR	"low_power"
+
+/* Defaults values */
+#define BMA180_DEF_PMODE	0
+#define BMA180_DEF_BW		20
+#define BMA180_DEF_SCALE	250
+
+/* Available values for sysfs */
+#define BMA180_FLP_FREQ_AVAILABLE \
+	"10 20 40 75 150 300"
+#define BMA180_SCALE_AVAILABLE \
+	"0.000130 0.000190 0.000250 0.000380 0.000500 0.000990 0.001980"
+
+struct bma180_data {
+	struct i2c_client *client;
+	struct iio_trigger *trig;
+	struct mutex mutex;
+	int sleep_state;
+	int scale;
+	int bw;
+	int pmode;
+	char *buff;
+};
+
+enum bma180_axis {
+	AXIS_X,
+	AXIS_Y,
+	AXIS_Z,
+};
+
+static int bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
+static int scale_table[] = { 130, 190, 250, 380, 500, 990, 1980 };
+
+static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis)
+{
+	u8 reg = BMA180_ACC_X_LSB + axis * 2;
+	int ret;
+
+	if (data->sleep_state)
+		return -EBUSY;
+
+	ret = i2c_smbus_read_word_data(data->client, reg);
+	if (ret < 0)
+		dev_err(&data->client->dev,
+			"failed to read accel_%c registers\n", 'x' + axis);
+
+	return ret;
+}
+
+static int bma180_set_bits(struct bma180_data *data, u8 reg, u8 mask, u8 val)
+{
+	int ret = i2c_smbus_read_byte_data(data->client, reg);
+	u8 reg_val = (ret & ~mask) | (val << (ffs(mask) - 1));
+
+	if (ret < 0)
+		return ret;
+
+	return i2c_smbus_write_byte_data(data->client, reg, reg_val);
+}
+
+static int bma180_reset_intr(struct bma180_data *data)
+{
+	int ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_RESET_INT, 1);
+
+	if (ret)
+		dev_err(&data->client->dev, "failed to reset interrupt\n");
+
+	return ret;
+}
+
+static int bma180_set_new_data_intr_state(struct bma180_data *data, int state)
+{
+	u8 reg_val = state ? BMA180_NEW_DATA_INT : 0x00;
+	int ret = i2c_smbus_write_byte_data(data->client, BMA180_CTRL_REG3,
+			reg_val);
+
+	if (ret)
+		goto err;
+	ret = bma180_reset_intr(data);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	dev_err(&data->client->dev,
+		"failed to set new data interrupt state %d\n", state);
+	return ret;
+}
+
+static int bma180_set_sleep_state(struct bma180_data *data, int state)
+{
+	int ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_SLEEP, state);
+
+	if (ret) {
+		dev_err(&data->client->dev,
+			"failed to set sleep state %d\n", state);
+		return ret;
+	}
+	data->sleep_state = state;
+
+	return 0;
+}
+
+static int bma180_set_ee_writing_state(struct bma180_data *data, int state)
+{
+	int ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_EE_W, state);
+
+	if (ret)
+		dev_err(&data->client->dev,
+			"failed to set ee writing state %d\n", state);
+
+	return ret;
+}
+
+static int bma180_set_bw(struct bma180_data *data, int val)
+{
+	int ret, i;
+
+	if (data->sleep_state)
+		return -EBUSY;
+
+	for (i = 0; i < ARRAY_SIZE(bw_table); ++i) {
+		if (bw_table[i] == val) {
+			ret = bma180_set_bits(data,
+					BMA180_BW_TCS, BMA180_BW, i);
+			if (ret) {
+				dev_err(&data->client->dev,
+					"failed to set bandwidth\n");
+				return ret;
+			}
+			data->bw = val;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int bma180_set_scale(struct bma180_data *data, int val)
+{
+	int ret, i;
+
+	if (data->sleep_state)
+		return -EBUSY;
+
+	for (i = 0; i < ARRAY_SIZE(scale_table); ++i)
+		if (scale_table[i] == val) {
+			ret = bma180_set_bits(data,
+					BMA180_OFFSET_LSB1, BMA180_RANGE, i);
+			if (ret) {
+				dev_err(&data->client->dev,
+					"failed to set scale\n");
+				return ret;
+			}
+			data->scale = val;
+			return 0;
+		}
+
+	return -EINVAL;
+}
+
+static int bma180_set_pmode(struct bma180_data *data, int mode)
+{
+	u8 reg_val = mode ? BMA180_LOW_POWER : BMA180_LOW_NOISE;
+	int ret = bma180_set_bits(data, BMA180_TCO_Z, BMA180_MODE_CONFIG,
+			reg_val);
+
+	if (ret) {
+		dev_err(&data->client->dev, "failed to set power mode\n");
+		return ret;
+	}
+	data->pmode = mode;
+
+	return 0;
+}
+
+static int bma180_soft_reset(struct bma180_data *data)
+{
+	int ret = i2c_smbus_write_byte_data(data->client,
+			BMA180_RESET, BMA180_RESET_VAL);
+
+	if (ret)
+		dev_err(&data->client->dev, "failed to reset the chip\n");
+
+	return ret;
+}
+
+static int bma180_chip_init(struct bma180_data *data)
+{
+	/* Try to read chip_id register. It must return 0x03. */
+	int ret = i2c_smbus_read_byte_data(data->client, BMA180_CHIP_ID);
+
+	if (ret < 0)
+		goto err;
+	if (ret != BMA_180_ID_REG_VAL) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	ret = bma180_soft_reset(data);
+	if (ret)
+		goto err;
+	/*
+	 * No serial transaction should occur within minimum 10 us
+	 * after soft_reset command
+	 */
+	msleep(20);
+
+	ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_DIS_WAKE_UP, 1);
+	if (ret)
+		goto err;
+	ret = bma180_set_ee_writing_state(data, 1);
+	if (ret)
+		goto err;
+	ret = bma180_set_new_data_intr_state(data, 0);
+	if (ret)
+		goto err;
+	ret = bma180_set_bits(data, BMA180_OFFSET_LSB1, BMA180_SMP_SKIP, 1);
+	if (ret)
+		goto err;
+	ret = bma180_set_pmode(data, BMA180_DEF_PMODE);
+	if (ret)
+		goto err;
+	ret = bma180_set_bw(data, BMA180_DEF_BW);
+	if (ret)
+		goto err;
+	ret = bma180_set_scale(data, BMA180_DEF_SCALE);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	dev_err(&data->client->dev, "failed to init the chip\n");
+	return ret;
+}
+
+static void bma180_chip_disable(struct bma180_data *data)
+{
+	if (bma180_set_new_data_intr_state(data, 0))
+		goto err;
+	if (bma180_set_ee_writing_state(data, 0))
+		goto err;
+	if (bma180_set_sleep_state(data, 1))
+		goto err;
+
+	return;
+
+err:
+	dev_err(&data->client->dev, "failed to disable the chip\n");
+}
+
+static IIO_CONST_ATTR(in_accel_filter_low_pass_3db_frequency_available,
+		BMA180_FLP_FREQ_AVAILABLE);
+static IIO_CONST_ATTR(in_accel_scale_available, BMA180_SCALE_AVAILABLE);
+
+static struct attribute *bma180_attributes[] = {
+	&iio_const_attr_in_accel_filter_low_pass_3db_frequency_available.dev_attr.attr,
+	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group bma180_attrs_group = {
+	.attrs = bma180_attributes,
+};
+
+static int bma180_read_raw(struct iio_dev *indio_dev,
+		struct iio_chan_spec const *chan, int *val, int *val2,
+		long mask)
+{
+	struct bma180_data *data = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		mutex_lock(&data->mutex);
+		if (iio_buffer_enabled(indio_dev))
+			ret = -EBUSY;
+		else
+			ret = bma180_get_acc_reg(data, chan->scan_index);
+		mutex_unlock(&data->mutex);
+		if (ret < 0)
+			return ret;
+		*val = (s16)ret >> chan->scan_type.shift;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+		*val = data->bw;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		*val = 0;
+		*val2 = data->scale;
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int bma180_write_raw(struct iio_dev *indio_dev,
+		struct iio_chan_spec const *chan, int val, int val2, long mask)
+{
+	struct bma180_data *data = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		if (val)
+			return -EINVAL;
+		mutex_lock(&data->mutex);
+		ret = bma180_set_scale(data, val2);
+		mutex_unlock(&data->mutex);
+		return ret;
+	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+		mutex_lock(&data->mutex);
+		ret = bma180_set_bw(data, val);
+		mutex_unlock(&data->mutex);
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int bma180_update_scan_mode(struct iio_dev *indio_dev,
+		const unsigned long *scan_mask)
+{
+	struct bma180_data *data = iio_priv(indio_dev);
+
+	if (data->buff)
+		devm_kfree(&indio_dev->dev, data->buff);
+	data->buff = devm_kzalloc(&indio_dev->dev,
+			indio_dev->scan_bytes, GFP_KERNEL);
+	if (!data->buff)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static const struct iio_info bma180_info = {
+	.attrs			= &bma180_attrs_group,
+	.read_raw		= bma180_read_raw,
+	.write_raw		= bma180_write_raw,
+	.update_scan_mode	= bma180_update_scan_mode,
+	.driver_module		= THIS_MODULE,
+};
+
+static const char * const bma180_power_modes[] = {
+	BMA180_LOW_NOISE_STR,
+	BMA180_LOW_POWER_STR,
+};
+
+static int bma180_get_power_mode(struct iio_dev *indio_dev,
+		const struct iio_chan_spec *chan)
+{
+	struct bma180_data *data = iio_priv(indio_dev);
+
+	return data->pmode;
+}
+
+static int bma180_set_power_mode(struct iio_dev *indio_dev,
+		const struct iio_chan_spec *chan, unsigned int mode)
+{
+	struct bma180_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = bma180_set_pmode(data, mode);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static const struct iio_enum bma180_power_mode_enum = {
+	.items = bma180_power_modes,
+	.num_items = ARRAY_SIZE(bma180_power_modes),
+	.get = bma180_get_power_mode,
+	.set = bma180_set_power_mode,
+};
+
+static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
+	IIO_ENUM("power_mode", true, &bma180_power_mode_enum),
+	IIO_ENUM_AVAILABLE("power_mode", &bma180_power_mode_enum),
+	{ },
+};
+
+#define BMA180_CHANNEL(_index) {					\
+	.type = IIO_ACCEL,						\
+	.indexed = 1,							\
+	.channel = (_index),						\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |			\
+		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),	\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),		\
+	.scan_index = (_index),						\
+	.scan_type = IIO_ST('s', 14, 16, 2),				\
+	.ext_info = bma180_ext_info,					\
+}
+
+static const struct iio_chan_spec bma180_channels[] = {
+	BMA180_CHANNEL(AXIS_X),
+	BMA180_CHANNEL(AXIS_Y),
+	BMA180_CHANNEL(AXIS_Z),
+	IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static irqreturn_t bma180_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct bma180_data *data = iio_priv(indio_dev);
+	int bit, ret, i = 0;
+
+	mutex_lock(&data->mutex);
+	if (indio_dev->scan_timestamp) {
+		ret = indio_dev->scan_bytes / sizeof(s64) - 1;
+		((s64 *)data->buff)[ret] = iio_get_time_ns();
+	}
+
+	for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+			 indio_dev->masklength) {
+		ret = bma180_get_acc_reg(data, bit);
+		if (ret < 0) {
+			mutex_unlock(&data->mutex);
+			goto err;
+		}
+		((s16 *)data->buff)[i++] = ret;
+	}
+	mutex_unlock(&data->mutex);
+
+	iio_push_to_buffers(indio_dev, (u8 *)data->buff);
+err:
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+static int bma180_data_rdy_trigger_set_state(struct iio_trigger *trig,
+		bool state)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct bma180_data *data = iio_priv(indio_dev);
+
+	return bma180_set_new_data_intr_state(data, state);
+}
+
+static int bma180_trig_try_reen(struct iio_trigger *trig)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct bma180_data *data = iio_priv(indio_dev);
+
+	return bma180_reset_intr(data);
+}
+
+static const struct iio_trigger_ops bma180_trigger_ops = {
+	.set_trigger_state = bma180_data_rdy_trigger_set_state,
+	.try_reenable = bma180_trig_try_reen,
+	.owner = THIS_MODULE,
+};
+
+static int bma180_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct bma180_data *data;
+	struct iio_dev *indio_dev;
+	struct iio_trigger *trig;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+
+	ret = bma180_chip_init(data);
+	if (ret < 0)
+		goto err_chip_disable;
+
+	mutex_init(&data->mutex);
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->channels = bma180_channels;
+	indio_dev->num_channels = ARRAY_SIZE(bma180_channels);
+	indio_dev->name = BMA180_DRV_NAME;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &bma180_info;
+
+	trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, indio_dev->id);
+	if (!trig) {
+		ret = -ENOMEM;
+		goto err_chip_disable;
+	}
+
+	ret = devm_request_irq(&client->dev, client->irq,
+			iio_trigger_generic_data_rdy_poll,
+			IRQF_TRIGGER_RISING, BMA180_IRQ_NAME, trig);
+	if (ret) {
+		dev_err(&client->dev, "unable to request IRQ\n");
+		goto err_trigger_free;
+	}
+
+	trig->dev.parent = &client->dev;
+	trig->ops = &bma180_trigger_ops;
+	iio_trigger_set_drvdata(trig, indio_dev);
+	data->trig = trig;
+	indio_dev->trig = trig;
+
+	ret = iio_trigger_register(trig);
+	if (ret)
+		goto err_trigger_free;
+
+	ret = iio_triggered_buffer_setup(indio_dev, NULL,
+			bma180_trigger_handler, NULL);
+	if (ret < 0) {
+		dev_err(&client->dev, "unable to setup iio triggered buffer\n");
+		goto err_trigger_unregister;
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0) {
+		dev_err(&client->dev, "unable to register iio device\n");
+		goto err_buffer_cleanup;
+	}
+
+	return 0;
+
+err_buffer_cleanup:
+	iio_triggered_buffer_cleanup(indio_dev);
+err_trigger_unregister:
+	iio_trigger_unregister(trig);
+err_trigger_free:
+	iio_trigger_free(trig);
+err_chip_disable:
+	bma180_chip_disable(data);
+
+	return ret;
+}
+
+static int bma180_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct bma180_data *data = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+	iio_trigger_unregister(data->trig);
+	iio_trigger_free(data->trig);
+
+	mutex_lock(&data->mutex);
+	bma180_chip_disable(data);
+	mutex_unlock(&data->mutex);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int bma180_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct bma180_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = bma180_set_sleep_state(data, 1);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static int bma180_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct bma180_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = bma180_set_sleep_state(data, 0);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
+#define BMA180_PM_OPS (&bma180_pm_ops)
+#else
+#define BMA180_PM_OPS NULL
+#endif
+
+static struct i2c_device_id bma180_id[] = {
+	{ BMA180_DRV_NAME, 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, bma180_id);
+
+static struct i2c_driver bma180_driver = {
+	.driver = {
+		.name	= BMA180_DRV_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= BMA180_PM_OPS,
+	},
+	.probe		= bma180_probe,
+	.remove		= bma180_remove,
+	.id_table	= bma180_id,
+};
+
+module_i2c_driver(bma180_driver);
+
+MODULE_AUTHOR("Kravchenko Oleksandr <x0199363@ti.com>");
+MODULE_AUTHOR("Texas Instruments, Inc.");
+MODULE_DESCRIPTION("Bosch BMA180 triaxial acceleration sensor");
+MODULE_LICENSE("GPL");

+ 18 - 25
drivers/iio/accel/hid-sensor-accel-3d.c

@@ -30,10 +30,6 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/triggered_buffer.h>
 #include "../common/hid-sensors/hid-sensor-trigger.h"
 #include "../common/hid-sensors/hid-sensor-trigger.h"
 
 
-/*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Accelerometer-3D: 0x200073*/
-#define DRIVER_NAME "HID-SENSOR-200073"
-
 enum accel_3d_channel {
 enum accel_3d_channel {
 	CHANNEL_SCAN_INDEX_X,
 	CHANNEL_SCAN_INDEX_X,
 	CHANNEL_SCAN_INDEX_Y,
 	CHANNEL_SCAN_INDEX_Y,
@@ -179,18 +175,10 @@ static int accel_3d_write_raw(struct iio_dev *indio_dev,
 	return ret;
 	return ret;
 }
 }
 
 
-static int accel_3d_write_raw_get_fmt(struct iio_dev *indio_dev,
-			       struct iio_chan_spec const *chan,
-			       long mask)
-{
-	return IIO_VAL_INT_PLUS_MICRO;
-}
-
 static const struct iio_info accel_3d_info = {
 static const struct iio_info accel_3d_info = {
 	.driver_module = THIS_MODULE,
 	.driver_module = THIS_MODULE,
 	.read_raw = &accel_3d_read_raw,
 	.read_raw = &accel_3d_read_raw,
 	.write_raw = &accel_3d_write_raw,
 	.write_raw = &accel_3d_write_raw,
-	.write_raw_get_fmt = &accel_3d_write_raw_get_fmt,
 };
 };
 
 
 /* Function to push data to buffer */
 /* Function to push data to buffer */
@@ -286,11 +274,11 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 	struct iio_chan_spec *channels;
 	struct iio_chan_spec *channels;
 
 
-	indio_dev = iio_device_alloc(sizeof(struct accel_3d_state));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&pdev->dev,
+					  sizeof(struct accel_3d_state));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
 	platform_set_drvdata(pdev, indio_dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 
 	accel_state = iio_priv(indio_dev);
 	accel_state = iio_priv(indio_dev);
@@ -302,15 +290,14 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
 					&accel_state->common_attributes);
 					&accel_state->common_attributes);
 	if (ret) {
 	if (ret) {
 		dev_err(&pdev->dev, "failed to setup common attributes\n");
 		dev_err(&pdev->dev, "failed to setup common attributes\n");
-		goto error_free_dev;
+		return ret;
 	}
 	}
 
 
 	channels = kmemdup(accel_3d_channels, sizeof(accel_3d_channels),
 	channels = kmemdup(accel_3d_channels, sizeof(accel_3d_channels),
 			   GFP_KERNEL);
 			   GFP_KERNEL);
 	if (!channels) {
 	if (!channels) {
-		ret = -ENOMEM;
 		dev_err(&pdev->dev, "failed to duplicate channels\n");
 		dev_err(&pdev->dev, "failed to duplicate channels\n");
-		goto error_free_dev;
+		return -ENOMEM;
 	}
 	}
 
 
 	ret = accel_3d_parse_report(pdev, hsdev, channels,
 	ret = accel_3d_parse_report(pdev, hsdev, channels,
@@ -367,9 +354,6 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 error_free_dev_mem:
 error_free_dev_mem:
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-error_free_dev:
-	iio_device_free(indio_dev);
-error_ret:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -384,14 +368,23 @@ static int hid_accel_3d_remove(struct platform_device *pdev)
 	hid_sensor_remove_trigger(indio_dev);
 	hid_sensor_remove_trigger(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+static struct platform_device_id hid_accel_3d_ids[] = {
+	{
+		/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+		.name = "HID-SENSOR-200073",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_accel_3d_ids);
+
 static struct platform_driver hid_accel_3d_platform_driver = {
 static struct platform_driver hid_accel_3d_platform_driver = {
+	.id_table = hid_accel_3d_ids,
 	.driver = {
 	.driver = {
-		.name	= DRIVER_NAME,
+		.name	= KBUILD_MODNAME,
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= hid_accel_3d_probe,
 	.probe		= hid_accel_3d_probe,

+ 5 - 12
drivers/iio/accel/kxsd9.c

@@ -224,11 +224,10 @@ static int kxsd9_probe(struct spi_device *spi)
 	struct kxsd9_state *st;
 	struct kxsd9_state *st;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
+
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
 
 
@@ -247,20 +246,14 @@ static int kxsd9_probe(struct spi_device *spi)
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
 	return 0;
 	return 0;
-
-error_free_dev:
-	iio_device_free(indio_dev);
-error_ret:
-	return ret;
 }
 }
 
 
 static int kxsd9_remove(struct spi_device *spi)
 static int kxsd9_remove(struct spi_device *spi)
 {
 {
 	iio_device_unregister(spi_get_drvdata(spi));
 	iio_device_unregister(spi_get_drvdata(spi));
-	iio_device_free(spi_get_drvdata(spi));
 
 
 	return 0;
 	return 0;
 }
 }

+ 10 - 1
drivers/iio/accel/st_accel.h

@@ -25,7 +25,16 @@
 #define LSM303DLM_ACCEL_DEV_NAME	"lsm303dlm_accel"
 #define LSM303DLM_ACCEL_DEV_NAME	"lsm303dlm_accel"
 #define LSM330_ACCEL_DEV_NAME		"lsm330_accel"
 #define LSM330_ACCEL_DEV_NAME		"lsm330_accel"
 
 
-int st_accel_common_probe(struct iio_dev *indio_dev);
+/**
+* struct st_sensors_platform_data - default accel platform data
+* @drdy_int_pin: default accel DRDY is available on INT1 pin.
+*/
+static const struct st_sensors_platform_data default_accel_pdata = {
+	.drdy_int_pin = 1,
+};
+
+int st_accel_common_probe(struct iio_dev *indio_dev,
+					struct st_sensors_platform_data *pdata);
 void st_accel_common_remove(struct iio_dev *indio_dev);
 void st_accel_common_remove(struct iio_dev *indio_dev);
 
 
 #ifdef CONFIG_IIO_BUFFER
 #ifdef CONFIG_IIO_BUFFER

+ 19 - 9
drivers/iio/accel/st_accel_core.c

@@ -65,7 +65,8 @@
 #define ST_ACCEL_1_BDU_ADDR			0x23
 #define ST_ACCEL_1_BDU_ADDR			0x23
 #define ST_ACCEL_1_BDU_MASK			0x80
 #define ST_ACCEL_1_BDU_MASK			0x80
 #define ST_ACCEL_1_DRDY_IRQ_ADDR		0x22
 #define ST_ACCEL_1_DRDY_IRQ_ADDR		0x22
-#define ST_ACCEL_1_DRDY_IRQ_MASK		0x10
+#define ST_ACCEL_1_DRDY_IRQ_INT1_MASK		0x10
+#define ST_ACCEL_1_DRDY_IRQ_INT2_MASK		0x08
 #define ST_ACCEL_1_MULTIREAD_BIT		true
 #define ST_ACCEL_1_MULTIREAD_BIT		true
 
 
 /* CUSTOM VALUES FOR SENSOR 2 */
 /* CUSTOM VALUES FOR SENSOR 2 */
@@ -89,7 +90,8 @@
 #define ST_ACCEL_2_BDU_ADDR			0x23
 #define ST_ACCEL_2_BDU_ADDR			0x23
 #define ST_ACCEL_2_BDU_MASK			0x80
 #define ST_ACCEL_2_BDU_MASK			0x80
 #define ST_ACCEL_2_DRDY_IRQ_ADDR		0x22
 #define ST_ACCEL_2_DRDY_IRQ_ADDR		0x22
-#define ST_ACCEL_2_DRDY_IRQ_MASK		0x02
+#define ST_ACCEL_2_DRDY_IRQ_INT1_MASK		0x02
+#define ST_ACCEL_2_DRDY_IRQ_INT2_MASK		0x10
 #define ST_ACCEL_2_MULTIREAD_BIT		true
 #define ST_ACCEL_2_MULTIREAD_BIT		true
 
 
 /* CUSTOM VALUES FOR SENSOR 3 */
 /* CUSTOM VALUES FOR SENSOR 3 */
@@ -121,7 +123,8 @@
 #define ST_ACCEL_3_BDU_ADDR			0x20
 #define ST_ACCEL_3_BDU_ADDR			0x20
 #define ST_ACCEL_3_BDU_MASK			0x08
 #define ST_ACCEL_3_BDU_MASK			0x08
 #define ST_ACCEL_3_DRDY_IRQ_ADDR		0x23
 #define ST_ACCEL_3_DRDY_IRQ_ADDR		0x23
-#define ST_ACCEL_3_DRDY_IRQ_MASK		0x80
+#define ST_ACCEL_3_DRDY_IRQ_INT1_MASK		0x80
+#define ST_ACCEL_3_DRDY_IRQ_INT2_MASK		0x00
 #define ST_ACCEL_3_IG1_EN_ADDR			0x23
 #define ST_ACCEL_3_IG1_EN_ADDR			0x23
 #define ST_ACCEL_3_IG1_EN_MASK			0x08
 #define ST_ACCEL_3_IG1_EN_MASK			0x08
 #define ST_ACCEL_3_MULTIREAD_BIT		false
 #define ST_ACCEL_3_MULTIREAD_BIT		false
@@ -224,7 +227,8 @@ static const struct st_sensors st_accel_sensors[] = {
 		},
 		},
 		.drdy_irq = {
 		.drdy_irq = {
 			.addr = ST_ACCEL_1_DRDY_IRQ_ADDR,
 			.addr = ST_ACCEL_1_DRDY_IRQ_ADDR,
-			.mask = ST_ACCEL_1_DRDY_IRQ_MASK,
+			.mask_int1 = ST_ACCEL_1_DRDY_IRQ_INT1_MASK,
+			.mask_int2 = ST_ACCEL_1_DRDY_IRQ_INT2_MASK,
 		},
 		},
 		.multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
 		.multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
 		.bootime = 2,
 		.bootime = 2,
@@ -285,7 +289,8 @@ static const struct st_sensors st_accel_sensors[] = {
 		},
 		},
 		.drdy_irq = {
 		.drdy_irq = {
 			.addr = ST_ACCEL_2_DRDY_IRQ_ADDR,
 			.addr = ST_ACCEL_2_DRDY_IRQ_ADDR,
-			.mask = ST_ACCEL_2_DRDY_IRQ_MASK,
+			.mask_int1 = ST_ACCEL_2_DRDY_IRQ_INT1_MASK,
+			.mask_int2 = ST_ACCEL_2_DRDY_IRQ_INT2_MASK,
 		},
 		},
 		.multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
 		.multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
 		.bootime = 2,
 		.bootime = 2,
@@ -358,7 +363,8 @@ static const struct st_sensors st_accel_sensors[] = {
 		},
 		},
 		.drdy_irq = {
 		.drdy_irq = {
 			.addr = ST_ACCEL_3_DRDY_IRQ_ADDR,
 			.addr = ST_ACCEL_3_DRDY_IRQ_ADDR,
-			.mask = ST_ACCEL_3_DRDY_IRQ_MASK,
+			.mask_int1 = ST_ACCEL_3_DRDY_IRQ_INT1_MASK,
+			.mask_int2 = ST_ACCEL_3_DRDY_IRQ_INT2_MASK,
 			.ig1 = {
 			.ig1 = {
 				.en_addr = ST_ACCEL_3_IG1_EN_ADDR,
 				.en_addr = ST_ACCEL_3_IG1_EN_ADDR,
 				.en_mask = ST_ACCEL_3_IG1_EN_MASK,
 				.en_mask = ST_ACCEL_3_IG1_EN_MASK,
@@ -443,7 +449,8 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
 #define ST_ACCEL_TRIGGER_OPS NULL
 #define ST_ACCEL_TRIGGER_OPS NULL
 #endif
 #endif
 
 
-int st_accel_common_probe(struct iio_dev *indio_dev)
+int st_accel_common_probe(struct iio_dev *indio_dev,
+				struct st_sensors_platform_data *plat_data)
 {
 {
 	int err;
 	int err;
 	struct st_sensor_data *adata = iio_priv(indio_dev);
 	struct st_sensor_data *adata = iio_priv(indio_dev);
@@ -465,7 +472,11 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
 						&adata->sensor->fs.fs_avl[0];
 						&adata->sensor->fs.fs_avl[0];
 	adata->odr = adata->sensor->odr.odr_avl[0].hz;
 	adata->odr = adata->sensor->odr.odr_avl[0].hz;
 
 
-	err = st_sensors_init_sensor(indio_dev);
+	if (!plat_data)
+		plat_data =
+			(struct st_sensors_platform_data *)&default_accel_pdata;
+
+	err = st_sensors_init_sensor(indio_dev, plat_data);
 	if (err < 0)
 	if (err < 0)
 		goto st_accel_common_probe_error;
 		goto st_accel_common_probe_error;
 
 
@@ -506,7 +517,6 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
 		st_sensors_deallocate_trigger(indio_dev);
 		st_sensors_deallocate_trigger(indio_dev);
 		st_accel_deallocate_ring(indio_dev);
 		st_accel_deallocate_ring(indio_dev);
 	}
 	}
-	iio_device_free(indio_dev);
 }
 }
 EXPORT_SYMBOL(st_accel_common_remove);
 EXPORT_SYMBOL(st_accel_common_remove);
 
 

+ 5 - 12
drivers/iio/accel/st_accel_i2c.c

@@ -25,27 +25,20 @@ static int st_accel_i2c_probe(struct i2c_client *client,
 	struct st_sensor_data *adata;
 	struct st_sensor_data *adata;
 	int err;
 	int err;
 
 
-	indio_dev = iio_device_alloc(sizeof(*adata));
-	if (indio_dev == NULL) {
-		err = -ENOMEM;
-		goto iio_device_alloc_error;
-	}
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adata));
+	if (!indio_dev)
+		return -ENOMEM;
 
 
 	adata = iio_priv(indio_dev);
 	adata = iio_priv(indio_dev);
 	adata->dev = &client->dev;
 	adata->dev = &client->dev;
 
 
 	st_sensors_i2c_configure(indio_dev, client, adata);
 	st_sensors_i2c_configure(indio_dev, client, adata);
 
 
-	err = st_accel_common_probe(indio_dev);
+	err = st_accel_common_probe(indio_dev, client->dev.platform_data);
 	if (err < 0)
 	if (err < 0)
-		goto st_accel_common_probe_error;
+		return err;
 
 
 	return 0;
 	return 0;
-
-st_accel_common_probe_error:
-	iio_device_free(indio_dev);
-iio_device_alloc_error:
-	return err;
 }
 }
 
 
 static int st_accel_i2c_remove(struct i2c_client *client)
 static int st_accel_i2c_remove(struct i2c_client *client)

+ 5 - 12
drivers/iio/accel/st_accel_spi.c

@@ -24,27 +24,20 @@ static int st_accel_spi_probe(struct spi_device *spi)
 	struct st_sensor_data *adata;
 	struct st_sensor_data *adata;
 	int err;
 	int err;
 
 
-	indio_dev = iio_device_alloc(sizeof(*adata));
-	if (indio_dev == NULL) {
-		err = -ENOMEM;
-		goto iio_device_alloc_error;
-	}
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adata));
+	if (!indio_dev)
+		return -ENOMEM;
 
 
 	adata = iio_priv(indio_dev);
 	adata = iio_priv(indio_dev);
 	adata->dev = &spi->dev;
 	adata->dev = &spi->dev;
 
 
 	st_sensors_spi_configure(indio_dev, spi, adata);
 	st_sensors_spi_configure(indio_dev, spi, adata);
 
 
-	err = st_accel_common_probe(indio_dev);
+	err = st_accel_common_probe(indio_dev, spi->dev.platform_data);
 	if (err < 0)
 	if (err < 0)
-		goto st_accel_common_probe_error;
+		return err;
 
 
 	return 0;
 	return 0;
-
-st_accel_common_probe_error:
-	iio_device_free(indio_dev);
-iio_device_alloc_error:
-	return err;
 }
 }
 
 
 static int st_accel_spi_remove(struct spi_device *spi)
 static int st_accel_spi_remove(struct spi_device *spi)

+ 43 - 18
drivers/iio/adc/Kconfig

@@ -1,6 +1,8 @@
 #
 #
 # ADC drivers
 # ADC drivers
 #
 #
+# When adding new entries keep the list in alphabetical order
+
 menu "Analog to digital converters"
 menu "Analog to digital converters"
 
 
 config AD_SIGMA_DELTA
 config AD_SIGMA_DELTA
@@ -30,17 +32,20 @@ config AD7298
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad7298.
 	  module will be called ad7298.
 
 
-config AD7923
-	tristate "Analog Devices AD7923 and similar ADCs driver"
+config AD7476
+	tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
 	depends on SPI
 	depends on SPI
 	select IIO_BUFFER
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	help
 	help
-	  Say yes here to build support for Analog Devices
-	  AD7904, AD7914, AD7923, AD7924 4 Channel ADCs.
+	  Say yes here to build support for Analog Devices AD7273, AD7274, AD7276,
+	  AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
+	  AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC).
+
+	  If unsure, say N (but it's safe to say "Y").
 
 
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
-	  module will be called ad7923.
+	  module will be called ad7476.
 
 
 config AD7791
 config AD7791
 	tristate "Analog Devices AD7791 ADC driver"
 	tristate "Analog Devices AD7791 ADC driver"
@@ -66,33 +71,30 @@ config AD7793
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called AD7793.
 	  module will be called AD7793.
 
 
-config AD7476
-	tristate "Analog Devices AD7476 and similar 1-channel ADCs driver"
+config AD7887
+	tristate "Analog Devices AD7887 ADC driver"
 	depends on SPI
 	depends on SPI
 	select IIO_BUFFER
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	help
 	help
-	  Say yes here to build support for Analog Devices AD7273, AD7274, AD7276,
-	  AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
-	  AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC).
-
+	  Say yes here to build support for Analog Devices
+	  AD7887 SPI analog to digital converter (ADC).
 	  If unsure, say N (but it's safe to say "Y").
 	  If unsure, say N (but it's safe to say "Y").
 
 
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
-	  module will be called ad7476.
+	  module will be called ad7887.
 
 
-config AD7887
-	tristate "Analog Devices AD7887 ADC driver"
+config AD7923
+	tristate "Analog Devices AD7923 and similar ADCs driver"
 	depends on SPI
 	depends on SPI
 	select IIO_BUFFER
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	help
 	help
 	  Say yes here to build support for Analog Devices
 	  Say yes here to build support for Analog Devices
-	  AD7887 SPI analog to digital converter (ADC).
-	  If unsure, say N (but it's safe to say "Y").
+	  AD7904, AD7914, AD7923, AD7924 4 Channel ADCs.
 
 
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
-	  module will be called ad7887.
+	  module will be called ad7923.
 
 
 config AT91_ADC
 config AT91_ADC
 	tristate "Atmel AT91 ADC"
 	tristate "Atmel AT91 ADC"
@@ -143,6 +145,15 @@ config MCP320X
 	  This driver can also be built as a module. If so, the module will be
 	  This driver can also be built as a module. If so, the module will be
 	  called mcp320x.
 	  called mcp320x.
 
 
+config NAU7802
+	tristate "Nuvoton NAU7802 ADC driver"
+	depends on I2C
+	help
+	  Say yes here to build support for Nuvoton NAU7802 ADC.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called nau7802.
+
 config TI_ADC081C
 config TI_ADC081C
 	tristate "Texas Instruments ADC081C021/027"
 	tristate "Texas Instruments ADC081C021/027"
 	depends on I2C
 	depends on I2C
@@ -154,12 +165,26 @@ config TI_ADC081C
 	  called ti-adc081c.
 	  called ti-adc081c.
 
 
 config TI_AM335X_ADC
 config TI_AM335X_ADC
-	tristate "TI's ADC driver"
+	tristate "TI's AM335X ADC driver"
 	depends on MFD_TI_AM335X_TSCADC
 	depends on MFD_TI_AM335X_TSCADC
 	help
 	help
 	  Say yes here to build support for Texas Instruments ADC
 	  Say yes here to build support for Texas Instruments ADC
 	  driver which is also a MFD client.
 	  driver which is also a MFD client.
 
 
+config TWL6030_GPADC
+	tristate "TWL6030 GPADC (General Purpose A/D Converter) Support"
+	depends on TWL4030_CORE
+	default n
+	help
+	  Say yes here if you want support for the TWL6030/TWL6032 General
+	  Purpose A/D Converter. This will add support for battery type
+	  detection, battery voltage and temperature measurement, die
+	  temperature measurement, system supply voltage, audio accessory,
+	  USB ID detection.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called twl6030-gpadc.
+
 config VIPERBOARD_ADC
 config VIPERBOARD_ADC
 	tristate "Viperboard ADC support"
 	tristate "Viperboard ADC support"
 	depends on MFD_VIPERBOARD && USB
 	depends on MFD_VIPERBOARD && USB

+ 3 - 0
drivers/iio/adc/Makefile

@@ -2,6 +2,7 @@
 # Makefile for IIO ADC drivers
 # Makefile for IIO ADC drivers
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
 obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
 obj-$(CONFIG_AD7266) += ad7266.o
 obj-$(CONFIG_AD7266) += ad7266.o
 obj-$(CONFIG_AD7298) += ad7298.o
 obj-$(CONFIG_AD7298) += ad7298.o
@@ -15,6 +16,8 @@ obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
+obj-$(CONFIG_NAU7802) += nau7802.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
+obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o

+ 4 - 12
drivers/iio/adc/ad7266.c

@@ -399,17 +399,17 @@ static int ad7266_probe(struct spi_device *spi)
 	unsigned int i;
 	unsigned int i;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 
 
-	st->reg = regulator_get(&spi->dev, "vref");
+	st->reg = devm_regulator_get(&spi->dev, "vref");
 	if (!IS_ERR_OR_NULL(st->reg)) {
 	if (!IS_ERR_OR_NULL(st->reg)) {
 		ret = regulator_enable(st->reg);
 		ret = regulator_enable(st->reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 
 
 		ret = regulator_get_voltage(st->reg);
 		ret = regulator_get_voltage(st->reg);
 		if (ret < 0)
 		if (ret < 0)
@@ -489,11 +489,6 @@ static int ad7266_probe(struct spi_device *spi)
 error_disable_reg:
 error_disable_reg:
 	if (!IS_ERR_OR_NULL(st->reg))
 	if (!IS_ERR_OR_NULL(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-error_put_reg:
-	if (!IS_ERR_OR_NULL(st->reg))
-		regulator_put(st->reg);
-
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -507,11 +502,8 @@ static int ad7266_remove(struct spi_device *spi)
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	if (!st->fixed_addr)
 	if (!st->fixed_addr)
 		gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
 		gpio_free_array(st->gpios, ARRAY_SIZE(st->gpios));
-	if (!IS_ERR_OR_NULL(st->reg)) {
+	if (!IS_ERR_OR_NULL(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-		regulator_put(st->reg);
-	}
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 8 - 16
drivers/iio/adc/ad7298.c

@@ -296,9 +296,10 @@ static int ad7298_probe(struct spi_device *spi)
 {
 {
 	struct ad7298_platform_data *pdata = spi->dev.platform_data;
 	struct ad7298_platform_data *pdata = spi->dev.platform_data;
 	struct ad7298_state *st;
 	struct ad7298_state *st;
-	struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+	struct iio_dev *indio_dev;
 	int ret;
 	int ret;
 
 
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -308,14 +309,13 @@ static int ad7298_probe(struct spi_device *spi)
 		st->ext_ref = AD7298_EXTREF;
 		st->ext_ref = AD7298_EXTREF;
 
 
 	if (st->ext_ref) {
 	if (st->ext_ref) {
-		st->reg = regulator_get(&spi->dev, "vref");
-		if (IS_ERR(st->reg)) {
-			ret = PTR_ERR(st->reg);
-			goto error_free;
-		}
+		st->reg = devm_regulator_get(&spi->dev, "vref");
+		if (IS_ERR(st->reg))
+			return PTR_ERR(st->reg);
+
 		ret = regulator_enable(st->reg);
 		ret = regulator_enable(st->reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 	}
 	}
 
 
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
@@ -361,11 +361,6 @@ static int ad7298_probe(struct spi_device *spi)
 error_disable_reg:
 error_disable_reg:
 	if (st->ext_ref)
 	if (st->ext_ref)
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-error_put_reg:
-	if (st->ext_ref)
-		regulator_put(st->reg);
-error_free:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -377,11 +372,8 @@ static int ad7298_remove(struct spi_device *spi)
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
-	if (st->ext_ref) {
+	if (st->ext_ref)
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-		regulator_put(st->reg);
-	}
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 8 - 18
drivers/iio/adc/ad7476.c

@@ -213,24 +213,21 @@ static int ad7476_probe(struct spi_device *spi)
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
+
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 	st->chip_info =
 	st->chip_info =
 		&ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
 		&ad7476_chip_info_tbl[spi_get_device_id(spi)->driver_data];
 
 
-	st->reg = regulator_get(&spi->dev, "vcc");
-	if (IS_ERR(st->reg)) {
-		ret = PTR_ERR(st->reg);
-		goto error_free_dev;
-	}
+	st->reg = devm_regulator_get(&spi->dev, "vcc");
+	if (IS_ERR(st->reg))
+		return PTR_ERR(st->reg);
 
 
 	ret = regulator_enable(st->reg);
 	ret = regulator_enable(st->reg);
 	if (ret)
 	if (ret)
-		goto error_put_reg;
+		return ret;
 
 
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
 
 
@@ -268,12 +265,7 @@ static int ad7476_probe(struct spi_device *spi)
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 error_disable_reg:
 error_disable_reg:
 	regulator_disable(st->reg);
 	regulator_disable(st->reg);
-error_put_reg:
-	regulator_put(st->reg);
-error_free_dev:
-	iio_device_free(indio_dev);
 
 
-error_ret:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -285,8 +277,6 @@ static int ad7476_remove(struct spi_device *spi)
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	regulator_disable(st->reg);
 	regulator_disable(st->reg);
-	regulator_put(st->reg);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 5 - 14
drivers/iio/adc/ad7791.c

@@ -361,21 +361,19 @@ static int ad7791_probe(struct spi_device *spi)
 		return -ENXIO;
 		return -ENXIO;
 	}
 	}
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (!indio_dev)
 	if (!indio_dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 
 
-	st->reg = regulator_get(&spi->dev, "refin");
-	if (IS_ERR(st->reg)) {
-		ret = PTR_ERR(st->reg);
-		goto err_iio_free;
-	}
+	st->reg = devm_regulator_get(&spi->dev, "refin");
+	if (IS_ERR(st->reg))
+		return PTR_ERR(st->reg);
 
 
 	ret = regulator_enable(st->reg);
 	ret = regulator_enable(st->reg);
 	if (ret)
 	if (ret)
-		goto error_put_reg;
+		return ret;
 
 
 	st->info = &ad7791_chip_infos[spi_get_device_id(spi)->driver_data];
 	st->info = &ad7791_chip_infos[spi_get_device_id(spi)->driver_data];
 	ad_sd_init(&st->sd, indio_dev, spi, &ad7791_sigma_delta_info);
 	ad_sd_init(&st->sd, indio_dev, spi, &ad7791_sigma_delta_info);
@@ -410,10 +408,6 @@ static int ad7791_probe(struct spi_device *spi)
 	ad_sd_cleanup_buffer_and_trigger(indio_dev);
 	ad_sd_cleanup_buffer_and_trigger(indio_dev);
 error_disable_reg:
 error_disable_reg:
 	regulator_disable(st->reg);
 	regulator_disable(st->reg);
-error_put_reg:
-	regulator_put(st->reg);
-err_iio_free:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -427,9 +421,6 @@ static int ad7791_remove(struct spi_device *spi)
 	ad_sd_cleanup_buffer_and_trigger(indio_dev);
 	ad_sd_cleanup_buffer_and_trigger(indio_dev);
 
 
 	regulator_disable(st->reg);
 	regulator_disable(st->reg);
-	regulator_put(st->reg);
-
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 6 - 17
drivers/iio/adc/ad7793.c

@@ -757,7 +757,7 @@ static int ad7793_probe(struct spi_device *spi)
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -766,15 +766,13 @@ static int ad7793_probe(struct spi_device *spi)
 	ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
 	ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
 
 
 	if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
 	if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
-		st->reg = regulator_get(&spi->dev, "refin");
-		if (IS_ERR(st->reg)) {
-			ret = PTR_ERR(st->reg);
-			goto error_device_free;
-		}
+		st->reg = devm_regulator_get(&spi->dev, "refin");
+		if (IS_ERR(st->reg))
+			return PTR_ERR(st->reg);
 
 
 		ret = regulator_enable(st->reg);
 		ret = regulator_enable(st->reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 
 
 		vref_mv = regulator_get_voltage(st->reg);
 		vref_mv = regulator_get_voltage(st->reg);
 		if (vref_mv < 0) {
 		if (vref_mv < 0) {
@@ -818,11 +816,6 @@ static int ad7793_probe(struct spi_device *spi)
 error_disable_reg:
 error_disable_reg:
 	if (pdata->refsel != AD7793_REFSEL_INTERNAL)
 	if (pdata->refsel != AD7793_REFSEL_INTERNAL)
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-error_put_reg:
-	if (pdata->refsel != AD7793_REFSEL_INTERNAL)
-		regulator_put(st->reg);
-error_device_free:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -836,12 +829,8 @@ static int ad7793_remove(struct spi_device *spi)
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	ad_sd_cleanup_buffer_and_trigger(indio_dev);
 	ad_sd_cleanup_buffer_and_trigger(indio_dev);
 
 
-	if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
+	if (pdata->refsel != AD7793_REFSEL_INTERNAL)
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-		regulator_put(st->reg);
-	}
-
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 7 - 16
drivers/iio/adc/ad7887.c

@@ -237,25 +237,24 @@ static int ad7887_probe(struct spi_device *spi)
 {
 {
 	struct ad7887_platform_data *pdata = spi->dev.platform_data;
 	struct ad7887_platform_data *pdata = spi->dev.platform_data;
 	struct ad7887_state *st;
 	struct ad7887_state *st;
-	struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+	struct iio_dev *indio_dev;
 	uint8_t mode;
 	uint8_t mode;
 	int ret;
 	int ret;
 
 
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 
 
 	if (!pdata || !pdata->use_onchip_ref) {
 	if (!pdata || !pdata->use_onchip_ref) {
-		st->reg = regulator_get(&spi->dev, "vref");
-		if (IS_ERR(st->reg)) {
-			ret = PTR_ERR(st->reg);
-			goto error_free;
-		}
+		st->reg = devm_regulator_get(&spi->dev, "vref");
+		if (IS_ERR(st->reg))
+			return PTR_ERR(st->reg);
 
 
 		ret = regulator_enable(st->reg);
 		ret = regulator_enable(st->reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 	}
 	}
 
 
 	st->chip_info =
 	st->chip_info =
@@ -331,11 +330,6 @@ static int ad7887_probe(struct spi_device *spi)
 error_disable_reg:
 error_disable_reg:
 	if (st->reg)
 	if (st->reg)
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-error_put_reg:
-	if (st->reg)
-		regulator_put(st->reg);
-error_free:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -347,11 +341,8 @@ static int ad7887_remove(struct spi_device *spi)
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
-	if (st->reg) {
+	if (st->reg)
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-		regulator_put(st->reg);
-	}
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 7 - 13
drivers/iio/adc/ad7923.c

@@ -275,10 +275,11 @@ static const struct iio_info ad7923_info = {
 static int ad7923_probe(struct spi_device *spi)
 static int ad7923_probe(struct spi_device *spi)
 {
 {
 	struct ad7923_state *st;
 	struct ad7923_state *st;
-	struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+	struct iio_dev *indio_dev;
 	const struct ad7923_chip_info *info;
 	const struct ad7923_chip_info *info;
 	int ret;
 	int ret;
 
 
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -311,14 +312,13 @@ static int ad7923_probe(struct spi_device *spi)
 	spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg);
 	spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg);
 	spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
 	spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
 
 
-	st->reg = regulator_get(&spi->dev, "refin");
-	if (IS_ERR(st->reg)) {
-		ret = PTR_ERR(st->reg);
-		goto error_free;
-	}
+	st->reg = devm_regulator_get(&spi->dev, "refin");
+	if (IS_ERR(st->reg))
+		return PTR_ERR(st->reg);
+
 	ret = regulator_enable(st->reg);
 	ret = regulator_enable(st->reg);
 	if (ret)
 	if (ret)
-		goto error_put_reg;
+		return ret;
 
 
 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
 			&ad7923_trigger_handler, NULL);
 			&ad7923_trigger_handler, NULL);
@@ -335,10 +335,6 @@ static int ad7923_probe(struct spi_device *spi)
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 error_disable_reg:
 error_disable_reg:
 	regulator_disable(st->reg);
 	regulator_disable(st->reg);
-error_put_reg:
-	regulator_put(st->reg);
-error_free:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -351,8 +347,6 @@ static int ad7923_remove(struct spi_device *spi)
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	regulator_disable(st->reg);
 	regulator_disable(st->reg);
-	regulator_put(st->reg);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 57 - 56
drivers/iio/adc/at91_adc.c

@@ -39,6 +39,10 @@
 #define at91_adc_writel(st, reg, val) \
 #define at91_adc_writel(st, reg, val) \
 	(writel_relaxed(val, st->reg_base + reg))
 	(writel_relaxed(val, st->reg_base + reg))
 
 
+struct at91_adc_caps {
+	struct at91_adc_reg_desc registers;
+};
+
 struct at91_adc_state {
 struct at91_adc_state {
 	struct clk		*adc_clk;
 	struct clk		*adc_clk;
 	u16			*buffer;
 	u16			*buffer;
@@ -62,6 +66,7 @@ struct at91_adc_state {
 	u32			res;		/* resolution used for convertions */
 	u32			res;		/* resolution used for convertions */
 	bool			low_res;	/* the resolution corresponds to the lowest one */
 	bool			low_res;	/* the resolution corresponds to the lowest one */
 	wait_queue_head_t	wq_data_avail;
 	wait_queue_head_t	wq_data_avail;
+	struct at91_adc_caps	*caps;
 };
 };
 
 
 static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
 static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
@@ -429,6 +434,8 @@ static int at91_adc_of_get_resolution(struct at91_adc_state *st,
 	return ret;
 	return ret;
 }
 }
 
 
+static const struct of_device_id at91_adc_dt_ids[];
+
 static int at91_adc_probe_dt(struct at91_adc_state *st,
 static int at91_adc_probe_dt(struct at91_adc_state *st,
 			     struct platform_device *pdev)
 			     struct platform_device *pdev)
 {
 {
@@ -441,6 +448,9 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
 	if (!node)
 	if (!node)
 		return -EINVAL;
 		return -EINVAL;
 
 
+	st->caps = (struct at91_adc_caps *)
+		of_match_device(at91_adc_dt_ids, &pdev->dev)->data;
+
 	st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers");
 	st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers");
 
 
 	if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) {
 	if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) {
@@ -481,43 +491,7 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
 	if (ret)
 	if (ret)
 		goto error_ret;
 		goto error_ret;
 
 
-	st->registers = devm_kzalloc(&idev->dev,
-				     sizeof(struct at91_adc_reg_desc),
-				     GFP_KERNEL);
-	if (!st->registers) {
-		dev_err(&idev->dev, "Could not allocate register memory.\n");
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-
-	if (of_property_read_u32(node, "atmel,adc-channel-base", &prop)) {
-		dev_err(&idev->dev, "Missing adc-channel-base property in the DT.\n");
-		ret = -EINVAL;
-		goto error_ret;
-	}
-	st->registers->channel_base = prop;
-
-	if (of_property_read_u32(node, "atmel,adc-drdy-mask", &prop)) {
-		dev_err(&idev->dev, "Missing adc-drdy-mask property in the DT.\n");
-		ret = -EINVAL;
-		goto error_ret;
-	}
-	st->registers->drdy_mask = prop;
-
-	if (of_property_read_u32(node, "atmel,adc-status-register", &prop)) {
-		dev_err(&idev->dev, "Missing adc-status-register property in the DT.\n");
-		ret = -EINVAL;
-		goto error_ret;
-	}
-	st->registers->status_register = prop;
-
-	if (of_property_read_u32(node, "atmel,adc-trigger-register", &prop)) {
-		dev_err(&idev->dev, "Missing adc-trigger-register property in the DT.\n");
-		ret = -EINVAL;
-		goto error_ret;
-	}
-	st->registers->trigger_register = prop;
-
+	st->registers = &st->caps->registers;
 	st->trigger_number = of_get_child_count(node);
 	st->trigger_number = of_get_child_count(node);
 	st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number *
 	st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number *
 					sizeof(struct at91_adc_trigger),
 					sizeof(struct at91_adc_trigger),
@@ -589,11 +563,9 @@ static int at91_adc_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct resource *res;
 	u32 reg;
 	u32 reg;
 
 
-	idev = iio_device_alloc(sizeof(struct at91_adc_state));
-	if (idev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct at91_adc_state));
+	if (!idev)
+		return -ENOMEM;
 
 
 	st = iio_priv(idev);
 	st = iio_priv(idev);
 
 
@@ -604,8 +576,7 @@ static int at91_adc_probe(struct platform_device *pdev)
 
 
 	if (ret) {
 	if (ret) {
 		dev_err(&pdev->dev, "No platform data available.\n");
 		dev_err(&pdev->dev, "No platform data available.\n");
-		ret = -EINVAL;
-		goto error_free_device;
+		return -EINVAL;
 	}
 	}
 
 
 	platform_set_drvdata(pdev, idev);
 	platform_set_drvdata(pdev, idev);
@@ -618,16 +589,14 @@ static int at91_adc_probe(struct platform_device *pdev)
 	st->irq = platform_get_irq(pdev, 0);
 	st->irq = platform_get_irq(pdev, 0);
 	if (st->irq < 0) {
 	if (st->irq < 0) {
 		dev_err(&pdev->dev, "No IRQ ID is designated\n");
 		dev_err(&pdev->dev, "No IRQ ID is designated\n");
-		ret = -ENODEV;
-		goto error_free_device;
+		return -ENODEV;
 	}
 	}
 
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 
 	st->reg_base = devm_ioremap_resource(&pdev->dev, res);
 	st->reg_base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(st->reg_base)) {
 	if (IS_ERR(st->reg_base)) {
-		ret = PTR_ERR(st->reg_base);
-		goto error_free_device;
+		return PTR_ERR(st->reg_base);
 	}
 	}
 
 
 	/*
 	/*
@@ -642,7 +611,7 @@ static int at91_adc_probe(struct platform_device *pdev)
 			  idev);
 			  idev);
 	if (ret) {
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to allocate IRQ.\n");
 		dev_err(&pdev->dev, "Failed to allocate IRQ.\n");
-		goto error_free_device;
+		return ret;
 	}
 	}
 
 
 	st->clk = devm_clk_get(&pdev->dev, "adc_clk");
 	st->clk = devm_clk_get(&pdev->dev, "adc_clk");
@@ -703,8 +672,8 @@ static int at91_adc_probe(struct platform_device *pdev)
 	shtim = round_up((st->sample_hold_time * adc_clk /
 	shtim = round_up((st->sample_hold_time * adc_clk /
 			  1000000) - 1, 1);
 			  1000000) - 1, 1);
 
 
-	reg = AT91_ADC_PRESCAL_(prsc) & AT91_ADC_PRESCAL;
-	reg |= AT91_ADC_STARTUP_(ticks) & AT91_ADC_STARTUP;
+	reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask;
+	reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask;
 	if (st->low_res)
 	if (st->low_res)
 		reg |= AT91_ADC_LOWRES;
 		reg |= AT91_ADC_LOWRES;
 	if (st->sleep_mode)
 	if (st->sleep_mode)
@@ -752,9 +721,6 @@ static int at91_adc_probe(struct platform_device *pdev)
 	clk_disable_unprepare(st->clk);
 	clk_disable_unprepare(st->clk);
 error_free_irq:
 error_free_irq:
 	free_irq(st->irq, idev);
 	free_irq(st->irq, idev);
-error_free_device:
-	iio_device_free(idev);
-error_ret:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -769,14 +735,49 @@ static int at91_adc_remove(struct platform_device *pdev)
 	clk_disable_unprepare(st->adc_clk);
 	clk_disable_unprepare(st->adc_clk);
 	clk_disable_unprepare(st->clk);
 	clk_disable_unprepare(st->clk);
 	free_irq(st->irq, idev);
 	free_irq(st->irq, idev);
-	iio_device_free(idev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 #ifdef CONFIG_OF
 #ifdef CONFIG_OF
+static struct at91_adc_caps at91sam9260_caps = {
+	.registers = {
+		.channel_base = AT91_ADC_CHR(0),
+		.drdy_mask = AT91_ADC_DRDY,
+		.status_register = AT91_ADC_SR,
+		.trigger_register = AT91_ADC_TRGR_9260,
+		.mr_prescal_mask = AT91_ADC_PRESCAL_9260,
+		.mr_startup_mask = AT91_ADC_STARTUP_9260,
+	},
+};
+
+static struct at91_adc_caps at91sam9g45_caps = {
+	.registers = {
+		.channel_base = AT91_ADC_CHR(0),
+		.drdy_mask = AT91_ADC_DRDY,
+		.status_register = AT91_ADC_SR,
+		.trigger_register = AT91_ADC_TRGR_9G45,
+		.mr_prescal_mask = AT91_ADC_PRESCAL_9G45,
+		.mr_startup_mask = AT91_ADC_STARTUP_9G45,
+	},
+};
+
+static struct at91_adc_caps at91sam9x5_caps = {
+	.registers = {
+		.channel_base = AT91_ADC_CDR0_9X5,
+		.drdy_mask = AT91_ADC_SR_DRDY_9X5,
+		.status_register = AT91_ADC_SR_9X5,
+		.trigger_register = AT91_ADC_TRGR_9X5,
+		/* prescal mask is same as 9G45 */
+		.mr_prescal_mask = AT91_ADC_PRESCAL_9G45,
+		.mr_startup_mask = AT91_ADC_STARTUP_9X5,
+	},
+};
+
 static const struct of_device_id at91_adc_dt_ids[] = {
 static const struct of_device_id at91_adc_dt_ids[] = {
-	{ .compatible = "atmel,at91sam9260-adc" },
+	{ .compatible = "atmel,at91sam9260-adc", .data = &at91sam9260_caps },
+	{ .compatible = "atmel,at91sam9g45-adc", .data = &at91sam9g45_caps },
+	{ .compatible = "atmel,at91sam9x5-adc", .data = &at91sam9x5_caps },
 	{},
 	{},
 };
 };
 MODULE_DEVICE_TABLE(of, at91_adc_dt_ids);
 MODULE_DEVICE_TABLE(of, at91_adc_dt_ids);

+ 8 - 15
drivers/iio/adc/exynos_adc.c

@@ -33,6 +33,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_irq.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/consumer.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
+#include <linux/err.h>
 
 
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/machine.h>
 #include <linux/iio/machine.h>
@@ -261,7 +262,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
 	if (!np)
 	if (!np)
 		return ret;
 		return ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(struct exynos_adc));
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct exynos_adc));
 	if (!indio_dev) {
 	if (!indio_dev) {
 		dev_err(&pdev->dev, "failed allocating iio device\n");
 		dev_err(&pdev->dev, "failed allocating iio device\n");
 		return -ENOMEM;
 		return -ENOMEM;
@@ -271,23 +272,18 @@ static int exynos_adc_probe(struct platform_device *pdev)
 
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	info->regs = devm_ioremap_resource(&pdev->dev, mem);
 	info->regs = devm_ioremap_resource(&pdev->dev, mem);
-	if (IS_ERR(info->regs)) {
-		ret = PTR_ERR(info->regs);
-		goto err_iio;
-	}
+	if (IS_ERR(info->regs))
+		return PTR_ERR(info->regs);
 
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	info->enable_reg = devm_ioremap_resource(&pdev->dev, mem);
 	info->enable_reg = devm_ioremap_resource(&pdev->dev, mem);
-	if (IS_ERR(info->enable_reg)) {
-		ret = PTR_ERR(info->enable_reg);
-		goto err_iio;
-	}
+	if (IS_ERR(info->enable_reg))
+		return PTR_ERR(info->enable_reg);
 
 
 	irq = platform_get_irq(pdev, 0);
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 	if (irq < 0) {
 		dev_err(&pdev->dev, "no irq resource?\n");
 		dev_err(&pdev->dev, "no irq resource?\n");
-		ret = irq;
-		goto err_iio;
+		return irq;
 	}
 	}
 
 
 	info->irq = irq;
 	info->irq = irq;
@@ -299,7 +295,7 @@ static int exynos_adc_probe(struct platform_device *pdev)
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
 		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
 							info->irq);
 							info->irq);
-		goto err_iio;
+		return ret;
 	}
 	}
 
 
 	writel(1, info->enable_reg);
 	writel(1, info->enable_reg);
@@ -365,8 +361,6 @@ static int exynos_adc_probe(struct platform_device *pdev)
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 err_irq:
 err_irq:
 	free_irq(info->irq, info);
 	free_irq(info->irq, info);
-err_iio:
-	iio_device_free(indio_dev);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -382,7 +376,6 @@ static int exynos_adc_remove(struct platform_device *pdev)
 	writel(0, info->enable_reg);
 	writel(0, info->enable_reg);
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	free_irq(info->irq, info);
 	free_irq(info->irq, info);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 2 - 5
drivers/iio/adc/lp8788_adc.c

@@ -194,7 +194,7 @@ static int lp8788_adc_probe(struct platform_device *pdev)
 	struct lp8788_adc *adc;
 	struct lp8788_adc *adc;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*adc));
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
 	if (!indio_dev)
 	if (!indio_dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -205,7 +205,7 @@ static int lp8788_adc_probe(struct platform_device *pdev)
 	indio_dev->dev.of_node = pdev->dev.of_node;
 	indio_dev->dev.of_node = pdev->dev.of_node;
 	ret = lp8788_iio_map_register(indio_dev, lp->pdata, adc);
 	ret = lp8788_iio_map_register(indio_dev, lp->pdata, adc);
 	if (ret)
 	if (ret)
-		goto err_iio_map;
+		return ret;
 
 
 	mutex_init(&adc->lock);
 	mutex_init(&adc->lock);
 
 
@@ -226,8 +226,6 @@ static int lp8788_adc_probe(struct platform_device *pdev)
 
 
 err_iio_device:
 err_iio_device:
 	iio_map_array_unregister(indio_dev);
 	iio_map_array_unregister(indio_dev);
-err_iio_map:
-	iio_device_free(indio_dev);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -237,7 +235,6 @@ static int lp8788_adc_remove(struct platform_device *pdev)
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_map_array_unregister(indio_dev);
 	iio_map_array_unregister(indio_dev);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 5 - 10
drivers/iio/adc/max1363.c

@@ -1498,16 +1498,15 @@ static int max1363_probe(struct i2c_client *client,
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	struct regulator *vref;
 	struct regulator *vref;
 
 
-	indio_dev = iio_device_alloc(sizeof(struct max1363_state));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_out;
-	}
+	indio_dev = devm_iio_device_alloc(&client->dev,
+					  sizeof(struct max1363_state));
+	if (!indio_dev)
+		return -ENOMEM;
 
 
 	indio_dev->dev.of_node = client->dev.of_node;
 	indio_dev->dev.of_node = client->dev.of_node;
 	ret = iio_map_array_register(indio_dev, client->dev.platform_data);
 	ret = iio_map_array_register(indio_dev, client->dev.platform_data);
 	if (ret < 0)
 	if (ret < 0)
-		goto error_free_device;
+		return ret;
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 
 
@@ -1590,9 +1589,6 @@ static int max1363_probe(struct i2c_client *client,
 	regulator_disable(st->reg);
 	regulator_disable(st->reg);
 error_unregister_map:
 error_unregister_map:
 	iio_map_array_unregister(indio_dev);
 	iio_map_array_unregister(indio_dev);
-error_free_device:
-	iio_device_free(indio_dev);
-error_out:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1607,7 +1603,6 @@ static int max1363_remove(struct i2c_client *client)
 		regulator_disable(st->vref);
 		regulator_disable(st->vref);
 	regulator_disable(st->reg);
 	regulator_disable(st->reg);
 	iio_map_array_unregister(indio_dev);
 	iio_map_array_unregister(indio_dev);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 5 - 13
drivers/iio/adc/mcp320x.c

@@ -169,7 +169,7 @@ static int mcp320x_probe(struct spi_device *spi)
 	const struct mcp3208_chip_info *chip_info;
 	const struct mcp3208_chip_info *chip_info;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*adc));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
 	if (!indio_dev)
 	if (!indio_dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -193,15 +193,13 @@ static int mcp320x_probe(struct spi_device *spi)
 	spi_message_init_with_transfers(&adc->msg, adc->transfer,
 	spi_message_init_with_transfers(&adc->msg, adc->transfer,
 					ARRAY_SIZE(adc->transfer));
 					ARRAY_SIZE(adc->transfer));
 
 
-	adc->reg = regulator_get(&spi->dev, "vref");
-	if (IS_ERR(adc->reg)) {
-		ret = PTR_ERR(adc->reg);
-		goto iio_free;
-	}
+	adc->reg = devm_regulator_get(&spi->dev, "vref");
+	if (IS_ERR(adc->reg))
+		return PTR_ERR(adc->reg);
 
 
 	ret = regulator_enable(adc->reg);
 	ret = regulator_enable(adc->reg);
 	if (ret < 0)
 	if (ret < 0)
-		goto reg_free;
+		return ret;
 
 
 	mutex_init(&adc->lock);
 	mutex_init(&adc->lock);
 
 
@@ -213,10 +211,6 @@ static int mcp320x_probe(struct spi_device *spi)
 
 
 reg_disable:
 reg_disable:
 	regulator_disable(adc->reg);
 	regulator_disable(adc->reg);
-reg_free:
-	regulator_put(adc->reg);
-iio_free:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -228,8 +222,6 @@ static int mcp320x_remove(struct spi_device *spi)
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	regulator_disable(adc->reg);
 	regulator_disable(adc->reg);
-	regulator_put(adc->reg);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 581 - 0
drivers/iio/adc/nau7802.c

@@ -0,0 +1,581 @@
+/*
+ * Driver for the Nuvoton NAU7802 ADC
+ *
+ * Copyright 2013 Free Electrons
+ *
+ * Licensed under the GPLv2 or later.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/wait.h>
+#include <linux/log2.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define NAU7802_REG_PUCTRL	0x00
+#define NAU7802_PUCTRL_RR(x)		(x << 0)
+#define NAU7802_PUCTRL_RR_BIT		NAU7802_PUCTRL_RR(1)
+#define NAU7802_PUCTRL_PUD(x)		(x << 1)
+#define NAU7802_PUCTRL_PUD_BIT		NAU7802_PUCTRL_PUD(1)
+#define NAU7802_PUCTRL_PUA(x)		(x << 2)
+#define NAU7802_PUCTRL_PUA_BIT		NAU7802_PUCTRL_PUA(1)
+#define NAU7802_PUCTRL_PUR(x)		(x << 3)
+#define NAU7802_PUCTRL_PUR_BIT		NAU7802_PUCTRL_PUR(1)
+#define NAU7802_PUCTRL_CS(x)		(x << 4)
+#define NAU7802_PUCTRL_CS_BIT		NAU7802_PUCTRL_CS(1)
+#define NAU7802_PUCTRL_CR(x)		(x << 5)
+#define NAU7802_PUCTRL_CR_BIT		NAU7802_PUCTRL_CR(1)
+#define NAU7802_PUCTRL_AVDDS(x)		(x << 7)
+#define NAU7802_PUCTRL_AVDDS_BIT	NAU7802_PUCTRL_AVDDS(1)
+#define NAU7802_REG_CTRL1	0x01
+#define NAU7802_CTRL1_VLDO(x)		(x << 3)
+#define NAU7802_CTRL1_GAINS(x)		(x)
+#define NAU7802_CTRL1_GAINS_BITS	0x07
+#define NAU7802_REG_CTRL2	0x02
+#define NAU7802_CTRL2_CHS(x)		(x << 7)
+#define NAU7802_CTRL2_CRS(x)		(x << 4)
+#define NAU7802_SAMP_FREQ_320	0x07
+#define NAU7802_CTRL2_CHS_BIT		NAU7802_CTRL2_CHS(1)
+#define NAU7802_REG_ADC_B2	0x12
+#define NAU7802_REG_ADC_B1	0x13
+#define NAU7802_REG_ADC_B0	0x14
+#define NAU7802_REG_ADC_CTRL	0x15
+
+#define NAU7802_MIN_CONVERSIONS 6
+
+struct nau7802_state {
+	struct i2c_client	*client;
+	s32			last_value;
+	struct mutex		lock;
+	struct mutex		data_lock;
+	u32			vref_mv;
+	u32			conversion_count;
+	u32			min_conversions;
+	u8			sample_rate;
+	u32			scale_avail[8];
+	struct completion	value_ok;
+};
+
+#define NAU7802_CHANNEL(chan) {					\
+	.type = IIO_VOLTAGE,					\
+	.indexed = 1,						\
+	.channel = (chan),					\
+	.scan_index = (chan),					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
+				BIT(IIO_CHAN_INFO_SAMP_FREQ)	\
+}
+
+static const struct iio_chan_spec nau7802_chan_array[] = {
+	NAU7802_CHANNEL(0),
+	NAU7802_CHANNEL(1),
+};
+
+static const u16 nau7802_sample_freq_avail[] = {10, 20, 40, 80,
+						10, 10, 10, 320};
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 40 80 320");
+
+static struct attribute *nau7802_attributes[] = {
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group nau7802_attribute_group = {
+	.attrs = nau7802_attributes,
+};
+
+static int nau7802_set_gain(struct nau7802_state *st, int gain)
+{
+	int ret;
+
+	mutex_lock(&st->lock);
+	st->conversion_count = 0;
+
+	ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
+	if (ret < 0)
+		goto nau7802_sysfs_set_gain_out;
+	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
+					(ret & (~NAU7802_CTRL1_GAINS_BITS)) |
+					gain);
+
+nau7802_sysfs_set_gain_out:
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+
+static int nau7802_read_conversion(struct nau7802_state *st)
+{
+	int data;
+
+	mutex_lock(&st->data_lock);
+	data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B2);
+	if (data < 0)
+		goto nau7802_read_conversion_out;
+	st->last_value = data << 16;
+
+	data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B1);
+	if (data < 0)
+		goto nau7802_read_conversion_out;
+	st->last_value |= data << 8;
+
+	data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B0);
+	if (data < 0)
+		goto nau7802_read_conversion_out;
+	st->last_value |= data;
+
+	st->last_value = sign_extend32(st->last_value, 23);
+
+nau7802_read_conversion_out:
+	mutex_unlock(&st->data_lock);
+
+	return data;
+}
+
+/*
+ * Conversions are synchronised on the rising edge of NAU7802_PUCTRL_CS_BIT
+ */
+static int nau7802_sync(struct nau7802_state *st)
+{
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
+	if (ret < 0)
+		return ret;
+	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
+				ret | NAU7802_PUCTRL_CS_BIT);
+
+	return ret;
+}
+
+static irqreturn_t nau7802_eoc_trigger(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct nau7802_state *st = iio_priv(indio_dev);
+	int status;
+
+	status = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
+	if (status < 0)
+		return IRQ_HANDLED;
+
+	if (!(status & NAU7802_PUCTRL_CR_BIT))
+		return IRQ_NONE;
+
+	if (nau7802_read_conversion(st) < 0)
+		return IRQ_HANDLED;
+
+	/*
+	 * Because there is actually only one ADC for both channels, we have to
+	 * wait for enough conversions to happen before getting a significant
+	 * value when changing channels and the values are far apart.
+	 */
+	if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
+		st->conversion_count++;
+	if (st->conversion_count >= NAU7802_MIN_CONVERSIONS)
+		complete_all(&st->value_ok);
+
+	return IRQ_HANDLED;
+}
+
+static int nau7802_read_irq(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int *val)
+{
+	struct nau7802_state *st = iio_priv(indio_dev);
+	int ret;
+
+	INIT_COMPLETION(st->value_ok);
+	enable_irq(st->client->irq);
+
+	nau7802_sync(st);
+
+	/* read registers to ensure we flush everything */
+	ret = nau7802_read_conversion(st);
+	if (ret < 0)
+		goto read_chan_info_failure;
+
+	/* Wait for a conversion to finish */
+	ret = wait_for_completion_interruptible_timeout(&st->value_ok,
+			msecs_to_jiffies(1000));
+	if (ret == 0)
+		ret = -ETIMEDOUT;
+
+	if (ret < 0)
+		goto read_chan_info_failure;
+
+	disable_irq(st->client->irq);
+
+	*val = st->last_value;
+
+	return IIO_VAL_INT;
+
+read_chan_info_failure:
+	disable_irq(st->client->irq);
+
+	return ret;
+}
+
+static int nau7802_read_poll(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int *val)
+{
+	struct nau7802_state *st = iio_priv(indio_dev);
+	int ret;
+
+	nau7802_sync(st);
+
+	/* read registers to ensure we flush everything */
+	ret = nau7802_read_conversion(st);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Because there is actually only one ADC for both channels, we have to
+	 * wait for enough conversions to happen before getting a significant
+	 * value when changing channels and the values are far appart.
+	 */
+	do {
+		ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
+		if (ret < 0)
+			return ret;
+
+		while (!(ret & NAU7802_PUCTRL_CR_BIT)) {
+			if (st->sample_rate != NAU7802_SAMP_FREQ_320)
+				msleep(20);
+			else
+				mdelay(4);
+			ret = i2c_smbus_read_byte_data(st->client,
+							NAU7802_REG_PUCTRL);
+			if (ret < 0)
+				return ret;
+		}
+
+		ret = nau7802_read_conversion(st);
+		if (ret < 0)
+			return ret;
+		if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
+			st->conversion_count++;
+	} while (st->conversion_count < NAU7802_MIN_CONVERSIONS);
+
+	*val = st->last_value;
+
+	return IIO_VAL_INT;
+}
+
+static int nau7802_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val, int *val2, long mask)
+{
+	struct nau7802_state *st = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		mutex_lock(&st->lock);
+		/*
+		 * Select the channel to use
+		 *   - Channel 1 is value 0 in the CHS register
+		 *   - Channel 2 is value 1 in the CHS register
+		 */
+		ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL2);
+		if (ret < 0) {
+			mutex_unlock(&st->lock);
+			return ret;
+		}
+
+		if (((ret & NAU7802_CTRL2_CHS_BIT) && !chan->channel) ||
+				(!(ret & NAU7802_CTRL2_CHS_BIT) &&
+				 chan->channel)) {
+			st->conversion_count = 0;
+			ret = i2c_smbus_write_byte_data(st->client,
+					NAU7802_REG_CTRL2,
+					NAU7802_CTRL2_CHS(chan->channel) |
+					NAU7802_CTRL2_CRS(st->sample_rate));
+
+			if (ret < 0) {
+				mutex_unlock(&st->lock);
+				return ret;
+			}
+		}
+
+		if (st->client->irq)
+			ret = nau7802_read_irq(indio_dev, chan, val);
+		else
+			ret = nau7802_read_poll(indio_dev, chan, val);
+
+		mutex_unlock(&st->lock);
+		return ret;
+
+	case IIO_CHAN_INFO_SCALE:
+		ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
+		if (ret < 0)
+			return ret;
+
+		/*
+		 * We have 24 bits of signed data, that means 23 bits of data
+		 * plus the sign bit
+		 */
+		*val = st->vref_mv;
+		*val2 = 23 + (ret & NAU7802_CTRL1_GAINS_BITS);
+
+		return IIO_VAL_FRACTIONAL_LOG2;
+
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val =  nau7802_sample_freq_avail[st->sample_rate];
+		*val2 = 0;
+		return IIO_VAL_INT;
+
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int nau7802_write_raw(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     int val, int val2, long mask)
+{
+	struct nau7802_state *st = iio_priv(indio_dev);
+	int i, ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
+			if (val2 == st->scale_avail[i])
+				return nau7802_set_gain(st, i);
+
+		break;
+
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		for (i = 0; i < ARRAY_SIZE(nau7802_sample_freq_avail); i++)
+			if (val == nau7802_sample_freq_avail[i]) {
+				mutex_lock(&st->lock);
+				st->sample_rate = i;
+				st->conversion_count = 0;
+				ret = i2c_smbus_write_byte_data(st->client,
+					NAU7802_REG_CTRL2,
+					NAU7802_CTRL2_CRS(st->sample_rate));
+				mutex_unlock(&st->lock);
+				return ret;
+			}
+
+		break;
+
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int nau7802_write_raw_get_fmt(struct iio_dev *indio_dev,
+				     struct iio_chan_spec const *chan,
+				     long mask)
+{
+	return IIO_VAL_INT_PLUS_NANO;
+}
+
+static const struct iio_info nau7802_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &nau7802_read_raw,
+	.write_raw = &nau7802_write_raw,
+	.write_raw_get_fmt = nau7802_write_raw_get_fmt,
+	.attrs = &nau7802_attribute_group,
+};
+
+static int nau7802_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct iio_dev *indio_dev;
+	struct nau7802_state *st;
+	struct device_node *np = client->dev.of_node;
+	int i, ret;
+	u8 data;
+	u32 tmp = 0;
+
+	if (!client->dev.of_node) {
+		dev_err(&client->dev, "No device tree node available.\n");
+		return -EINVAL;
+	}
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
+
+	i2c_set_clientdata(client, indio_dev);
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = dev_name(&client->dev);
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &nau7802_info;
+
+	st->client = client;
+
+	/* Reset the device */
+	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
+				  NAU7802_PUCTRL_RR_BIT);
+	if (ret < 0)
+		return ret;
+
+	/* Enter normal operation mode */
+	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
+				  NAU7802_PUCTRL_PUD_BIT);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * After about 200 usecs, the device should be ready and then
+	 * the Power Up bit will be set to 1. If not, wait for it.
+	 */
+	udelay(210);
+	ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
+	if (ret < 0)
+		return ret;
+	if (!(ret & NAU7802_PUCTRL_PUR_BIT))
+		return ret;
+
+	of_property_read_u32(np, "nuvoton,vldo", &tmp);
+	st->vref_mv = tmp;
+
+	data = NAU7802_PUCTRL_PUD_BIT | NAU7802_PUCTRL_PUA_BIT |
+		NAU7802_PUCTRL_CS_BIT;
+	if (tmp >= 2400)
+		data |= NAU7802_PUCTRL_AVDDS_BIT;
+
+	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL, data);
+	if (ret < 0)
+		return ret;
+	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_ADC_CTRL, 0x30);
+	if (ret < 0)
+		return ret;
+
+	if (tmp >= 2400) {
+		data = NAU7802_CTRL1_VLDO((4500 - tmp) / 300);
+		ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
+						data);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Populate available ADC input ranges */
+	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
+		st->scale_avail[i] = (((u64)st->vref_mv) * 1000000000ULL)
+					   >> (23 + i);
+
+	init_completion(&st->value_ok);
+
+	/*
+	 * The ADC fires continuously and we can't do anything about
+	 * it. So we need to have the IRQ disabled by default, and we
+	 * will enable them back when we will need them..
+	 */
+	if (client->irq) {
+		ret = request_threaded_irq(client->irq,
+				NULL,
+				nau7802_eoc_trigger,
+				IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+				client->dev.driver->name,
+				indio_dev);
+		if (ret) {
+			/*
+			 * What may happen here is that our IRQ controller is
+			 * not able to get level interrupt but this is required
+			 * by this ADC as when going over 40 sample per second,
+			 * the interrupt line may stay high between conversions.
+			 * So, we continue no matter what but we switch to
+			 * polling mode.
+			 */
+			dev_info(&client->dev,
+				"Failed to allocate IRQ, using polling mode\n");
+			client->irq = 0;
+		} else
+			disable_irq(client->irq);
+	}
+
+	if (!client->irq) {
+		/*
+		 * We are polling, use the fastest sample rate by
+		 * default
+		 */
+		st->sample_rate = NAU7802_SAMP_FREQ_320;
+		ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL2,
+					  NAU7802_CTRL2_CRS(st->sample_rate));
+		if (ret)
+			goto error_free_irq;
+	}
+
+	/* Setup the ADC channels available on the board */
+	indio_dev->num_channels = ARRAY_SIZE(nau7802_chan_array);
+	indio_dev->channels = nau7802_chan_array;
+
+	mutex_init(&st->lock);
+	mutex_init(&st->data_lock);
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0) {
+		dev_err(&client->dev, "Couldn't register the device.\n");
+		goto error_device_register;
+	}
+
+	return 0;
+
+error_device_register:
+	mutex_destroy(&st->lock);
+	mutex_destroy(&st->data_lock);
+error_free_irq:
+	if (client->irq)
+		free_irq(client->irq, indio_dev);
+
+	return ret;
+}
+
+static int nau7802_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct nau7802_state *st = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	mutex_destroy(&st->lock);
+	mutex_destroy(&st->data_lock);
+	if (client->irq)
+		free_irq(client->irq, indio_dev);
+
+	return 0;
+}
+
+static const struct i2c_device_id nau7802_i2c_id[] = {
+	{ "nau7802", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, nau7802_i2c_id);
+
+static const struct of_device_id nau7802_dt_ids[] = {
+	{ .compatible = "nuvoton,nau7802" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, nau7802_dt_ids);
+
+static struct i2c_driver nau7802_driver = {
+	.probe = nau7802_probe,
+	.remove = nau7802_remove,
+	.id_table = nau7802_i2c_id,
+	.driver = {
+		   .name = "nau7802",
+		   .of_match_table = of_match_ptr(nau7802_dt_ids),
+	},
+};
+
+module_i2c_driver(nau7802_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Nuvoton NAU7802 ADC Driver");
+MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");

+ 5 - 13
drivers/iio/adc/ti-adc081c.c

@@ -74,22 +74,20 @@ static int adc081c_probe(struct i2c_client *client,
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
 		return -ENODEV;
 		return -ENODEV;
 
 
-	iio = iio_device_alloc(sizeof(*adc));
+	iio = devm_iio_device_alloc(&client->dev, sizeof(*adc));
 	if (!iio)
 	if (!iio)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	adc = iio_priv(iio);
 	adc = iio_priv(iio);
 	adc->i2c = client;
 	adc->i2c = client;
 
 
-	adc->ref = regulator_get(&client->dev, "vref");
-	if (IS_ERR(adc->ref)) {
-		err = PTR_ERR(adc->ref);
-		goto iio_free;
-	}
+	adc->ref = devm_regulator_get(&client->dev, "vref");
+	if (IS_ERR(adc->ref))
+		return PTR_ERR(adc->ref);
 
 
 	err = regulator_enable(adc->ref);
 	err = regulator_enable(adc->ref);
 	if (err < 0)
 	if (err < 0)
-		goto regulator_put;
+		return err;
 
 
 	iio->dev.parent = &client->dev;
 	iio->dev.parent = &client->dev;
 	iio->name = dev_name(&client->dev);
 	iio->name = dev_name(&client->dev);
@@ -109,10 +107,6 @@ static int adc081c_probe(struct i2c_client *client,
 
 
 regulator_disable:
 regulator_disable:
 	regulator_disable(adc->ref);
 	regulator_disable(adc->ref);
-regulator_put:
-	regulator_put(adc->ref);
-iio_free:
-	iio_device_free(iio);
 
 
 	return err;
 	return err;
 }
 }
@@ -124,8 +118,6 @@ static int adc081c_remove(struct i2c_client *client)
 
 
 	iio_device_unregister(iio);
 	iio_device_unregister(iio);
 	regulator_disable(adc->ref);
 	regulator_disable(adc->ref);
-	regulator_put(adc->ref);
-	iio_device_free(iio);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 9
drivers/iio/adc/ti_am335x_adc.c

@@ -216,11 +216,11 @@ static int tiadc_probe(struct platform_device *pdev)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	indio_dev = iio_device_alloc(sizeof(struct tiadc_device));
+	indio_dev = devm_iio_device_alloc(&pdev->dev,
+					  sizeof(struct tiadc_device));
 	if (indio_dev == NULL) {
 	if (indio_dev == NULL) {
 		dev_err(&pdev->dev, "failed to allocate iio device\n");
 		dev_err(&pdev->dev, "failed to allocate iio device\n");
-		err = -ENOMEM;
-		goto err_ret;
+		return -ENOMEM;
 	}
 	}
 	adc_dev = iio_priv(indio_dev);
 	adc_dev = iio_priv(indio_dev);
 
 
@@ -241,7 +241,7 @@ static int tiadc_probe(struct platform_device *pdev)
 
 
 	err = tiadc_channel_init(indio_dev, adc_dev->channels);
 	err = tiadc_channel_init(indio_dev, adc_dev->channels);
 	if (err < 0)
 	if (err < 0)
-		goto err_free_device;
+		return err;
 
 
 	err = iio_device_register(indio_dev);
 	err = iio_device_register(indio_dev);
 	if (err)
 	if (err)
@@ -253,9 +253,6 @@ static int tiadc_probe(struct platform_device *pdev)
 
 
 err_free_channels:
 err_free_channels:
 	tiadc_channels_remove(indio_dev);
 	tiadc_channels_remove(indio_dev);
-err_free_device:
-	iio_device_free(indio_dev);
-err_ret:
 	return err;
 	return err;
 }
 }
 
 
@@ -271,8 +268,6 @@ static int tiadc_remove(struct platform_device *pdev)
 	step_en = get_adc_step_mask(adc_dev);
 	step_en = get_adc_step_mask(adc_dev);
 	am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en);
 	am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en);
 
 
-	iio_device_free(indio_dev);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 1013 - 0
drivers/iio/adc/twl6030-gpadc.c

@@ -0,0 +1,1013 @@
+/*
+ * TWL6030 GPADC module driver
+ *
+ * Copyright (C) 2009-2013 Texas Instruments Inc.
+ * Nishant Kamat <nskamat@ti.com>
+ * Balaji T K <balajitk@ti.com>
+ * Graeme Gregory <gg@slimlogic.co.uk>
+ * Girish S Ghongdemath <girishsg@ti.com>
+ * Ambresh K <ambresh@ti.com>
+ * Oleksandr Kozaruk <oleksandr.kozaruk@ti.com
+ *
+ * Based on twl4030-madc.c
+ * Copyright (C) 2008 Nokia Corporation
+ * Mikko Ylinen <mikko.k.ylinen@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/i2c/twl.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define DRIVER_NAME		"twl6030_gpadc"
+
+/*
+ * twl6030 per TRM has 17 channels, and twl6032 has 19 channels
+ * 2 test network channels are not used,
+ * 2 die temperature channels are not used either, as it is not
+ * defined how to convert ADC value to temperature
+ */
+#define TWL6030_GPADC_USED_CHANNELS		13
+#define TWL6030_GPADC_MAX_CHANNELS		15
+#define TWL6032_GPADC_USED_CHANNELS		15
+#define TWL6032_GPADC_MAX_CHANNELS		19
+#define TWL6030_GPADC_NUM_TRIM_REGS		16
+
+#define TWL6030_GPADC_CTRL_P1			0x05
+
+#define TWL6032_GPADC_GPSELECT_ISB		0x07
+#define TWL6032_GPADC_CTRL_P1			0x08
+
+#define TWL6032_GPADC_GPCH0_LSB			0x0d
+#define TWL6032_GPADC_GPCH0_MSB			0x0e
+
+#define TWL6030_GPADC_CTRL_P1_SP1		BIT(3)
+
+#define TWL6030_GPADC_GPCH0_LSB			(0x29)
+
+#define TWL6030_GPADC_RT_SW1_EOC_MASK		BIT(5)
+
+#define TWL6030_GPADC_TRIM1			0xCD
+
+#define TWL6030_REG_TOGGLE1			0x90
+#define TWL6030_GPADCS				BIT(1)
+#define TWL6030_GPADCR				BIT(0)
+
+/**
+ * struct twl6030_chnl_calib - channel calibration
+ * @gain:		slope coefficient for ideal curve
+ * @gain_error:		gain error
+ * @offset_error:	offset of the real curve
+ */
+struct twl6030_chnl_calib {
+	s32 gain;
+	s32 gain_error;
+	s32 offset_error;
+};
+
+/**
+ * struct twl6030_ideal_code - GPADC calibration parameters
+ * GPADC is calibrated in two points: close to the beginning and
+ * to the and of the measurable input range
+ *
+ * @channel:	channel number
+ * @code1:	ideal code for the input at the beginning
+ * @code2:	ideal code for at the end of the range
+ * @volt1:	voltage input at the beginning(low voltage)
+ * @volt2:	voltage input at the end(high voltage)
+ */
+struct twl6030_ideal_code {
+	int channel;
+	u16 code1;
+	u16 code2;
+	u16 volt1;
+	u16 volt2;
+};
+
+struct twl6030_gpadc_data;
+
+/**
+ * struct twl6030_gpadc_platform_data - platform specific data
+ * @nchannels:		number of GPADC channels
+ * @iio_channels:	iio channels
+ * @twl6030_ideal:	pointer to calibration parameters
+ * @start_conversion:	pointer to ADC start conversion function
+ * @channel_to_reg	pointer to ADC function to convert channel to
+ *			register address for reading conversion result
+ * @calibrate:		pointer to calibration function
+ */
+struct twl6030_gpadc_platform_data {
+	const int nchannels;
+	const struct iio_chan_spec *iio_channels;
+	const struct twl6030_ideal_code *ideal;
+	int (*start_conversion)(int channel);
+	u8 (*channel_to_reg)(int channel);
+	int (*calibrate)(struct twl6030_gpadc_data *gpadc);
+};
+
+/**
+ * struct twl6030_gpadc_data - GPADC data
+ * @dev:		device pointer
+ * @lock:		mutual exclusion lock for the structure
+ * @irq_complete:	completion to signal end of conversion
+ * @twl6030_cal_tbl:	pointer to calibration data for each
+ *			channel with gain error and offset
+ * @pdata:		pointer to device specific data
+ */
+struct twl6030_gpadc_data {
+	struct device	*dev;
+	struct mutex	lock;
+	struct completion	irq_complete;
+	struct twl6030_chnl_calib	*twl6030_cal_tbl;
+	const struct twl6030_gpadc_platform_data *pdata;
+};
+
+/*
+ * channels 11, 12, 13, 15 and 16 have no calibration data
+ * calibration offset is same for channels 1, 3, 4, 5
+ *
+ * The data is taken from GPADC_TRIM registers description.
+ * GPADC_TRIM registers keep difference between the code measured
+ * at volt1 and volt2 input voltages and corresponding code1 and code2
+ */
+static const struct twl6030_ideal_code
+	twl6030_ideal[TWL6030_GPADC_USED_CHANNELS] = {
+	[0] = { /* ch 0, external, battery type, resistor value */
+		.channel = 0,
+		.code1 = 116,
+		.code2 = 745,
+		.volt1 = 141,
+		.volt2 = 910,
+	},
+	[1] = { /* ch 1, external, battery temperature, NTC resistor value */
+		.channel = 1,
+		.code1 = 82,
+		.code2 = 900,
+		.volt1 = 100,
+		.volt2 = 1100,
+	},
+	[2] = { /* ch 2, external, audio accessory/general purpose */
+		.channel = 2,
+		.code1 = 55,
+		.code2 = 818,
+		.volt1 = 101,
+		.volt2 = 1499,
+	},
+	[3] = { /* ch 3, external, general purpose */
+		.channel = 3,
+		.code1 = 82,
+		.code2 = 900,
+		.volt1 = 100,
+		.volt2 = 1100,
+	},
+	[4] = { /* ch 4, external, temperature measurement/general purpose */
+		.channel = 4,
+		.code1 = 82,
+		.code2 = 900,
+		.volt1 = 100,
+		.volt2 = 1100,
+	},
+	[5] = { /* ch 5, external, general purpose */
+		.channel = 5,
+		.code1 = 82,
+		.code2 = 900,
+		.volt1 = 100,
+		.volt2 = 1100,
+	},
+	[6] = { /* ch 6, external, general purpose */
+		.channel = 6,
+		.code1 = 82,
+		.code2 = 900,
+		.volt1 = 100,
+		.volt2 = 1100,
+	},
+	[7] = { /* ch 7, internal, main battery */
+		.channel = 7,
+		.code1 = 614,
+		.code2 = 941,
+		.volt1 = 3001,
+		.volt2 = 4599,
+	},
+	[8] = { /* ch 8, internal, backup battery */
+		.channel = 8,
+		.code1 = 82,
+		.code2 = 688,
+		.volt1 = 501,
+		.volt2 = 4203,
+	},
+	[9] = { /* ch 9, internal, external charger input */
+		.channel = 9,
+		.code1 = 182,
+		.code2 = 818,
+		.volt1 = 2001,
+		.volt2 = 8996,
+	},
+	[10] = { /* ch 10, internal, VBUS */
+		.channel = 10,
+		.code1 = 149,
+		.code2 = 818,
+		.volt1 = 1001,
+		.volt2 = 5497,
+	},
+	[11] = { /* ch 11, internal, VBUS charging current */
+		.channel = 11,
+	},
+		/* ch 12, internal, Die temperature */
+		/* ch 13, internal, Die temperature */
+	[12] = { /* ch 14, internal, USB ID line */
+		.channel = 14,
+		.code1 = 48,
+		.code2 = 714,
+		.volt1 = 323,
+		.volt2 = 4800,
+	},
+};
+
+static const struct twl6030_ideal_code
+			twl6032_ideal[TWL6032_GPADC_USED_CHANNELS] = {
+	[0] = { /* ch 0, external, battery type, resistor value */
+		.channel = 0,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 440,
+		.volt2 = 1000,
+	},
+	[1] = { /* ch 1, external, battery temperature, NTC resistor value */
+		.channel = 1,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 440,
+		.volt2 = 1000,
+	},
+	[2] = { /* ch 2, external, audio accessory/general purpose */
+		.channel = 2,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 660,
+		.volt2 = 1500,
+	},
+	[3] = { /* ch 3, external, temperature with external diode/general
+								purpose */
+		.channel = 3,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 440,
+		.volt2 = 1000,
+	},
+	[4] = { /* ch 4, external, temperature measurement/general purpose */
+		.channel = 4,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 440,
+		.volt2 = 1000,
+	},
+	[5] = { /* ch 5, external, general purpose */
+		.channel = 5,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 440,
+		.volt2 = 1000,
+	},
+	[6] = { /* ch 6, external, general purpose */
+		.channel = 6,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 440,
+		.volt2 = 1000,
+	},
+	[7] = { /* ch7, internal, system supply */
+		.channel = 7,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 2200,
+		.volt2 = 5000,
+	},
+	[8] = { /* ch8, internal, backup battery */
+		.channel = 8,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 2200,
+		.volt2 = 5000,
+	},
+	[9] = { /* ch 9, internal, external charger input */
+		.channel = 9,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 3960,
+		.volt2 = 9000,
+	},
+	[10] = { /* ch10, internal, VBUS */
+		.channel = 10,
+		.code1 = 150,
+		.code2 = 751,
+		.volt1 = 1000,
+		.volt2 = 5000,
+	},
+	[11] = { /* ch 11, internal, VBUS DC-DC output current */
+		.channel = 11,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 660,
+		.volt2 = 1500,
+	},
+		/* ch 12, internal, Die temperature */
+		/* ch 13, internal, Die temperature */
+	[12] = { /* ch 14, internal, USB ID line */
+		.channel = 14,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 2420,
+		.volt2 = 5500,
+	},
+		/* ch 15, internal, test network */
+		/* ch 16, internal, test network */
+	[13] = { /* ch 17, internal, battery charging current */
+		.channel = 17,
+	},
+	[14] = { /* ch 18, internal, battery voltage */
+		.channel = 18,
+		.code1 = 1441,
+		.code2 = 3276,
+		.volt1 = 2200,
+		.volt2 = 5000,
+	},
+};
+
+static inline int twl6030_gpadc_write(u8 reg, u8 val)
+{
+	return twl_i2c_write_u8(TWL6030_MODULE_GPADC, val, reg);
+}
+
+static inline int twl6030_gpadc_read(u8 reg, u8 *val)
+{
+
+	return twl_i2c_read(TWL6030_MODULE_GPADC, val, reg, 2);
+}
+
+static int twl6030_gpadc_enable_irq(u8 mask)
+{
+	int ret;
+
+	ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_LINE_B);
+	if (ret < 0)
+		return ret;
+
+	ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_STS_B);
+
+	return ret;
+}
+
+static void twl6030_gpadc_disable_irq(u8 mask)
+{
+	twl6030_interrupt_mask(mask, REG_INT_MSK_LINE_B);
+	twl6030_interrupt_mask(mask, REG_INT_MSK_STS_B);
+}
+
+static irqreturn_t twl6030_gpadc_irq_handler(int irq, void *indio_dev)
+{
+	struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);
+
+	complete(&gpadc->irq_complete);
+
+	return IRQ_HANDLED;
+}
+
+static int twl6030_start_conversion(int channel)
+{
+	return twl6030_gpadc_write(TWL6030_GPADC_CTRL_P1,
+					TWL6030_GPADC_CTRL_P1_SP1);
+}
+
+static int twl6032_start_conversion(int channel)
+{
+	int ret;
+
+	ret = twl6030_gpadc_write(TWL6032_GPADC_GPSELECT_ISB, channel);
+	if (ret)
+		return ret;
+
+	return twl6030_gpadc_write(TWL6032_GPADC_CTRL_P1,
+						TWL6030_GPADC_CTRL_P1_SP1);
+}
+
+static u8 twl6030_channel_to_reg(int channel)
+{
+	return TWL6030_GPADC_GPCH0_LSB + 2 * channel;
+}
+
+static u8 twl6032_channel_to_reg(int channel)
+{
+	/*
+	 * for any prior chosen channel, when the conversion is ready
+	 * the result is avalable in GPCH0_LSB, GPCH0_MSB.
+	 */
+
+	return TWL6032_GPADC_GPCH0_LSB;
+}
+
+static int twl6030_gpadc_lookup(const struct twl6030_ideal_code *ideal,
+		int channel, int size)
+{
+	int i;
+
+	for (i = 0; i < size; i++)
+		if (ideal[i].channel == channel)
+			break;
+
+	return i;
+}
+
+static int twl6030_channel_calibrated(const struct twl6030_gpadc_platform_data
+		*pdata, int channel)
+{
+	const struct twl6030_ideal_code *ideal = pdata->ideal;
+	int i;
+
+	i = twl6030_gpadc_lookup(ideal, channel, pdata->nchannels);
+	/* not calibrated channels have 0 in all structure members */
+	return pdata->ideal[i].code2;
+}
+
+static int twl6030_gpadc_make_correction(struct twl6030_gpadc_data *gpadc,
+		int channel, int raw_code)
+{
+	const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
+	int corrected_code;
+	int i;
+
+	i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
+	corrected_code = ((raw_code * 1000) -
+		gpadc->twl6030_cal_tbl[i].offset_error) /
+		gpadc->twl6030_cal_tbl[i].gain_error;
+
+	return corrected_code;
+}
+
+static int twl6030_gpadc_get_raw(struct twl6030_gpadc_data *gpadc,
+		int channel, int *res)
+{
+	u8 reg = gpadc->pdata->channel_to_reg(channel);
+	__le16 val;
+	int raw_code;
+	int ret;
+
+	ret = twl6030_gpadc_read(reg, (u8 *)&val);
+	if (ret) {
+		dev_dbg(gpadc->dev, "unable to read register 0x%X\n", reg);
+		return ret;
+	}
+
+	raw_code = le16_to_cpu(val);
+	dev_dbg(gpadc->dev, "GPADC raw code: %d", raw_code);
+
+	if (twl6030_channel_calibrated(gpadc->pdata, channel))
+		*res = twl6030_gpadc_make_correction(gpadc, channel, raw_code);
+	else
+		*res = raw_code;
+
+	return ret;
+}
+
+static int twl6030_gpadc_get_processed(struct twl6030_gpadc_data *gpadc,
+		int channel, int *val)
+{
+	const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
+	int corrected_code;
+	int channel_value;
+	int i;
+	int ret;
+
+	ret = twl6030_gpadc_get_raw(gpadc, channel, &corrected_code);
+	if (ret)
+		return ret;
+
+	i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
+	channel_value = corrected_code *
+			gpadc->twl6030_cal_tbl[i].gain;
+
+	/* Shift back into mV range */
+	channel_value /= 1000;
+
+	dev_dbg(gpadc->dev, "GPADC corrected code: %d", corrected_code);
+	dev_dbg(gpadc->dev, "GPADC value: %d", channel_value);
+
+	*val = channel_value;
+
+	return ret;
+}
+
+static int twl6030_gpadc_read_raw(struct iio_dev *indio_dev,
+			     const struct iio_chan_spec *chan,
+			     int *val, int *val2, long mask)
+{
+	struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);
+	int ret;
+	long timeout;
+
+	mutex_lock(&gpadc->lock);
+
+	ret = gpadc->pdata->start_conversion(chan->channel);
+	if (ret) {
+		dev_err(gpadc->dev, "failed to start conversion\n");
+		goto err;
+	}
+	/* wait for conversion to complete */
+	timeout = wait_for_completion_interruptible_timeout(
+				&gpadc->irq_complete, msecs_to_jiffies(5000));
+	if (timeout == 0) {
+		ret = -ETIMEDOUT;
+		goto err;
+	} else if (timeout < 0) {
+		ret = -EINTR;
+		goto err;
+	}
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		ret = twl6030_gpadc_get_raw(gpadc, chan->channel, val);
+		ret = ret ? -EIO : IIO_VAL_INT;
+		break;
+
+	case IIO_CHAN_INFO_PROCESSED:
+		ret = twl6030_gpadc_get_processed(gpadc, chan->channel, val);
+		ret = ret ? -EIO : IIO_VAL_INT;
+		break;
+
+	default:
+		break;
+	}
+err:
+	mutex_unlock(&gpadc->lock);
+
+	return ret;
+}
+
+/*
+ * The GPADC channels are calibrated using a two point calibration method.
+ * The channels measured with two known values: volt1 and volt2, and
+ * ideal corresponding output codes are known: code1, code2.
+ * The difference(d1, d2) between ideal and measured codes stored in trim
+ * registers.
+ * The goal is to find offset and gain of the real curve for each calibrated
+ * channel.
+ * gain: k = 1 + ((d2 - d1) / (x2 - x1))
+ * offset: b = d1 + (k - 1) * x1
+ */
+static void twl6030_calibrate_channel(struct twl6030_gpadc_data *gpadc,
+		int channel, int d1, int d2)
+{
+	int b, k, gain, x1, x2, i;
+	const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
+
+	i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
+
+	/* Gain */
+	gain = ((ideal[i].volt2 - ideal[i].volt1) * 1000) /
+		(ideal[i].code2 - ideal[i].code1);
+
+	x1 = ideal[i].code1;
+	x2 = ideal[i].code2;
+
+	/* k - real curve gain */
+	k = 1000 + (((d2 - d1) * 1000) / (x2 - x1));
+
+	/* b - offset of the real curve gain */
+	b = (d1 * 1000) - (k - 1000) * x1;
+
+	gpadc->twl6030_cal_tbl[i].gain = gain;
+	gpadc->twl6030_cal_tbl[i].gain_error = k;
+	gpadc->twl6030_cal_tbl[i].offset_error = b;
+
+	dev_dbg(gpadc->dev, "GPADC d1   for Chn: %d = %d\n", channel, d1);
+	dev_dbg(gpadc->dev, "GPADC d2   for Chn: %d = %d\n", channel, d2);
+	dev_dbg(gpadc->dev, "GPADC x1   for Chn: %d = %d\n", channel, x1);
+	dev_dbg(gpadc->dev, "GPADC x2   for Chn: %d = %d\n", channel, x2);
+	dev_dbg(gpadc->dev, "GPADC Gain for Chn: %d = %d\n", channel, gain);
+	dev_dbg(gpadc->dev, "GPADC k    for Chn: %d = %d\n", channel, k);
+	dev_dbg(gpadc->dev, "GPADC b    for Chn: %d = %d\n", channel, b);
+}
+
+static inline int twl6030_gpadc_get_trim_offset(s8 d)
+{
+	/*
+	 * XXX NOTE!
+	 * bit 0 - sign, bit 7 - reserved, 6..1 - trim value
+	 * though, the documentation states that trim value
+	 * is absolute value, the correct conversion results are
+	 * obtained if the value is interpreted as 2's complement.
+	 */
+	__u32 temp = ((d & 0x7f) >> 1) | ((d & 1) << 6);
+
+	return sign_extend32(temp, 6);
+}
+
+static int twl6030_calibration(struct twl6030_gpadc_data *gpadc)
+{
+	int ret;
+	int chn;
+	u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];
+	s8 d1, d2;
+
+	/*
+	 * for calibration two measurements have been performed at
+	 * factory, for some channels, during the production test and
+	 * have been stored in registers. This two stored values are
+	 * used to correct the measurements. The values represent
+	 * offsets for the given input from the output on ideal curve.
+	 */
+	ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,
+			TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);
+	if (ret < 0) {
+		dev_err(gpadc->dev, "calibration failed\n");
+		return ret;
+	}
+
+	for (chn = 0; chn < TWL6030_GPADC_MAX_CHANNELS; chn++) {
+
+		switch (chn) {
+		case 0:
+			d1 = trim_regs[0];
+			d2 = trim_regs[1];
+			break;
+		case 1:
+		case 3:
+		case 4:
+		case 5:
+		case 6:
+			d1 = trim_regs[4];
+			d2 = trim_regs[5];
+			break;
+		case 2:
+			d1 = trim_regs[12];
+			d2 = trim_regs[13];
+			break;
+		case 7:
+			d1 = trim_regs[6];
+			d2 = trim_regs[7];
+			break;
+		case 8:
+			d1 = trim_regs[2];
+			d2 = trim_regs[3];
+			break;
+		case 9:
+			d1 = trim_regs[8];
+			d2 = trim_regs[9];
+			break;
+		case 10:
+			d1 = trim_regs[10];
+			d2 = trim_regs[11];
+			break;
+		case 14:
+			d1 = trim_regs[14];
+			d2 = trim_regs[15];
+			break;
+		default:
+			continue;
+		}
+
+		d1 = twl6030_gpadc_get_trim_offset(d1);
+		d2 = twl6030_gpadc_get_trim_offset(d2);
+
+		twl6030_calibrate_channel(gpadc, chn, d1, d2);
+	}
+
+	return 0;
+}
+
+static int twl6032_get_trim_value(u8 *trim_regs, unsigned int reg0,
+		unsigned int reg1, unsigned int mask0, unsigned int mask1,
+		unsigned int shift0)
+{
+	int val;
+
+	val = (trim_regs[reg0] & mask0) << shift0;
+	val |= (trim_regs[reg1] & mask1) >> 1;
+	if (trim_regs[reg1] & 0x01)
+		val = -val;
+
+	return val;
+}
+
+static int twl6032_calibration(struct twl6030_gpadc_data *gpadc)
+{
+	int chn, d1 = 0, d2 = 0, temp;
+	u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];
+	int ret;
+
+	ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,
+			TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);
+	if (ret < 0) {
+		dev_err(gpadc->dev, "calibration failed\n");
+		return ret;
+	}
+
+	/*
+	 * Loop to calculate the value needed for returning voltages from
+	 * GPADC not values.
+	 *
+	 * gain is calculated to 3 decimal places fixed point.
+	 */
+	for (chn = 0; chn < TWL6032_GPADC_MAX_CHANNELS; chn++) {
+
+		switch (chn) {
+		case 0:
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+		case 6:
+		case 11:
+		case 14:
+			d1 = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
+								0x06, 2);
+			d2 = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
+								0x06, 2);
+			break;
+		case 8:
+			temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
+								0x06, 2);
+			d1 = temp + twl6032_get_trim_value(trim_regs, 7, 6,
+								0x18, 0x1E, 1);
+
+			temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3F,
+								0x06, 2);
+			d2 = temp + twl6032_get_trim_value(trim_regs, 9, 7,
+								0x1F, 0x06, 2);
+			break;
+		case 9:
+			temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
+								0x06, 2);
+			d1 = temp + twl6032_get_trim_value(trim_regs, 13, 11,
+								0x18, 0x1E, 1);
+
+			temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
+								0x06, 2);
+			d2 = temp + twl6032_get_trim_value(trim_regs, 15, 13,
+								0x1F, 0x06, 1);
+			break;
+		case 10:
+			d1 = twl6032_get_trim_value(trim_regs, 10, 8, 0x0f,
+								0x0E, 3);
+			d2 = twl6032_get_trim_value(trim_regs, 14, 12, 0x0f,
+								0x0E, 3);
+			break;
+		case 7:
+		case 18:
+			temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
+								0x06, 2);
+
+			d1 = (trim_regs[4] & 0x7E) >> 1;
+			if (trim_regs[4] & 0x01)
+				d1 = -d1;
+			d1 += temp;
+
+			temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
+								0x06, 2);
+
+			d2 = (trim_regs[5] & 0xFE) >> 1;
+			if (trim_regs[5] & 0x01)
+				d2 = -d2;
+
+			d2 += temp;
+			break;
+		default:
+			/* No data for other channels */
+			continue;
+		}
+
+		twl6030_calibrate_channel(gpadc, chn, d1, d2);
+	}
+
+	return 0;
+}
+
+#define TWL6030_GPADC_CHAN(chn, _type, chan_info) {	\
+	.type = _type,					\
+	.channel = chn,					\
+	.info_mask_separate = BIT(chan_info),		\
+	.indexed = 1,					\
+}
+
+static const struct iio_chan_spec twl6030_gpadc_iio_channels[] = {
+	TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),
+	TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),
+	TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
+	TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+};
+
+static const struct iio_chan_spec twl6032_gpadc_iio_channels[] = {
+	TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),
+	TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),
+	TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+	TWL6030_GPADC_CHAN(17, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
+	TWL6030_GPADC_CHAN(18, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
+};
+
+static const struct iio_info twl6030_gpadc_iio_info = {
+	.read_raw = &twl6030_gpadc_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct twl6030_gpadc_platform_data twl6030_pdata = {
+	.iio_channels = twl6030_gpadc_iio_channels,
+	.nchannels = TWL6030_GPADC_USED_CHANNELS,
+	.ideal = twl6030_ideal,
+	.start_conversion = twl6030_start_conversion,
+	.channel_to_reg = twl6030_channel_to_reg,
+	.calibrate = twl6030_calibration,
+};
+
+static const struct twl6030_gpadc_platform_data twl6032_pdata = {
+	.iio_channels = twl6032_gpadc_iio_channels,
+	.nchannels = TWL6032_GPADC_USED_CHANNELS,
+	.ideal = twl6032_ideal,
+	.start_conversion = twl6032_start_conversion,
+	.channel_to_reg = twl6032_channel_to_reg,
+	.calibrate = twl6032_calibration,
+};
+
+static const struct of_device_id of_twl6030_match_tbl[] = {
+	{
+		.compatible = "ti,twl6030-gpadc",
+		.data = &twl6030_pdata,
+	},
+	{
+		.compatible = "ti,twl6032-gpadc",
+		.data = &twl6032_pdata,
+	},
+	{ /* end */ }
+};
+
+static int twl6030_gpadc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct twl6030_gpadc_data *gpadc;
+	const struct twl6030_gpadc_platform_data *pdata;
+	const struct of_device_id *match;
+	struct iio_dev *indio_dev;
+	int irq;
+	int ret;
+
+	match = of_match_device(of_match_ptr(of_twl6030_match_tbl), dev);
+	if (!match)
+		return -EINVAL;
+
+	pdata = match->data;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*gpadc));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	gpadc = iio_priv(indio_dev);
+
+	gpadc->twl6030_cal_tbl = devm_kzalloc(dev,
+					sizeof(*gpadc->twl6030_cal_tbl) *
+					pdata->nchannels, GFP_KERNEL);
+	if (!gpadc->twl6030_cal_tbl)
+		return -ENOMEM;
+
+	gpadc->dev = dev;
+	gpadc->pdata = pdata;
+
+	platform_set_drvdata(pdev, indio_dev);
+	mutex_init(&gpadc->lock);
+	init_completion(&gpadc->irq_complete);
+
+	ret = pdata->calibrate(gpadc);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to read calibration registers\n");
+		return ret;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get irq\n");
+		return irq;
+	}
+
+	ret = devm_request_threaded_irq(dev, irq, NULL,
+				twl6030_gpadc_irq_handler,
+				IRQF_ONESHOT, "twl6030_gpadc", indio_dev);
+
+	ret = twl6030_gpadc_enable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to enable GPADC interrupt\n");
+		return ret;
+	}
+
+	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,
+					TWL6030_REG_TOGGLE1);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to enable GPADC module\n");
+		return ret;
+	}
+
+	indio_dev->name = DRIVER_NAME;
+	indio_dev->dev.parent = dev;
+	indio_dev->info = &twl6030_gpadc_iio_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = pdata->iio_channels;
+	indio_dev->num_channels = pdata->nchannels;
+
+	ret = iio_device_register(indio_dev);
+
+	return ret;
+}
+
+static int twl6030_gpadc_remove(struct platform_device *pdev)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+
+	twl6030_gpadc_disable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);
+	iio_device_unregister(indio_dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int twl6030_gpadc_suspend(struct device *pdev)
+{
+	int ret;
+
+	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCR,
+				TWL6030_REG_TOGGLE1);
+	if (ret)
+		dev_err(pdev, "error reseting GPADC (%d)!\n", ret);
+
+	return 0;
+};
+
+static int twl6030_gpadc_resume(struct device *pdev)
+{
+	int ret;
+
+	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,
+				TWL6030_REG_TOGGLE1);
+	if (ret)
+		dev_err(pdev, "error setting GPADC (%d)!\n", ret);
+
+	return 0;
+};
+#endif
+
+static SIMPLE_DEV_PM_OPS(twl6030_gpadc_pm_ops, twl6030_gpadc_suspend,
+					twl6030_gpadc_resume);
+
+static struct platform_driver twl6030_gpadc_driver = {
+	.probe		= twl6030_gpadc_probe,
+	.remove		= twl6030_gpadc_remove,
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= &twl6030_gpadc_pm_ops,
+		.of_match_table = of_twl6030_match_tbl,
+	},
+};
+
+module_platform_driver(twl6030_gpadc_driver);
+
+MODULE_ALIAS("platform: " DRIVER_NAME);
+MODULE_AUTHOR("Balaji T K <balajitk@ti.com>");
+MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
+MODULE_AUTHOR("Oleksandr Kozaruk <oleksandr.kozaruk@ti.com");
+MODULE_DESCRIPTION("twl6030 ADC driver");
+MODULE_LICENSE("GPL");

+ 2 - 7
drivers/iio/adc/viperboard_adc.c

@@ -124,7 +124,7 @@ static int vprbrd_adc_probe(struct platform_device *pdev)
 	int ret;
 	int ret;
 
 
 	/* registering iio */
 	/* registering iio */
-	indio_dev = iio_device_alloc(sizeof(*adc));
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
 	if (!indio_dev) {
 	if (!indio_dev) {
 		dev_err(&pdev->dev, "failed allocating iio device\n");
 		dev_err(&pdev->dev, "failed allocating iio device\n");
 		return -ENOMEM;
 		return -ENOMEM;
@@ -142,16 +142,12 @@ static int vprbrd_adc_probe(struct platform_device *pdev)
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret) {
 	if (ret) {
 		dev_err(&pdev->dev, "could not register iio (adc)");
 		dev_err(&pdev->dev, "could not register iio (adc)");
-		goto error;
+		return ret;
 	}
 	}
 
 
 	platform_set_drvdata(pdev, indio_dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 
 	return 0;
 	return 0;
-
-error:
-	iio_device_free(indio_dev);
-	return ret;
 }
 }
 
 
 static int vprbrd_adc_remove(struct platform_device *pdev)
 static int vprbrd_adc_remove(struct platform_device *pdev)
@@ -159,7 +155,6 @@ static int vprbrd_adc_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 2 - 0
drivers/iio/amplifiers/Kconfig

@@ -1,6 +1,8 @@
 #
 #
 # Gain Amplifiers, etc.
 # Gain Amplifiers, etc.
 #
 #
+# When adding new entries keep the list in alphabetical order
+
 menu "Amplifiers"
 menu "Amplifiers"
 
 
 config AD8366
 config AD8366

+ 1 - 0
drivers/iio/amplifiers/Makefile

@@ -2,4 +2,5 @@
 # Makefile iio/amplifiers
 # Makefile iio/amplifiers
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AD8366) += ad8366.o
 obj-$(CONFIG_AD8366) += ad8366.o

+ 3 - 10
drivers/iio/amplifiers/ad8366.c

@@ -139,17 +139,17 @@ static int ad8366_probe(struct spi_device *spi)
 	struct ad8366_state *st;
 	struct ad8366_state *st;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 
 
-	st->reg = regulator_get(&spi->dev, "vcc");
+	st->reg = devm_regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
 	if (!IS_ERR(st->reg)) {
 		ret = regulator_enable(st->reg);
 		ret = regulator_enable(st->reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 	}
 	}
 
 
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
@@ -173,11 +173,6 @@ static int ad8366_probe(struct spi_device *spi)
 error_disable_reg:
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-error_put_reg:
-	if (!IS_ERR(st->reg))
-		regulator_put(st->reg);
-
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -195,8 +190,6 @@ static int ad8366_remove(struct spi_device *spi)
 		regulator_put(reg);
 		regulator_put(reg);
 	}
 	}
 
 
-	iio_device_free(indio_dev);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 0
drivers/iio/common/Makefile

@@ -6,5 +6,6 @@
 # instead of duplicating in each module.
 # instead of duplicating in each module.
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
 obj-y += hid-sensors/
 obj-y += hid-sensors/
 obj-y += st_sensors/
 obj-y += st_sensors/

+ 36 - 5
drivers/iio/common/st_sensors/st_sensors_core.c

@@ -22,7 +22,7 @@
 
 
 static inline u32 st_sensors_get_unaligned_le24(const u8 *p)
 static inline u32 st_sensors_get_unaligned_le24(const u8 *p)
 {
 {
-	return ((s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8);
+	return (s32)((p[0] | p[1] << 8 | p[2] << 16) << 8) >> 8;
 }
 }
 
 
 static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
 static int st_sensors_write_data_with_mask(struct iio_dev *indio_dev,
@@ -118,7 +118,7 @@ static int st_sensors_match_fs(struct st_sensors *sensor,
 }
 }
 
 
 static int st_sensors_set_fullscale(struct iio_dev *indio_dev,
 static int st_sensors_set_fullscale(struct iio_dev *indio_dev,
-							unsigned int fs)
+								unsigned int fs)
 {
 {
 	int err, i = 0;
 	int err, i = 0;
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
@@ -198,13 +198,39 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
 }
 }
 EXPORT_SYMBOL(st_sensors_set_axis_enable);
 EXPORT_SYMBOL(st_sensors_set_axis_enable);
 
 
-int st_sensors_init_sensor(struct iio_dev *indio_dev)
+int st_sensors_init_sensor(struct iio_dev *indio_dev,
+					struct st_sensors_platform_data *pdata)
 {
 {
 	int err;
 	int err;
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
 
 
 	mutex_init(&sdata->tb.buf_lock);
 	mutex_init(&sdata->tb.buf_lock);
 
 
+	switch (pdata->drdy_int_pin) {
+	case 1:
+		if (sdata->sensor->drdy_irq.mask_int1 == 0) {
+			dev_err(&indio_dev->dev,
+					"DRDY on INT1 not available.\n");
+			err = -EINVAL;
+			goto init_error;
+		}
+		sdata->drdy_int_pin = 1;
+		break;
+	case 2:
+		if (sdata->sensor->drdy_irq.mask_int2 == 0) {
+			dev_err(&indio_dev->dev,
+					"DRDY on INT2 not available.\n");
+			err = -EINVAL;
+			goto init_error;
+		}
+		sdata->drdy_int_pin = 2;
+		break;
+	default:
+		dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
+		err = -EINVAL;
+		goto init_error;
+	}
+
 	err = st_sensors_set_enable(indio_dev, false);
 	err = st_sensors_set_enable(indio_dev, false);
 	if (err < 0)
 	if (err < 0)
 		goto init_error;
 		goto init_error;
@@ -234,6 +260,7 @@ EXPORT_SYMBOL(st_sensors_init_sensor);
 int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
 int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
 {
 {
 	int err;
 	int err;
+	u8 drdy_mask;
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
 
 
 	/* Enable/Disable the interrupt generator 1. */
 	/* Enable/Disable the interrupt generator 1. */
@@ -245,10 +272,14 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
 			goto st_accel_set_dataready_irq_error;
 			goto st_accel_set_dataready_irq_error;
 	}
 	}
 
 
+	if (sdata->drdy_int_pin == 1)
+		drdy_mask = sdata->sensor->drdy_irq.mask_int1;
+	else
+		drdy_mask = sdata->sensor->drdy_irq.mask_int2;
+
 	/* Enable/Disable the interrupt generator for data ready. */
 	/* Enable/Disable the interrupt generator for data ready. */
 	err = st_sensors_write_data_with_mask(indio_dev,
 	err = st_sensors_write_data_with_mask(indio_dev,
-			sdata->sensor->drdy_irq.addr,
-			sdata->sensor->drdy_irq.mask, (int)enable);
+			sdata->sensor->drdy_irq.addr, drdy_mask, (int)enable);
 
 
 st_accel_set_dataready_irq_error:
 st_accel_set_dataready_irq_error:
 	return err;
 	return err;

+ 23 - 21
drivers/iio/dac/Kconfig

@@ -1,6 +1,8 @@
 #
 #
 # DAC drivers
 # DAC drivers
 #
 #
+# When adding new entries keep the list in alphabetical order
+
 menu "Digital to analog converters"
 menu "Digital to analog converters"
 
 
 config AD5064
 config AD5064
@@ -15,7 +17,7 @@ config AD5064
 	  module will be called ad5064.
 	  module will be called ad5064.
 
 
 config AD5360
 config AD5360
-	tristate "Analog Devices Analog Devices AD5360/61/62/63/70/71/73 DAC driver"
+	tristate "Analog Devices AD5360/61/62/63/70/71/73 DAC driver"
 	depends on SPI
 	depends on SPI
 	help
 	help
 	  Say yes here to build support for Analog Devices AD5360, AD5361,
 	  Say yes here to build support for Analog Devices AD5360, AD5361,
@@ -48,13 +50,6 @@ config AD5421
 	  To compile this driver as module choose M here: the module will be called
 	  To compile this driver as module choose M here: the module will be called
 	  ad5421.
 	  ad5421.
 
 
-config AD5624R_SPI
-	tristate "Analog Devices AD5624/44/64R DAC spi driver"
-	depends on SPI
-	help
-	  Say yes here to build support for Analog Devices AD5624R, AD5644R and
-	  AD5664R converters (DAC). This driver uses the common SPI interface.
-
 config AD5446
 config AD5446
 	tristate "Analog Devices AD5446 and similar single channel DACs driver"
 	tristate "Analog Devices AD5446 and similar single channel DACs driver"
 	depends on (SPI_MASTER && I2C!=m) || I2C
 	depends on (SPI_MASTER && I2C!=m) || I2C
@@ -68,7 +63,7 @@ config AD5446
 	  module will be called ad5446.
 	  module will be called ad5446.
 
 
 config AD5449
 config AD5449
-	tristate "Analog Device AD5449 and similar DACs driver"
+	tristate "Analog Devices AD5449 and similar DACs driver"
 	depends on SPI_MASTER
 	depends on SPI_MASTER
 	help
 	help
 	  Say yes here to build support for Analog Devices AD5415, AD5426, AD5429,
 	  Say yes here to build support for Analog Devices AD5415, AD5426, AD5429,
@@ -87,6 +82,24 @@ config AD5504
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad5504.
 	  module will be called ad5504.
 
 
+config AD5624R_SPI
+	tristate "Analog Devices AD5624/44/64R DAC spi driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD5624R, AD5644R and
+	  AD5664R converters (DAC). This driver uses the common SPI interface.
+
+config AD5686
+	tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD5686R, AD5685R,
+	  AD5684R, AD5791 Voltage Output Digital to
+	  Analog Converter.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad5686.
+
 config AD5755
 config AD5755
 	tristate "Analog Devices AD5755/AD5755-1/AD5757/AD5735/AD5737 DAC driver"
 	tristate "Analog Devices AD5755/AD5755-1/AD5757/AD5735/AD5737 DAC driver"
 	depends on SPI_MASTER
 	depends on SPI_MASTER
@@ -119,19 +132,8 @@ config AD5791
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad5791.
 	  module will be called ad5791.
 
 
-config AD5686
-	tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
-	depends on SPI
-	help
-	  Say yes here to build support for Analog Devices AD5686R, AD5685R,
-	  AD5684R, AD5791 Voltage Output Digital to
-	  Analog Converter.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ad5686.
-
 config AD7303
 config AD7303
-	tristate "Analog Devices Analog Devices AD7303 DAC driver"
+	tristate "Analog Devices AD7303 DAC driver"
 	depends on SPI
 	depends on SPI
 	help
 	help
 	  Say yes here to build support for Analog Devices AD7303 Digital to Analog
 	  Say yes here to build support for Analog Devices AD7303 Digital to Analog

+ 1 - 0
drivers/iio/dac/Makefile

@@ -2,6 +2,7 @@
 # Makefile for industrial I/O DAC drivers
 # Makefile for industrial I/O DAC drivers
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AD5360) += ad5360.o
 obj-$(CONFIG_AD5360) += ad5360.o
 obj-$(CONFIG_AD5380) += ad5380.o
 obj-$(CONFIG_AD5380) += ad5380.o
 obj-$(CONFIG_AD5421) += ad5421.o
 obj-$(CONFIG_AD5421) += ad5421.o

+ 6 - 15
drivers/iio/dac/ad5064.c

@@ -442,7 +442,7 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
 	unsigned int i;
 	unsigned int i;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return  -ENOMEM;
 		return  -ENOMEM;
 
 
@@ -456,23 +456,23 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
 	for (i = 0; i < ad5064_num_vref(st); ++i)
 	for (i = 0; i < ad5064_num_vref(st); ++i)
 		st->vref_reg[i].supply = ad5064_vref_name(st, i);
 		st->vref_reg[i].supply = ad5064_vref_name(st, i);
 
 
-	ret = regulator_bulk_get(dev, ad5064_num_vref(st),
+	ret = devm_regulator_bulk_get(dev, ad5064_num_vref(st),
 		st->vref_reg);
 		st->vref_reg);
 	if (ret) {
 	if (ret) {
 		if (!st->chip_info->internal_vref)
 		if (!st->chip_info->internal_vref)
-			goto error_free;
+			return ret;
 		st->use_internal_vref = true;
 		st->use_internal_vref = true;
 		ret = ad5064_write(st, AD5064_CMD_CONFIG, 0,
 		ret = ad5064_write(st, AD5064_CMD_CONFIG, 0,
 			AD5064_CONFIG_INT_VREF_ENABLE, 0);
 			AD5064_CONFIG_INT_VREF_ENABLE, 0);
 		if (ret) {
 		if (ret) {
 			dev_err(dev, "Failed to enable internal vref: %d\n",
 			dev_err(dev, "Failed to enable internal vref: %d\n",
 				ret);
 				ret);
-			goto error_free;
+			return ret;
 		}
 		}
 	} else {
 	} else {
 		ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg);
 		ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg);
 		if (ret)
 		if (ret)
-			goto error_free_reg;
+			return ret;
 	}
 	}
 
 
 	indio_dev->dev.parent = dev;
 	indio_dev->dev.parent = dev;
@@ -498,11 +498,6 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
 error_disable_reg:
 error_disable_reg:
 	if (!st->use_internal_vref)
 	if (!st->use_internal_vref)
 		regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
 		regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
-error_free_reg:
-	if (!st->use_internal_vref)
-		regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
-error_free:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -514,12 +509,8 @@ static int ad5064_remove(struct device *dev)
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 
 
-	if (!st->use_internal_vref) {
+	if (!st->use_internal_vref)
 		regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
 		regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
-		regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
-	}
-
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 11
drivers/iio/dac/ad5360.c

@@ -459,7 +459,7 @@ static int ad5360_probe(struct spi_device *spi)
 	unsigned int i;
 	unsigned int i;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL) {
 	if (indio_dev == NULL) {
 		dev_err(&spi->dev, "Failed to allocate iio device\n");
 		dev_err(&spi->dev, "Failed to allocate iio device\n");
 		return  -ENOMEM;
 		return  -ENOMEM;
@@ -480,13 +480,13 @@ static int ad5360_probe(struct spi_device *spi)
 	ret = ad5360_alloc_channels(indio_dev);
 	ret = ad5360_alloc_channels(indio_dev);
 	if (ret) {
 	if (ret) {
 		dev_err(&spi->dev, "Failed to allocate channel spec: %d\n", ret);
 		dev_err(&spi->dev, "Failed to allocate channel spec: %d\n", ret);
-		goto error_free;
+		return ret;
 	}
 	}
 
 
 	for (i = 0; i < st->chip_info->num_vrefs; ++i)
 	for (i = 0; i < st->chip_info->num_vrefs; ++i)
 		st->vref_reg[i].supply = ad5360_vref_name[i];
 		st->vref_reg[i].supply = ad5360_vref_name[i];
 
 
-	ret = regulator_bulk_get(&st->spi->dev, st->chip_info->num_vrefs,
+	ret = devm_regulator_bulk_get(&st->spi->dev, st->chip_info->num_vrefs,
 		st->vref_reg);
 		st->vref_reg);
 	if (ret) {
 	if (ret) {
 		dev_err(&spi->dev, "Failed to request vref regulators: %d\n", ret);
 		dev_err(&spi->dev, "Failed to request vref regulators: %d\n", ret);
@@ -496,7 +496,7 @@ static int ad5360_probe(struct spi_device *spi)
 	ret = regulator_bulk_enable(st->chip_info->num_vrefs, st->vref_reg);
 	ret = regulator_bulk_enable(st->chip_info->num_vrefs, st->vref_reg);
 	if (ret) {
 	if (ret) {
 		dev_err(&spi->dev, "Failed to enable vref regulators: %d\n", ret);
 		dev_err(&spi->dev, "Failed to enable vref regulators: %d\n", ret);
-		goto error_free_reg;
+		goto error_free_channels;
 	}
 	}
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
@@ -509,12 +509,8 @@ static int ad5360_probe(struct spi_device *spi)
 
 
 error_disable_reg:
 error_disable_reg:
 	regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
 	regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
-error_free_reg:
-	regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);
 error_free_channels:
 error_free_channels:
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-error_free:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -529,9 +525,6 @@ static int ad5360_remove(struct spi_device *spi)
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
 
 
 	regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
 	regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
-	regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);
-
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 14
drivers/iio/dac/ad5380.c

@@ -369,11 +369,10 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
 	unsigned int ctrl = 0;
 	unsigned int ctrl = 0;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
 	if (indio_dev == NULL) {
 	if (indio_dev == NULL) {
 		dev_err(dev, "Failed to allocate iio device\n");
 		dev_err(dev, "Failed to allocate iio device\n");
-		ret = -ENOMEM;
-		goto error_out;
+		return -ENOMEM;
 	}
 	}
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
@@ -391,13 +390,13 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
 	ret = ad5380_alloc_channels(indio_dev);
 	ret = ad5380_alloc_channels(indio_dev);
 	if (ret) {
 	if (ret) {
 		dev_err(dev, "Failed to allocate channel spec: %d\n", ret);
 		dev_err(dev, "Failed to allocate channel spec: %d\n", ret);
-		goto error_free;
+		return ret;
 	}
 	}
 
 
 	if (st->chip_info->int_vref == 2500000)
 	if (st->chip_info->int_vref == 2500000)
 		ctrl |= AD5380_CTRL_INT_VREF_2V5;
 		ctrl |= AD5380_CTRL_INT_VREF_2V5;
 
 
-	st->vref_reg = regulator_get(dev, "vref");
+	st->vref_reg = devm_regulator_get(dev, "vref");
 	if (!IS_ERR(st->vref_reg)) {
 	if (!IS_ERR(st->vref_reg)) {
 		ret = regulator_enable(st->vref_reg);
 		ret = regulator_enable(st->vref_reg);
 		if (ret) {
 		if (ret) {
@@ -434,13 +433,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
 	if (!IS_ERR(st->vref_reg))
 	if (!IS_ERR(st->vref_reg))
 		regulator_disable(st->vref_reg);
 		regulator_disable(st->vref_reg);
 error_free_reg:
 error_free_reg:
-	if (!IS_ERR(st->vref_reg))
-		regulator_put(st->vref_reg);
-
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-error_free:
-	iio_device_free(indio_dev);
-error_out:
 
 
 	return ret;
 	return ret;
 }
 }
@@ -456,11 +449,8 @@ static int ad5380_remove(struct device *dev)
 
 
 	if (!IS_ERR(st->vref_reg)) {
 	if (!IS_ERR(st->vref_reg)) {
 		regulator_disable(st->vref_reg);
 		regulator_disable(st->vref_reg);
-		regulator_put(st->vref_reg);
 	}
 	}
 
 
-	iio_device_free(indio_dev);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 4 - 15
drivers/iio/dac/ad5421.c

@@ -451,7 +451,7 @@ static int ad5421_probe(struct spi_device *spi)
 	struct ad5421_state *st;
 	struct ad5421_state *st;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL) {
 	if (indio_dev == NULL) {
 		dev_err(&spi->dev, "Failed to allocate iio device\n");
 		dev_err(&spi->dev, "Failed to allocate iio device\n");
 		return  -ENOMEM;
 		return  -ENOMEM;
@@ -484,31 +484,23 @@ static int ad5421_probe(struct spi_device *spi)
 	ad5421_update_ctrl(indio_dev, 0, 0);
 	ad5421_update_ctrl(indio_dev, 0, 0);
 
 
 	if (spi->irq) {
 	if (spi->irq) {
-		ret = request_threaded_irq(spi->irq,
+		ret = devm_request_threaded_irq(&spi->dev, spi->irq,
 					   NULL,
 					   NULL,
 					   ad5421_fault_handler,
 					   ad5421_fault_handler,
 					   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 					   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 					   "ad5421 fault",
 					   "ad5421 fault",
 					   indio_dev);
 					   indio_dev);
 		if (ret)
 		if (ret)
-			goto error_free;
+			return ret;
 	}
 	}
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret) {
 	if (ret) {
 		dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
 		dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
-		goto error_free_irq;
+		return ret;
 	}
 	}
 
 
 	return 0;
 	return 0;
-
-error_free_irq:
-	if (spi->irq)
-		free_irq(spi->irq, indio_dev);
-error_free:
-	iio_device_free(indio_dev);
-
-	return ret;
 }
 }
 
 
 static int ad5421_remove(struct spi_device *spi)
 static int ad5421_remove(struct spi_device *spi)
@@ -516,9 +508,6 @@ static int ad5421_remove(struct spi_device *spi)
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
-	if (spi->irq)
-		free_irq(spi->irq, indio_dev);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 5 - 14
drivers/iio/dac/ad5446.c

@@ -220,11 +220,11 @@ static int ad5446_probe(struct device *dev, const char *name,
 	struct regulator *reg;
 	struct regulator *reg;
 	int ret, voltage_uv = 0;
 	int ret, voltage_uv = 0;
 
 
-	reg = regulator_get(dev, "vcc");
+	reg = devm_regulator_get(dev, "vcc");
 	if (!IS_ERR(reg)) {
 	if (!IS_ERR(reg)) {
 		ret = regulator_enable(reg);
 		ret = regulator_enable(reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 
 
 		ret = regulator_get_voltage(reg);
 		ret = regulator_get_voltage(reg);
 		if (ret < 0)
 		if (ret < 0)
@@ -233,7 +233,7 @@ static int ad5446_probe(struct device *dev, const char *name,
 		voltage_uv = ret;
 		voltage_uv = ret;
 	}
 	}
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
 	if (indio_dev == NULL) {
 	if (indio_dev == NULL) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
 		goto error_disable_reg;
 		goto error_disable_reg;
@@ -264,19 +264,13 @@ static int ad5446_probe(struct device *dev, const char *name,
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret)
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
 
 
 	return 0;
 	return 0;
 
 
-error_free_device:
-	iio_device_free(indio_dev);
 error_disable_reg:
 error_disable_reg:
 	if (!IS_ERR(reg))
 	if (!IS_ERR(reg))
 		regulator_disable(reg);
 		regulator_disable(reg);
-error_put_reg:
-	if (!IS_ERR(reg))
-		regulator_put(reg);
-
 	return ret;
 	return ret;
 }
 }
 
 
@@ -286,11 +280,8 @@ static int ad5446_remove(struct device *dev)
 	struct ad5446_state *st = iio_priv(indio_dev);
 	struct ad5446_state *st = iio_priv(indio_dev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
-	if (!IS_ERR(st->reg)) {
+	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-		regulator_put(st->reg);
-	}
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 11
drivers/iio/dac/ad5449.c

@@ -275,7 +275,7 @@ static int ad5449_spi_probe(struct spi_device *spi)
 	unsigned int i;
 	unsigned int i;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -288,14 +288,14 @@ static int ad5449_spi_probe(struct spi_device *spi)
 	for (i = 0; i < st->chip_info->num_channels; ++i)
 	for (i = 0; i < st->chip_info->num_channels; ++i)
 		st->vref_reg[i].supply = ad5449_vref_name(st, i);
 		st->vref_reg[i].supply = ad5449_vref_name(st, i);
 
 
-	ret = regulator_bulk_get(&spi->dev, st->chip_info->num_channels,
+	ret = devm_regulator_bulk_get(&spi->dev, st->chip_info->num_channels,
 				st->vref_reg);
 				st->vref_reg);
 	if (ret)
 	if (ret)
-		goto error_free;
+		return ret;
 
 
 	ret = regulator_bulk_enable(st->chip_info->num_channels, st->vref_reg);
 	ret = regulator_bulk_enable(st->chip_info->num_channels, st->vref_reg);
 	if (ret)
 	if (ret)
-		goto error_free_reg;
+		return ret;
 
 
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->name = id->name;
 	indio_dev->name = id->name;
@@ -325,10 +325,6 @@ static int ad5449_spi_probe(struct spi_device *spi)
 
 
 error_disable_reg:
 error_disable_reg:
 	regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
 	regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
-error_free_reg:
-	regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
-error_free:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -341,9 +337,6 @@ static int ad5449_spi_remove(struct spi_device *spi)
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 
 
 	regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
 	regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
-	regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
-
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 8 - 23
drivers/iio/dac/ad5504.c

@@ -281,16 +281,14 @@ static int ad5504_probe(struct spi_device *spi)
 	struct regulator *reg;
 	struct regulator *reg;
 	int ret, voltage_uv = 0;
 	int ret, voltage_uv = 0;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	reg = regulator_get(&spi->dev, "vcc");
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
+	reg = devm_regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(reg)) {
 	if (!IS_ERR(reg)) {
 		ret = regulator_enable(reg);
 		ret = regulator_enable(reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 
 
 		ret = regulator_get_voltage(reg);
 		ret = regulator_get_voltage(reg);
 		if (ret < 0)
 		if (ret < 0)
@@ -321,7 +319,7 @@ static int ad5504_probe(struct spi_device *spi)
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 
 	if (spi->irq) {
 	if (spi->irq) {
-		ret = request_threaded_irq(spi->irq,
+		ret = devm_request_threaded_irq(&spi->dev, spi->irq,
 					   NULL,
 					   NULL,
 					   &ad5504_event_handler,
 					   &ad5504_event_handler,
 					   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 					   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
@@ -333,22 +331,14 @@ static int ad5504_probe(struct spi_device *spi)
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret)
 	if (ret)
-		goto error_free_irq;
+		goto error_disable_reg;
 
 
 	return 0;
 	return 0;
 
 
-error_free_irq:
-	if (spi->irq)
-		free_irq(spi->irq, indio_dev);
 error_disable_reg:
 error_disable_reg:
 	if (!IS_ERR(reg))
 	if (!IS_ERR(reg))
 		regulator_disable(reg);
 		regulator_disable(reg);
-error_put_reg:
-	if (!IS_ERR(reg))
-		regulator_put(reg);
 
 
-	iio_device_free(indio_dev);
-error_ret:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -358,14 +348,9 @@ static int ad5504_remove(struct spi_device *spi)
 	struct ad5504_state *st = iio_priv(indio_dev);
 	struct ad5504_state *st = iio_priv(indio_dev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
-	if (spi->irq)
-		free_irq(spi->irq, indio_dev);
 
 
-	if (!IS_ERR(st->reg)) {
+	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-		regulator_put(st->reg);
-	}
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 6 - 16
drivers/iio/dac/ad5624r_spi.c

@@ -226,17 +226,15 @@ static int ad5624r_probe(struct spi_device *spi)
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int ret, voltage_uv = 0;
 	int ret, voltage_uv = 0;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
-	st->reg = regulator_get(&spi->dev, "vcc");
+	st->reg = devm_regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
 	if (!IS_ERR(st->reg)) {
 		ret = regulator_enable(st->reg);
 		ret = regulator_enable(st->reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 
 
 		ret = regulator_get_voltage(st->reg);
 		ret = regulator_get_voltage(st->reg);
 		if (ret < 0)
 		if (ret < 0)
@@ -277,11 +275,6 @@ static int ad5624r_probe(struct spi_device *spi)
 error_disable_reg:
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-error_put_reg:
-	if (!IS_ERR(st->reg))
-		regulator_put(st->reg);
-	iio_device_free(indio_dev);
-error_ret:
 
 
 	return ret;
 	return ret;
 }
 }
@@ -292,11 +285,8 @@ static int ad5624r_remove(struct spi_device *spi)
 	struct ad5624r_state *st = iio_priv(indio_dev);
 	struct ad5624r_state *st = iio_priv(indio_dev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
-	if (!IS_ERR(st->reg)) {
+	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-		regulator_put(st->reg);
-	}
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 13
drivers/iio/dac/ad5686.c

@@ -314,18 +314,18 @@ static int ad5686_probe(struct spi_device *spi)
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int ret, regdone = 0, voltage_uv = 0;
 	int ret, regdone = 0, voltage_uv = 0;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return  -ENOMEM;
 		return  -ENOMEM;
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
 
 
-	st->reg = regulator_get(&spi->dev, "vcc");
+	st->reg = devm_regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
 	if (!IS_ERR(st->reg)) {
 		ret = regulator_enable(st->reg);
 		ret = regulator_enable(st->reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 
 
 		ret = regulator_get_voltage(st->reg);
 		ret = regulator_get_voltage(st->reg);
 		if (ret < 0)
 		if (ret < 0)
@@ -369,12 +369,6 @@ static int ad5686_probe(struct spi_device *spi)
 error_disable_reg:
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-error_put_reg:
-	if (!IS_ERR(st->reg))
-		regulator_put(st->reg);
-
-	iio_device_free(indio_dev);
-
 	return ret;
 	return ret;
 }
 }
 
 
@@ -384,11 +378,8 @@ static int ad5686_remove(struct spi_device *spi)
 	struct ad5686_state *st = iio_priv(indio_dev);
 	struct ad5686_state *st = iio_priv(indio_dev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
-	if (!IS_ERR(st->reg)) {
+	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-		regulator_put(st->reg);
-	}
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 10
drivers/iio/dac/ad5755.c

@@ -565,7 +565,7 @@ static int ad5755_probe(struct spi_device *spi)
 	struct ad5755_state *st;
 	struct ad5755_state *st;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL) {
 	if (indio_dev == NULL) {
 		dev_err(&spi->dev, "Failed to allocate iio device\n");
 		dev_err(&spi->dev, "Failed to allocate iio device\n");
 		return  -ENOMEM;
 		return  -ENOMEM;
@@ -589,24 +589,19 @@ static int ad5755_probe(struct spi_device *spi)
 
 
 	ret = ad5755_init_channels(indio_dev, pdata);
 	ret = ad5755_init_channels(indio_dev, pdata);
 	if (ret)
 	if (ret)
-		goto error_free;
+		return ret;
 
 
 	ret = ad5755_setup_pdata(indio_dev, pdata);
 	ret = ad5755_setup_pdata(indio_dev, pdata);
 	if (ret)
 	if (ret)
-		goto error_free;
+		return ret;
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret) {
 	if (ret) {
 		dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
 		dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
-		goto error_free;
+		return ret;
 	}
 	}
 
 
 	return 0;
 	return 0;
-
-error_free:
-	iio_device_free(indio_dev);
-
-	return ret;
 }
 }
 
 
 static int ad5755_remove(struct spi_device *spi)
 static int ad5755_remove(struct spi_device *spi)
@@ -614,7 +609,6 @@ static int ad5755_remove(struct spi_device *spi)
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 5 - 15
drivers/iio/dac/ad5764.c

@@ -275,7 +275,7 @@ static int ad5764_probe(struct spi_device *spi)
 	struct ad5764_state *st;
 	struct ad5764_state *st;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL) {
 	if (indio_dev == NULL) {
 		dev_err(&spi->dev, "Failed to allocate iio device\n");
 		dev_err(&spi->dev, "Failed to allocate iio device\n");
 		return -ENOMEM;
 		return -ENOMEM;
@@ -298,12 +298,12 @@ static int ad5764_probe(struct spi_device *spi)
 		st->vref_reg[0].supply = "vrefAB";
 		st->vref_reg[0].supply = "vrefAB";
 		st->vref_reg[1].supply = "vrefCD";
 		st->vref_reg[1].supply = "vrefCD";
 
 
-		ret = regulator_bulk_get(&st->spi->dev,
+		ret = devm_regulator_bulk_get(&st->spi->dev,
 			ARRAY_SIZE(st->vref_reg), st->vref_reg);
 			ARRAY_SIZE(st->vref_reg), st->vref_reg);
 		if (ret) {
 		if (ret) {
 			dev_err(&spi->dev, "Failed to request vref regulators: %d\n",
 			dev_err(&spi->dev, "Failed to request vref regulators: %d\n",
 				ret);
 				ret);
-			goto error_free;
+			return ret;
 		}
 		}
 
 
 		ret = regulator_bulk_enable(ARRAY_SIZE(st->vref_reg),
 		ret = regulator_bulk_enable(ARRAY_SIZE(st->vref_reg),
@@ -311,7 +311,7 @@ static int ad5764_probe(struct spi_device *spi)
 		if (ret) {
 		if (ret) {
 			dev_err(&spi->dev, "Failed to enable vref regulators: %d\n",
 			dev_err(&spi->dev, "Failed to enable vref regulators: %d\n",
 				ret);
 				ret);
-			goto error_free_reg;
+			return ret;
 		}
 		}
 	}
 	}
 
 
@@ -326,12 +326,6 @@ static int ad5764_probe(struct spi_device *spi)
 error_disable_reg:
 error_disable_reg:
 	if (st->chip_info->int_vref == 0)
 	if (st->chip_info->int_vref == 0)
 		regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
 		regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
-error_free_reg:
-	if (st->chip_info->int_vref == 0)
-		regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
-error_free:
-	iio_device_free(indio_dev);
-
 	return ret;
 	return ret;
 }
 }
 
 
@@ -342,12 +336,8 @@ static int ad5764_remove(struct spi_device *spi)
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 
 
-	if (st->chip_info->int_vref == 0) {
+	if (st->chip_info->int_vref == 0)
 		regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
 		regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
-		regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
-	}
-
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 9 - 26
drivers/iio/dac/ad5791.c

@@ -349,17 +349,15 @@ static int ad5791_probe(struct spi_device *spi)
 	struct ad5791_state *st;
 	struct ad5791_state *st;
 	int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
 	int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
-	st->reg_vdd = regulator_get(&spi->dev, "vdd");
+	st->reg_vdd = devm_regulator_get(&spi->dev, "vdd");
 	if (!IS_ERR(st->reg_vdd)) {
 	if (!IS_ERR(st->reg_vdd)) {
 		ret = regulator_enable(st->reg_vdd);
 		ret = regulator_enable(st->reg_vdd);
 		if (ret)
 		if (ret)
-			goto error_put_reg_pos;
+			return ret;
 
 
 		ret = regulator_get_voltage(st->reg_vdd);
 		ret = regulator_get_voltage(st->reg_vdd);
 		if (ret < 0)
 		if (ret < 0)
@@ -368,11 +366,11 @@ static int ad5791_probe(struct spi_device *spi)
 		pos_voltage_uv = ret;
 		pos_voltage_uv = ret;
 	}
 	}
 
 
-	st->reg_vss = regulator_get(&spi->dev, "vss");
+	st->reg_vss = devm_regulator_get(&spi->dev, "vss");
 	if (!IS_ERR(st->reg_vss)) {
 	if (!IS_ERR(st->reg_vss)) {
 		ret = regulator_enable(st->reg_vss);
 		ret = regulator_enable(st->reg_vss);
 		if (ret)
 		if (ret)
-			goto error_put_reg_neg;
+			goto error_disable_reg_pos;
 
 
 		ret = regulator_get_voltage(st->reg_vss);
 		ret = regulator_get_voltage(st->reg_vss);
 		if (ret < 0)
 		if (ret < 0)
@@ -428,19 +426,9 @@ static int ad5791_probe(struct spi_device *spi)
 error_disable_reg_neg:
 error_disable_reg_neg:
 	if (!IS_ERR(st->reg_vss))
 	if (!IS_ERR(st->reg_vss))
 		regulator_disable(st->reg_vss);
 		regulator_disable(st->reg_vss);
-error_put_reg_neg:
-	if (!IS_ERR(st->reg_vss))
-		regulator_put(st->reg_vss);
-
 error_disable_reg_pos:
 error_disable_reg_pos:
 	if (!IS_ERR(st->reg_vdd))
 	if (!IS_ERR(st->reg_vdd))
 		regulator_disable(st->reg_vdd);
 		regulator_disable(st->reg_vdd);
-error_put_reg_pos:
-	if (!IS_ERR(st->reg_vdd))
-		regulator_put(st->reg_vdd);
-	iio_device_free(indio_dev);
-error_ret:
-
 	return ret;
 	return ret;
 }
 }
 
 
@@ -450,16 +438,11 @@ static int ad5791_remove(struct spi_device *spi)
 	struct ad5791_state *st = iio_priv(indio_dev);
 	struct ad5791_state *st = iio_priv(indio_dev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
-	if (!IS_ERR(st->reg_vdd)) {
+	if (!IS_ERR(st->reg_vdd))
 		regulator_disable(st->reg_vdd);
 		regulator_disable(st->reg_vdd);
-		regulator_put(st->reg_vdd);
-	}
 
 
-	if (!IS_ERR(st->reg_vss)) {
+	if (!IS_ERR(st->reg_vss))
 		regulator_disable(st->reg_vss);
 		regulator_disable(st->reg_vss);
-		regulator_put(st->reg_vss);
-	}
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 8 - 23
drivers/iio/dac/ad7303.c

@@ -203,7 +203,7 @@ static int ad7303_probe(struct spi_device *spi)
 	bool ext_ref;
 	bool ext_ref;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -212,15 +212,13 @@ static int ad7303_probe(struct spi_device *spi)
 
 
 	st->spi = spi;
 	st->spi = spi;
 
 
-	st->vdd_reg = regulator_get(&spi->dev, "Vdd");
-	if (IS_ERR(st->vdd_reg)) {
-		ret = PTR_ERR(st->vdd_reg);
-		goto err_free;
-	}
+	st->vdd_reg = devm_regulator_get(&spi->dev, "Vdd");
+	if (IS_ERR(st->vdd_reg))
+		return PTR_ERR(st->vdd_reg);
 
 
 	ret = regulator_enable(st->vdd_reg);
 	ret = regulator_enable(st->vdd_reg);
 	if (ret)
 	if (ret)
-		goto err_put_vdd_reg;
+		return ret;
 
 
 	if (spi->dev.of_node) {
 	if (spi->dev.of_node) {
 		ext_ref = of_property_read_bool(spi->dev.of_node,
 		ext_ref = of_property_read_bool(spi->dev.of_node,
@@ -234,7 +232,7 @@ static int ad7303_probe(struct spi_device *spi)
 	}
 	}
 
 
 	if (ext_ref) {
 	if (ext_ref) {
-		st->vref_reg = regulator_get(&spi->dev, "REF");
+		st->vref_reg = devm_regulator_get(&spi->dev, "REF");
 		if (IS_ERR(st->vref_reg)) {
 		if (IS_ERR(st->vref_reg)) {
 			ret = PTR_ERR(st->vref_reg);
 			ret = PTR_ERR(st->vref_reg);
 			goto err_disable_vdd_reg;
 			goto err_disable_vdd_reg;
@@ -242,7 +240,7 @@ static int ad7303_probe(struct spi_device *spi)
 
 
 		ret = regulator_enable(st->vref_reg);
 		ret = regulator_enable(st->vref_reg);
 		if (ret)
 		if (ret)
-			goto err_put_vref_reg;
+			goto err_disable_vdd_reg;
 
 
 		st->config |= AD7303_CFG_EXTERNAL_VREF;
 		st->config |= AD7303_CFG_EXTERNAL_VREF;
 	}
 	}
@@ -263,16 +261,8 @@ static int ad7303_probe(struct spi_device *spi)
 err_disable_vref_reg:
 err_disable_vref_reg:
 	if (st->vref_reg)
 	if (st->vref_reg)
 		regulator_disable(st->vref_reg);
 		regulator_disable(st->vref_reg);
-err_put_vref_reg:
-	if (st->vref_reg)
-		regulator_put(st->vref_reg);
 err_disable_vdd_reg:
 err_disable_vdd_reg:
 	regulator_disable(st->vdd_reg);
 	regulator_disable(st->vdd_reg);
-err_put_vdd_reg:
-	regulator_put(st->vdd_reg);
-err_free:
-	iio_device_free(indio_dev);
-
 	return ret;
 	return ret;
 }
 }
 
 
@@ -283,14 +273,9 @@ static int ad7303_remove(struct spi_device *spi)
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 
 
-	if (st->vref_reg) {
+	if (st->vref_reg)
 		regulator_disable(st->vref_reg);
 		regulator_disable(st->vref_reg);
-		regulator_put(st->vref_reg);
-	}
 	regulator_disable(st->vdd_reg);
 	regulator_disable(st->vdd_reg);
-	regulator_put(st->vdd_reg);
-
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 13
drivers/iio/dac/max517.c

@@ -164,11 +164,9 @@ static int max517_probe(struct i2c_client *client,
 	struct max517_platform_data *platform_data = client->dev.platform_data;
 	struct max517_platform_data *platform_data = client->dev.platform_data;
 	int err;
 	int err;
 
 
-	indio_dev = iio_device_alloc(sizeof(*data));
-	if (indio_dev == NULL) {
-		err = -ENOMEM;
-		goto exit;
-	}
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
 	data = iio_priv(indio_dev);
 	data = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
 	i2c_set_clientdata(client, indio_dev);
 	data->client = client;
 	data->client = client;
@@ -198,23 +196,16 @@ static int max517_probe(struct i2c_client *client,
 
 
 	err = iio_device_register(indio_dev);
 	err = iio_device_register(indio_dev);
 	if (err)
 	if (err)
-		goto exit_free_device;
+		return err;
 
 
 	dev_info(&client->dev, "DAC registered\n");
 	dev_info(&client->dev, "DAC registered\n");
 
 
 	return 0;
 	return 0;
-
-exit_free_device:
-	iio_device_free(indio_dev);
-exit:
-	return err;
 }
 }
 
 
 static int max517_remove(struct i2c_client *client)
 static int max517_remove(struct i2c_client *client)
 {
 {
 	iio_device_unregister(i2c_get_clientdata(client));
 	iio_device_unregister(i2c_get_clientdata(client));
-	iio_device_free(i2c_get_clientdata(client));
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 154 - 23
drivers/iio/dac/mcp4725.c

@@ -12,14 +12,13 @@
  * driver for the Microchip I2C 12-bit digital-to-analog converter (DAC)
  * driver for the Microchip I2C 12-bit digital-to-analog converter (DAC)
  * (7-bit I2C slave address 0x60, the three LSBs can be configured in
  * (7-bit I2C slave address 0x60, the three LSBs can be configured in
  * hardware)
  * hardware)
- *
- * writing the DAC value to EEPROM is not supported
  */
  */
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
 #include <linux/err.h>
+#include <linux/delay.h>
 
 
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/sysfs.h>
@@ -32,15 +31,19 @@ struct mcp4725_data {
 	struct i2c_client *client;
 	struct i2c_client *client;
 	u16 vref_mv;
 	u16 vref_mv;
 	u16 dac_value;
 	u16 dac_value;
+	bool powerdown;
+	unsigned powerdown_mode;
 };
 };
 
 
-#ifdef CONFIG_PM_SLEEP
 static int mcp4725_suspend(struct device *dev)
 static int mcp4725_suspend(struct device *dev)
 {
 {
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct mcp4725_data *data = iio_priv(indio_dev);
 	u8 outbuf[2];
 	u8 outbuf[2];
 
 
-	outbuf[0] = 0x3 << 4; /* power-down bits, 500 kOhm resistor */
+	outbuf[0] = (data->powerdown_mode + 1) << 4;
 	outbuf[1] = 0;
 	outbuf[1] = 0;
+	data->powerdown = true;
 
 
 	return i2c_master_send(to_i2c_client(dev), outbuf, 2);
 	return i2c_master_send(to_i2c_client(dev), outbuf, 2);
 }
 }
@@ -54,16 +57,150 @@ static int mcp4725_resume(struct device *dev)
 	/* restore previous DAC value */
 	/* restore previous DAC value */
 	outbuf[0] = (data->dac_value >> 8) & 0xf;
 	outbuf[0] = (data->dac_value >> 8) & 0xf;
 	outbuf[1] = data->dac_value & 0xff;
 	outbuf[1] = data->dac_value & 0xff;
+	data->powerdown = false;
 
 
 	return i2c_master_send(to_i2c_client(dev), outbuf, 2);
 	return i2c_master_send(to_i2c_client(dev), outbuf, 2);
 }
 }
 
 
+#ifdef CONFIG_PM_SLEEP
 static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume);
 static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume);
 #define MCP4725_PM_OPS (&mcp4725_pm_ops)
 #define MCP4725_PM_OPS (&mcp4725_pm_ops)
 #else
 #else
 #define MCP4725_PM_OPS NULL
 #define MCP4725_PM_OPS NULL
 #endif
 #endif
 
 
+static ssize_t mcp4725_store_eeprom(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+	struct mcp4725_data *data = iio_priv(indio_dev);
+	int tries = 20;
+	u8 inoutbuf[3];
+	bool state;
+	int ret;
+
+	ret = strtobool(buf, &state);
+	if (ret < 0)
+		return ret;
+
+	if (!state)
+		return 0;
+
+	inoutbuf[0] = 0x60; /* write EEPROM */
+	inoutbuf[1] = data->dac_value >> 4;
+	inoutbuf[2] = (data->dac_value & 0xf) << 4;
+
+	ret = i2c_master_send(data->client, inoutbuf, 3);
+	if (ret < 0)
+		return ret;
+	else if (ret != 3)
+		return -EIO;
+
+	/* wait for write complete, takes up to 50ms */
+	while (tries--) {
+		msleep(20);
+		ret = i2c_master_recv(data->client, inoutbuf, 3);
+		if (ret < 0)
+			return ret;
+		else if (ret != 3)
+			return -EIO;
+
+		if (inoutbuf[0] & 0x80)
+			break;
+	}
+
+	if (tries < 0) {
+		dev_err(&data->client->dev,
+			"mcp4725_store_eeprom() failed, incomplete\n");
+		return -EIO;
+	}
+
+	return len;
+}
+
+static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR, NULL, mcp4725_store_eeprom, 0);
+
+static struct attribute *mcp4725_attributes[] = {
+	&iio_dev_attr_store_eeprom.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group mcp4725_attribute_group = {
+	.attrs = mcp4725_attributes,
+};
+
+static const char * const mcp4725_powerdown_modes[] = {
+	"1kohm_to_gnd",
+	"100kohm_to_gnd",
+	"500kohm_to_gnd"
+};
+
+static int mcp4725_get_powerdown_mode(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan)
+{
+	struct mcp4725_data *data = iio_priv(indio_dev);
+
+	return data->powerdown_mode;
+}
+
+static int mcp4725_set_powerdown_mode(struct iio_dev *indio_dev,
+	const struct iio_chan_spec *chan, unsigned mode)
+{
+	struct mcp4725_data *data = iio_priv(indio_dev);
+
+	data->powerdown_mode = mode;
+
+	return 0;
+}
+
+static ssize_t mcp4725_read_powerdown(struct iio_dev *indio_dev,
+	uintptr_t private, const struct iio_chan_spec *chan, char *buf)
+{
+	struct mcp4725_data *data = iio_priv(indio_dev);
+
+	return sprintf(buf, "%d\n", data->powerdown);
+}
+
+static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev,
+	 uintptr_t private, const struct iio_chan_spec *chan,
+	 const char *buf, size_t len)
+{
+	struct mcp4725_data *data = iio_priv(indio_dev);
+	bool state;
+	int ret;
+
+	ret = strtobool(buf, &state);
+	if (ret)
+		return ret;
+
+	if (state)
+		ret = mcp4725_suspend(&data->client->dev);
+	else
+		ret = mcp4725_resume(&data->client->dev);
+	if (ret < 0)
+		return ret;
+
+	return len;
+}
+
+static const struct iio_enum mcp4725_powerdown_mode_enum = {
+	.items = mcp4725_powerdown_modes,
+	.num_items = ARRAY_SIZE(mcp4725_powerdown_modes),
+	.get = mcp4725_get_powerdown_mode,
+	.set = mcp4725_set_powerdown_mode,
+};
+
+static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
+	{
+		.name = "powerdown",
+		.read = mcp4725_read_powerdown,
+		.write = mcp4725_write_powerdown,
+	},
+	IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum),
+	IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
+	{ },
+};
+
 static const struct iio_chan_spec mcp4725_channel = {
 static const struct iio_chan_spec mcp4725_channel = {
 	.type		= IIO_VOLTAGE,
 	.type		= IIO_VOLTAGE,
 	.indexed	= 1,
 	.indexed	= 1,
@@ -72,6 +209,7 @@ static const struct iio_chan_spec mcp4725_channel = {
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
 	.scan_type	= IIO_ST('u', 12, 16, 0),
 	.scan_type	= IIO_ST('u', 12, 16, 0),
+	.ext_info	= mcp4725_ext_info,
 };
 };
 
 
 static int mcp4725_set_value(struct iio_dev *indio_dev, int val)
 static int mcp4725_set_value(struct iio_dev *indio_dev, int val)
@@ -138,6 +276,7 @@ static int mcp4725_write_raw(struct iio_dev *indio_dev,
 static const struct iio_info mcp4725_info = {
 static const struct iio_info mcp4725_info = {
 	.read_raw = mcp4725_read_raw,
 	.read_raw = mcp4725_read_raw,
 	.write_raw = mcp4725_write_raw,
 	.write_raw = mcp4725_write_raw,
+	.attrs = &mcp4725_attribute_group,
 	.driver_module = THIS_MODULE,
 	.driver_module = THIS_MODULE,
 };
 };
 
 
@@ -148,19 +287,17 @@ static int mcp4725_probe(struct i2c_client *client,
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	struct mcp4725_platform_data *platform_data = client->dev.platform_data;
 	struct mcp4725_platform_data *platform_data = client->dev.platform_data;
 	u8 inbuf[3];
 	u8 inbuf[3];
+	u8 pd;
 	int err;
 	int err;
 
 
 	if (!platform_data || !platform_data->vref_mv) {
 	if (!platform_data || !platform_data->vref_mv) {
 		dev_err(&client->dev, "invalid platform data");
 		dev_err(&client->dev, "invalid platform data");
-		err = -EINVAL;
-		goto exit;
+		return -EINVAL;
 	}
 	}
 
 
-	indio_dev = iio_device_alloc(sizeof(*data));
-	if (indio_dev == NULL) {
-		err = -ENOMEM;
-		goto exit;
-	}
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (indio_dev == NULL)
+		return -ENOMEM;
 	data = iio_priv(indio_dev);
 	data = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
 	i2c_set_clientdata(client, indio_dev);
 	data->client = client;
 	data->client = client;
@@ -177,31 +314,25 @@ static int mcp4725_probe(struct i2c_client *client,
 	err = i2c_master_recv(client, inbuf, 3);
 	err = i2c_master_recv(client, inbuf, 3);
 	if (err < 0) {
 	if (err < 0) {
 		dev_err(&client->dev, "failed to read DAC value");
 		dev_err(&client->dev, "failed to read DAC value");
-		goto exit_free_device;
+		return err;
 	}
 	}
+	pd = (inbuf[0] >> 1) & 0x3;
+	data->powerdown = pd > 0 ? true : false;
+	data->powerdown_mode = pd ? pd-1 : 2; /* 500kohm_to_gnd */
 	data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4);
 	data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4);
 
 
 	err = iio_device_register(indio_dev);
 	err = iio_device_register(indio_dev);
 	if (err)
 	if (err)
-		goto exit_free_device;
+		return err;
 
 
 	dev_info(&client->dev, "MCP4725 DAC registered\n");
 	dev_info(&client->dev, "MCP4725 DAC registered\n");
 
 
 	return 0;
 	return 0;
-
-exit_free_device:
-	iio_device_free(indio_dev);
-exit:
-	return err;
 }
 }
 
 
 static int mcp4725_remove(struct i2c_client *client)
 static int mcp4725_remove(struct i2c_client *client)
 {
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(client);
-
-	iio_device_unregister(indio_dev);
-	iio_device_free(indio_dev);
-
+	iio_device_unregister(i2c_get_clientdata(client));
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 0
drivers/iio/frequency/Kconfig

@@ -4,6 +4,7 @@
 #	Clock Distribution device drivers
 #	Clock Distribution device drivers
 #	Phase-Locked Loop (PLL) frequency synthesizers
 #	Phase-Locked Loop (PLL) frequency synthesizers
 #
 #
+# When adding new entries keep the list in alphabetical order
 
 
 menu "Frequency Synthesizers DDS/PLL"
 menu "Frequency Synthesizers DDS/PLL"
 
 

+ 1 - 0
drivers/iio/frequency/Makefile

@@ -2,5 +2,6 @@
 # Makefile iio/frequency
 # Makefile iio/frequency
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AD9523) += ad9523.o
 obj-$(CONFIG_AD9523) += ad9523.o
 obj-$(CONFIG_ADF4350) += adf4350.o
 obj-$(CONFIG_ADF4350) += adf4350.o

+ 4 - 13
drivers/iio/frequency/ad9523.c

@@ -961,17 +961,17 @@ static int ad9523_probe(struct spi_device *spi)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 
 
-	st->reg = regulator_get(&spi->dev, "vcc");
+	st->reg = devm_regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
 	if (!IS_ERR(st->reg)) {
 		ret = regulator_enable(st->reg);
 		ret = regulator_enable(st->reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			return ret;
 	}
 	}
 
 
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
@@ -1001,11 +1001,6 @@ static int ad9523_probe(struct spi_device *spi)
 error_disable_reg:
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-error_put_reg:
-	if (!IS_ERR(st->reg))
-		regulator_put(st->reg);
-
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -1017,12 +1012,8 @@ static int ad9523_remove(struct spi_device *spi)
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 
 
-	if (!IS_ERR(st->reg)) {
+	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-		regulator_put(st->reg);
-	}
-
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 9 - 22
drivers/iio/frequency/adf4350.c

@@ -515,7 +515,7 @@ static int adf4350_probe(struct spi_device *spi)
 	}
 	}
 
 
 	if (!pdata->clkin) {
 	if (!pdata->clkin) {
-		clk = clk_get(&spi->dev, "clkin");
+		clk = devm_clk_get(&spi->dev, "clkin");
 		if (IS_ERR(clk))
 		if (IS_ERR(clk))
 			return -EPROBE_DEFER;
 			return -EPROBE_DEFER;
 
 
@@ -524,17 +524,17 @@ static int adf4350_probe(struct spi_device *spi)
 			return ret;
 			return ret;
 	}
 	}
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 
 
-	st->reg = regulator_get(&spi->dev, "vcc");
+	st->reg = devm_regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
 	if (!IS_ERR(st->reg)) {
 		ret = regulator_enable(st->reg);
 		ret = regulator_enable(st->reg);
 		if (ret)
 		if (ret)
-			goto error_put_reg;
+			goto error_disable_clk;
 	}
 	}
 
 
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
@@ -564,7 +564,8 @@ static int adf4350_probe(struct spi_device *spi)
 	memset(st->regs_hw, 0xFF, sizeof(st->regs_hw));
 	memset(st->regs_hw, 0xFF, sizeof(st->regs_hw));
 
 
 	if (gpio_is_valid(pdata->gpio_lock_detect)) {
 	if (gpio_is_valid(pdata->gpio_lock_detect)) {
-		ret = gpio_request(pdata->gpio_lock_detect, indio_dev->name);
+		ret = devm_gpio_request(&spi->dev, pdata->gpio_lock_detect,
+					indio_dev->name);
 		if (ret) {
 		if (ret) {
 			dev_err(&spi->dev, "fail to request lock detect GPIO-%d",
 			dev_err(&spi->dev, "fail to request lock detect GPIO-%d",
 				pdata->gpio_lock_detect);
 				pdata->gpio_lock_detect);
@@ -576,29 +577,21 @@ static int adf4350_probe(struct spi_device *spi)
 	if (pdata->power_up_frequency) {
 	if (pdata->power_up_frequency) {
 		ret = adf4350_set_freq(st, pdata->power_up_frequency);
 		ret = adf4350_set_freq(st, pdata->power_up_frequency);
 		if (ret)
 		if (ret)
-			goto error_free_gpio;
+			goto error_disable_reg;
 	}
 	}
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret)
 	if (ret)
-		goto error_free_gpio;
+		goto error_disable_reg;
 
 
 	return 0;
 	return 0;
 
 
-error_free_gpio:
-	if (gpio_is_valid(pdata->gpio_lock_detect))
-		gpio_free(pdata->gpio_lock_detect);
-
 error_disable_reg:
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 		regulator_disable(st->reg);
-error_put_reg:
-	if (!IS_ERR(st->reg))
-		regulator_put(st->reg);
-
+error_disable_clk:
 	if (clk)
 	if (clk)
 		clk_disable_unprepare(clk);
 		clk_disable_unprepare(clk);
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -619,14 +612,8 @@ static int adf4350_remove(struct spi_device *spi)
 
 
 	if (!IS_ERR(reg)) {
 	if (!IS_ERR(reg)) {
 		regulator_disable(reg);
 		regulator_disable(reg);
-		regulator_put(reg);
 	}
 	}
 
 
-	if (gpio_is_valid(st->pdata->gpio_lock_detect))
-		gpio_free(st->pdata->gpio_lock_detect);
-
-	iio_device_free(indio_dev);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 16 - 2
drivers/iio/gyro/Kconfig

@@ -1,6 +1,8 @@
 #
 #
 # IIO Digital Gyroscope Sensor drivers configuration
 # IIO Digital Gyroscope Sensor drivers configuration
 #
 #
+# When adding new entries keep the list in alphabetical order
+
 menu "Digital gyroscope sensors"
 menu "Digital gyroscope sensors"
 
 
 config ADIS16080
 config ADIS16080
@@ -26,6 +28,18 @@ config ADIS16136
 	  Say yes here to build support for the Analog Devices ADIS16133, ADIS16135,
 	  Say yes here to build support for the Analog Devices ADIS16133, ADIS16135,
 	  ADIS16136 gyroscope devices.
 	  ADIS16136 gyroscope devices.
 
 
+config ADIS16260
+	tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver"
+	depends on SPI
+	select IIO_ADIS_LIB
+	select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
+	help
+	  Say yes here to build support for Analog Devices ADIS16260 ADIS16265
+	  ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adis16260.
+
 config ADXRS450
 config ADXRS450
 	tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver"
 	tristate "Analog Devices ADXRS450/3 Digital Output Gyroscope SPI driver"
 	depends on SPI
 	depends on SPI
@@ -58,8 +72,8 @@ config IIO_ST_GYRO_3AXIS
 	  Say yes here to build support for STMicroelectronics gyroscopes:
 	  Say yes here to build support for STMicroelectronics gyroscopes:
 	  L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330.
 	  L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330.
 
 
-	  This driver can also be built as a module. If so, will be created
-	  these modules:
+	  This driver can also be built as a module. If so, these modules
+	  will be created:
 	  - st_gyro (core functions for the driver [it is mandatory]);
 	  - st_gyro (core functions for the driver [it is mandatory]);
 	  - st_gyro_i2c (necessary for the I2C devices [optional*]);
 	  - st_gyro_i2c (necessary for the I2C devices [optional*]);
 	  - st_gyro_spi (necessary for the SPI devices [optional*]);
 	  - st_gyro_spi (necessary for the SPI devices [optional*]);

+ 2 - 0
drivers/iio/gyro/Makefile

@@ -2,9 +2,11 @@
 # Makefile for industrial I/O gyroscope sensor drivers
 # Makefile for industrial I/O gyroscope sensor drivers
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADIS16080) += adis16080.o
 obj-$(CONFIG_ADIS16080) += adis16080.o
 obj-$(CONFIG_ADIS16130) += adis16130.o
 obj-$(CONFIG_ADIS16130) += adis16130.o
 obj-$(CONFIG_ADIS16136) += adis16136.o
 obj-$(CONFIG_ADIS16136) += adis16136.o
+obj-$(CONFIG_ADIS16260) += adis16260.o
 obj-$(CONFIG_ADXRS450) += adxrs450.o
 obj-$(CONFIG_ADXRS450) += adxrs450.o
 
 
 obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o
 obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o

+ 4 - 17
drivers/iio/gyro/adis16080.c

@@ -192,16 +192,13 @@ static const struct adis16080_chip_info adis16080_chip_info[] = {
 static int adis16080_probe(struct spi_device *spi)
 static int adis16080_probe(struct spi_device *spi)
 {
 {
 	const struct spi_device_id *id = spi_get_device_id(spi);
 	const struct spi_device_id *id = spi_get_device_id(spi);
-	int ret;
 	struct adis16080_state *st;
 	struct adis16080_state *st;
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 
 
 	/* setup the industrialio driver allocated elements */
 	/* setup the industrialio driver allocated elements */
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 	/* this is only used for removal purposes */
 	/* this is only used for removal purposes */
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
@@ -217,22 +214,12 @@ static int adis16080_probe(struct spi_device *spi)
 	indio_dev->info = &adis16080_info;
 	indio_dev->info = &adis16080_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-	return 0;
-
-error_free_dev:
-	iio_device_free(indio_dev);
-error_ret:
-	return ret;
+	return iio_device_register(indio_dev);
 }
 }
 
 
 static int adis16080_remove(struct spi_device *spi)
 static int adis16080_remove(struct spi_device *spi)
 {
 {
 	iio_device_unregister(spi_get_drvdata(spi));
 	iio_device_unregister(spi_get_drvdata(spi));
-	iio_device_free(spi_get_drvdata(spi));
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 4 - 19
drivers/iio/gyro/adis16130.c

@@ -148,16 +148,13 @@ static const struct iio_info adis16130_info = {
 
 
 static int adis16130_probe(struct spi_device *spi)
 static int adis16130_probe(struct spi_device *spi)
 {
 {
-	int ret;
 	struct adis16130_state *st;
 	struct adis16130_state *st;
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 
 
 	/* setup the industrialio driver allocated elements */
 	/* setup the industrialio driver allocated elements */
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 	/* this is only used for removal purposes */
 	/* this is only used for removal purposes */
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
@@ -170,24 +167,12 @@ static int adis16130_probe(struct spi_device *spi)
 	indio_dev->info = &adis16130_info;
 	indio_dev->info = &adis16130_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 
-	ret = iio_device_register(indio_dev);
-	if (ret)
-		goto error_free_dev;
-
-	return 0;
-
-error_free_dev:
-	iio_device_free(indio_dev);
-
-error_ret:
-	return ret;
+	return iio_device_register(indio_dev);
 }
 }
 
 
 static int adis16130_remove(struct spi_device *spi)
 static int adis16130_remove(struct spi_device *spi)
 {
 {
 	iio_device_unregister(spi_get_drvdata(spi));
 	iio_device_unregister(spi_get_drvdata(spi));
-	iio_device_free(spi_get_drvdata(spi));
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 3 - 7
drivers/iio/gyro/adis16136.c

@@ -497,7 +497,7 @@ static int adis16136_probe(struct spi_device *spi)
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*adis16136));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis16136));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -515,11 +515,11 @@ static int adis16136_probe(struct spi_device *spi)
 
 
 	ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data);
 	ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
 	ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL);
 	ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
 	ret = adis16136_initial_setup(indio_dev);
 	ret = adis16136_initial_setup(indio_dev);
 	if (ret)
 	if (ret)
@@ -537,8 +537,6 @@ static int adis16136_probe(struct spi_device *spi)
 	adis16136_stop_device(indio_dev);
 	adis16136_stop_device(indio_dev);
 error_cleanup_buffer:
 error_cleanup_buffer:
 	adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
 	adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
-error_free_dev:
-	iio_device_free(indio_dev);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -552,8 +550,6 @@ static int adis16136_remove(struct spi_device *spi)
 
 
 	adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
 	adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
 
 
-	iio_device_free(indio_dev);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 157 - 162
drivers/staging/iio/gyro/adis16260_core.c → drivers/iio/gyro/adis16260.c

@@ -7,54 +7,119 @@
  */
  */
 
 
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi.h>
-#include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/buffer.h>
+#include <linux/iio/imu/adis.h>
+
+#define ADIS16260_STARTUP_DELAY	220 /* ms */
+
+#define ADIS16260_FLASH_CNT  0x00 /* Flash memory write count */
+#define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */
+#define ADIS16260_GYRO_OUT   0x04 /* X-axis gyroscope output */
+#define ADIS16260_AUX_ADC    0x0A /* analog input channel measurement */
+#define ADIS16260_TEMP_OUT   0x0C /* internal temperature measurement */
+#define ADIS16260_ANGL_OUT   0x0E /* angle displacement */
+#define ADIS16260_GYRO_OFF   0x14 /* Calibration, offset/bias adjustment */
+#define ADIS16260_GYRO_SCALE 0x16 /* Calibration, scale adjustment */
+#define ADIS16260_ALM_MAG1   0x20 /* Alarm 1 magnitude/polarity setting */
+#define ADIS16260_ALM_MAG2   0x22 /* Alarm 2 magnitude/polarity setting */
+#define ADIS16260_ALM_SMPL1  0x24 /* Alarm 1 dynamic rate of change setting */
+#define ADIS16260_ALM_SMPL2  0x26 /* Alarm 2 dynamic rate of change setting */
+#define ADIS16260_ALM_CTRL   0x28 /* Alarm control */
+#define ADIS16260_AUX_DAC    0x30 /* Auxiliary DAC data */
+#define ADIS16260_GPIO_CTRL  0x32 /* Control, digital I/O line */
+#define ADIS16260_MSC_CTRL   0x34 /* Control, data ready, self-test settings */
+#define ADIS16260_SMPL_PRD   0x36 /* Control, internal sample rate */
+#define ADIS16260_SENS_AVG   0x38 /* Control, dynamic range, filtering */
+#define ADIS16260_SLP_CNT    0x3A /* Control, sleep mode initiation */
+#define ADIS16260_DIAG_STAT  0x3C /* Diagnostic, error flags */
+#define ADIS16260_GLOB_CMD   0x3E /* Control, global commands */
+#define ADIS16260_LOT_ID1    0x52 /* Lot Identification Code 1 */
+#define ADIS16260_LOT_ID2    0x54 /* Lot Identification Code 2 */
+#define ADIS16260_PROD_ID    0x56 /* Product identifier;
+				   * convert to decimal = 16,265/16,260 */
+#define ADIS16260_SERIAL_NUM 0x58 /* Serial number */
+
+#define ADIS16260_ERROR_ACTIVE			(1<<14)
+#define ADIS16260_NEW_DATA			(1<<15)
+
+/* MSC_CTRL */
+#define ADIS16260_MSC_CTRL_MEM_TEST		(1<<11)
+/* Internal self-test enable */
+#define ADIS16260_MSC_CTRL_INT_SELF_TEST	(1<<10)
+#define ADIS16260_MSC_CTRL_NEG_SELF_TEST	(1<<9)
+#define ADIS16260_MSC_CTRL_POS_SELF_TEST	(1<<8)
+#define ADIS16260_MSC_CTRL_DATA_RDY_EN		(1<<2)
+#define ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH	(1<<1)
+#define ADIS16260_MSC_CTRL_DATA_RDY_DIO2	(1<<0)
+
+/* SMPL_PRD */
+/* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */
+#define ADIS16260_SMPL_PRD_TIME_BASE	(1<<7)
+#define ADIS16260_SMPL_PRD_DIV_MASK	0x7F
+
+/* SLP_CNT */
+#define ADIS16260_SLP_CNT_POWER_OFF     0x80
+
+/* DIAG_STAT */
+#define ADIS16260_DIAG_STAT_ALARM2	(1<<9)
+#define ADIS16260_DIAG_STAT_ALARM1	(1<<8)
+#define ADIS16260_DIAG_STAT_FLASH_CHK_BIT	6
+#define ADIS16260_DIAG_STAT_SELF_TEST_BIT	5
+#define ADIS16260_DIAG_STAT_OVERFLOW_BIT	4
+#define ADIS16260_DIAG_STAT_SPI_FAIL_BIT	3
+#define ADIS16260_DIAG_STAT_FLASH_UPT_BIT	2
+#define ADIS16260_DIAG_STAT_POWER_HIGH_BIT	1
+#define ADIS16260_DIAG_STAT_POWER_LOW_BIT	0
+
+/* GLOB_CMD */
+#define ADIS16260_GLOB_CMD_SW_RESET	(1<<7)
+#define ADIS16260_GLOB_CMD_FLASH_UPD	(1<<3)
+#define ADIS16260_GLOB_CMD_DAC_LATCH	(1<<2)
+#define ADIS16260_GLOB_CMD_FAC_CALIB	(1<<1)
+#define ADIS16260_GLOB_CMD_AUTO_NULL	(1<<0)
+
+#define ADIS16260_SPI_SLOW	(u32)(300 * 1000)
+#define ADIS16260_SPI_BURST	(u32)(1000 * 1000)
+#define ADIS16260_SPI_FAST	(u32)(2000 * 1000)
+
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
 
 
-#include "adis16260.h"
-
-static ssize_t adis16260_read_frequency_available(struct device *dev,
-						  struct device_attribute *attr,
-						  char *buf)
-{
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct adis16260_state *st = iio_priv(indio_dev);
-	if (spi_get_device_id(st->adis.spi)->driver_data)
-		return sprintf(buf, "%s\n", "0.129 ~ 256");
-	else
-		return sprintf(buf, "%s\n", "256 2048");
-}
+#define ADIS16260_SCAN_GYRO	0
+#define ADIS16260_SCAN_SUPPLY	1
+#define ADIS16260_SCAN_AUX_ADC	2
+#define ADIS16260_SCAN_TEMP	3
+#define ADIS16260_SCAN_ANGL	4
 
 
 static ssize_t adis16260_read_frequency(struct device *dev,
 static ssize_t adis16260_read_frequency(struct device *dev,
 		struct device_attribute *attr,
 		struct device_attribute *attr,
 		char *buf)
 		char *buf)
 {
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct adis16260_state *st = iio_priv(indio_dev);
+	struct adis *adis = iio_priv(indio_dev);
 	int ret, len = 0;
 	int ret, len = 0;
 	u16 t;
 	u16 t;
 	int sps;
 	int sps;
-	ret = adis_read_reg_16(&st->adis, ADIS16260_SMPL_PRD, &t);
+	ret = adis_read_reg_16(adis, ADIS16260_SMPL_PRD, &t);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	if (spi_get_device_id(st->adis.spi)->driver_data) /* If an adis16251 */
-		sps =  (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256;
+	if (spi_get_device_id(adis->spi)->driver_data) /* If an adis16251 */
+		sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256;
 	else
 	else
-		sps =  (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048;
+		sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048;
 	sps /= (t & ADIS16260_SMPL_PRD_DIV_MASK) + 1;
 	sps /= (t & ADIS16260_SMPL_PRD_DIV_MASK) + 1;
-	len = sprintf(buf, "%d SPS\n", sps);
+	len = sprintf(buf, "%d\n", sps);
 	return len;
 	return len;
 }
 }
 
 
@@ -64,36 +129,31 @@ static ssize_t adis16260_write_frequency(struct device *dev,
 		size_t len)
 		size_t len)
 {
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct adis16260_state *st = iio_priv(indio_dev);
-	long val;
+	struct adis *adis = iio_priv(indio_dev);
+	unsigned int val;
 	int ret;
 	int ret;
 	u8 t;
 	u8 t;
 
 
-	ret = strict_strtol(buf, 10, &val);
+	ret = kstrtouint(buf, 10, &val);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
-	if (val == 0)
-		return -EINVAL;
 
 
 	mutex_lock(&indio_dev->mlock);
 	mutex_lock(&indio_dev->mlock);
-	if (spi_get_device_id(st->adis.spi)->driver_data) {
-		t = (256 / val);
-		if (t > 0)
-			t--;
-		t &= ADIS16260_SMPL_PRD_DIV_MASK;
-	} else {
-		t = (2048 / val);
-		if (t > 0)
-			t--;
-		t &= ADIS16260_SMPL_PRD_DIV_MASK;
-	}
-	if ((t & ADIS16260_SMPL_PRD_DIV_MASK) >= 0x0A)
-		st->adis.spi->max_speed_hz = ADIS16260_SPI_SLOW;
+	if (spi_get_device_id(adis->spi)->driver_data)
+		t = 256 / val;
+	else
+		t = 2048 / val;
+
+	if (t > ADIS16260_SMPL_PRD_DIV_MASK)
+		t = ADIS16260_SMPL_PRD_DIV_MASK;
+	else if (t > 0)
+		t--;
+
+	if (t >= 0x0A)
+		adis->spi->max_speed_hz = ADIS16260_SPI_SLOW;
 	else
 	else
-		st->adis.spi->max_speed_hz = ADIS16260_SPI_FAST;
-	ret = adis_write_reg_8(&st->adis,
-			ADIS16260_SMPL_PRD,
-			t);
+		adis->spi->max_speed_hz = ADIS16260_SPI_FAST;
+	ret = adis_write_reg_8(adis, ADIS16260_SMPL_PRD, t);
 
 
 	mutex_unlock(&indio_dev->mlock);
 	mutex_unlock(&indio_dev->mlock);
 
 
@@ -103,11 +163,11 @@ static ssize_t adis16260_write_frequency(struct device *dev,
 /* Power down the device */
 /* Power down the device */
 static int adis16260_stop_device(struct iio_dev *indio_dev)
 static int adis16260_stop_device(struct iio_dev *indio_dev)
 {
 {
-	struct adis16260_state *st = iio_priv(indio_dev);
+	struct adis *adis = iio_priv(indio_dev);
 	int ret;
 	int ret;
 	u16 val = ADIS16260_SLP_CNT_POWER_OFF;
 	u16 val = ADIS16260_SLP_CNT_POWER_OFF;
 
 
-	ret = adis_write_reg_16(&st->adis, ADIS16260_SLP_CNT, val);
+	ret = adis_write_reg_16(adis, ADIS16260_SLP_CNT, val);
 	if (ret)
 	if (ret)
 		dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
 		dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
 
 
@@ -118,24 +178,16 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 		adis16260_read_frequency,
 		adis16260_read_frequency,
 		adis16260_write_frequency);
 		adis16260_write_frequency);
 
 
-static IIO_DEVICE_ATTR(sampling_frequency_available,
-		       S_IRUGO, adis16260_read_frequency_available, NULL, 0);
-
-#define ADIS16260_GYRO_CHANNEL_SET(axis, mod)				\
-struct iio_chan_spec adis16260_channels_##axis[] = {		\
-	ADIS_GYRO_CHAN(mod, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, \
-		BIT(IIO_CHAN_INFO_CALIBBIAS) | \
-		BIT(IIO_CHAN_INFO_CALIBSCALE), 14), \
-	ADIS_INCLI_CHAN(mod, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14), \
-	ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12), \
-	ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12), \
-	ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12), \
-	IIO_CHAN_SOFT_TIMESTAMP(5),				\
-}
-
-static const ADIS16260_GYRO_CHANNEL_SET(x, X);
-static const ADIS16260_GYRO_CHANNEL_SET(y, Y);
-static const ADIS16260_GYRO_CHANNEL_SET(z, Z);
+static const struct iio_chan_spec adis16260_channels[] = {
+	ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO,
+		BIT(IIO_CHAN_INFO_CALIBBIAS) |
+		BIT(IIO_CHAN_INFO_CALIBSCALE), 14),
+	ADIS_INCLI_CHAN(X, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14),
+	ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12),
+	ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12),
+	ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12),
+	IIO_CHAN_SOFT_TIMESTAMP(5),
+};
 
 
 static const u8 adis16260_addresses[][2] = {
 static const u8 adis16260_addresses[][2] = {
 	[ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE },
 	[ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE },
@@ -146,9 +198,8 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
 			      int *val, int *val2,
 			      int *val, int *val2,
 			      long mask)
 			      long mask)
 {
 {
-	struct adis16260_state *st = iio_priv(indio_dev);
+	struct adis *adis = iio_priv(indio_dev);
 	int ret;
 	int ret;
-	int bits;
 	u8 addr;
 	u8 addr;
 	s16 val16;
 	s16 val16;
 
 
@@ -160,7 +211,7 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
 		switch (chan->type) {
 		switch (chan->type) {
 		case IIO_ANGL_VEL:
 		case IIO_ANGL_VEL:
 			*val = 0;
 			*val = 0;
-			if (spi_get_device_id(st->adis.spi)->driver_data) {
+			if (spi_get_device_id(adis->spi)->driver_data) {
 				/* 0.01832 degree / sec */
 				/* 0.01832 degree / sec */
 				*val2 = IIO_DEGREE_TO_RAD(18320);
 				*val2 = IIO_DEGREE_TO_RAD(18320);
 			} else {
 			} else {
@@ -168,6 +219,10 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
 				*val2 = IIO_DEGREE_TO_RAD(73260);
 				*val2 = IIO_DEGREE_TO_RAD(73260);
 			}
 			}
 			return IIO_VAL_INT_PLUS_MICRO;
 			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_INCLI:
+			*val = 0;
+			*val2 = IIO_DEGREE_TO_RAD(36630);
+			return IIO_VAL_INT_PLUS_MICRO;
 		case IIO_VOLTAGE:
 		case IIO_VOLTAGE:
 			if (chan->channel == 0) {
 			if (chan->channel == 0) {
 				*val = 1;
 				*val = 1;
@@ -189,42 +244,20 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
 		*val = 250000 / 1453; /* 25 C = 0x00 */
 		*val = 250000 / 1453; /* 25 C = 0x00 */
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBBIAS:
 	case IIO_CHAN_INFO_CALIBBIAS:
-		switch (chan->type) {
-		case IIO_ANGL_VEL:
-			bits = 12;
-			break;
-		default:
-			return -EINVAL;
-		}
-		mutex_lock(&indio_dev->mlock);
 		addr = adis16260_addresses[chan->scan_index][0];
 		addr = adis16260_addresses[chan->scan_index][0];
-		ret = adis_read_reg_16(&st->adis, addr, &val16);
-		if (ret) {
-			mutex_unlock(&indio_dev->mlock);
+		ret = adis_read_reg_16(adis, addr, &val16);
+		if (ret)
 			return ret;
 			return ret;
-		}
-		val16 &= (1 << bits) - 1;
-		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
-		*val = val16;
-		mutex_unlock(&indio_dev->mlock);
+
+		*val = sign_extend32(val16, 11);
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBSCALE:
 	case IIO_CHAN_INFO_CALIBSCALE:
-		switch (chan->type) {
-		case IIO_ANGL_VEL:
-			bits = 12;
-			break;
-		default:
-			return -EINVAL;
-		}
-		mutex_lock(&indio_dev->mlock);
 		addr = adis16260_addresses[chan->scan_index][1];
 		addr = adis16260_addresses[chan->scan_index][1];
-		ret = adis_read_reg_16(&st->adis, addr, &val16);
-		if (ret) {
-			mutex_unlock(&indio_dev->mlock);
+		ret = adis_read_reg_16(adis, addr, &val16);
+		if (ret)
 			return ret;
 			return ret;
-		}
-		*val = (1 << bits) - 1;
-		mutex_unlock(&indio_dev->mlock);
+
+		*val = val16;
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	}
 	}
 	return -EINVAL;
 	return -EINVAL;
@@ -236,26 +269,28 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
 			       int val2,
 			       int val2,
 			       long mask)
 			       long mask)
 {
 {
-	struct adis16260_state *st = iio_priv(indio_dev);
-	int bits = 12;
-	s16 val16;
+	struct adis *adis = iio_priv(indio_dev);
 	u8 addr;
 	u8 addr;
+
 	switch (mask) {
 	switch (mask) {
 	case IIO_CHAN_INFO_CALIBBIAS:
 	case IIO_CHAN_INFO_CALIBBIAS:
-		val16 = val & ((1 << bits) - 1);
+		if (val < -2048 || val >= 2048)
+			return -EINVAL;
+
 		addr = adis16260_addresses[chan->scan_index][0];
 		addr = adis16260_addresses[chan->scan_index][0];
-		return adis_write_reg_16(&st->adis, addr, val16);
+		return adis_write_reg_16(adis, addr, val);
 	case IIO_CHAN_INFO_CALIBSCALE:
 	case IIO_CHAN_INFO_CALIBSCALE:
-		val16 = val & ((1 << bits) - 1);
+		if (val < 0 || val >= 4096)
+			return -EINVAL;
+
 		addr = adis16260_addresses[chan->scan_index][1];
 		addr = adis16260_addresses[chan->scan_index][1];
-		return adis_write_reg_16(&st->adis, addr, val16);
+		return adis_write_reg_16(adis, addr, val);
 	}
 	}
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
 static struct attribute *adis16260_attributes[] = {
 static struct attribute *adis16260_attributes[] = {
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 	NULL
 	NULL
 };
 };
 
 
@@ -303,71 +338,35 @@ static const struct adis_data adis16260_data = {
 
 
 static int adis16260_probe(struct spi_device *spi)
 static int adis16260_probe(struct spi_device *spi)
 {
 {
-	int ret;
-	struct adis16260_platform_data *pd = spi->dev.platform_data;
-	struct adis16260_state *st;
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
+	struct adis *adis;
+	int ret;
 
 
 	/* setup the industrialio driver allocated elements */
 	/* setup the industrialio driver allocated elements */
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	st = iio_priv(indio_dev);
-	if (pd)
-		st->negate = pd->negate;
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis));
+	if (!indio_dev)
+		return -ENOMEM;
+	adis = iio_priv(indio_dev);
 	/* this is only used for removal purposes */
 	/* this is only used for removal purposes */
 	spi_set_drvdata(spi, indio_dev);
 	spi_set_drvdata(spi, indio_dev);
 
 
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->name = spi_get_device_id(spi)->name;
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->dev.parent = &spi->dev;
 	indio_dev->info = &adis16260_info;
 	indio_dev->info = &adis16260_info;
-	indio_dev->num_channels
-		= ARRAY_SIZE(adis16260_channels_x);
-	if (pd && pd->direction)
-		switch (pd->direction) {
-		case 'x':
-			indio_dev->channels = adis16260_channels_x;
-			break;
-		case 'y':
-			indio_dev->channels = adis16260_channels_y;
-			break;
-		case 'z':
-			indio_dev->channels = adis16260_channels_z;
-			break;
-		default:
-			return -EINVAL;
-		}
-	else
-		indio_dev->channels = adis16260_channels_x;
-	indio_dev->num_channels = ARRAY_SIZE(adis16260_channels_x);
+	indio_dev->channels = adis16260_channels;
+	indio_dev->num_channels = ARRAY_SIZE(adis16260_channels);
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 
-	ret = adis_init(&st->adis, indio_dev, spi, &adis16260_data);
+	ret = adis_init(adis, indio_dev, spi, &adis16260_data);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
-	ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
+	ret = adis_setup_buffer_and_trigger(adis, indio_dev, NULL);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
-
-	if (indio_dev->buffer) {
-		/* Set default scan mode */
-		iio_scan_mask_set(indio_dev, indio_dev->buffer,
-				  ADIS16260_SCAN_SUPPLY);
-		iio_scan_mask_set(indio_dev, indio_dev->buffer,
-				  ADIS16260_SCAN_GYRO);
-		iio_scan_mask_set(indio_dev, indio_dev->buffer,
-				  ADIS16260_SCAN_AUX_ADC);
-		iio_scan_mask_set(indio_dev, indio_dev->buffer,
-				  ADIS16260_SCAN_TEMP);
-		iio_scan_mask_set(indio_dev, indio_dev->buffer,
-				  ADIS16260_SCAN_ANGL);
-	}
+		return ret;
 
 
 	/* Get the device into a sane initial state */
 	/* Get the device into a sane initial state */
-	ret = adis_initial_startup(&st->adis);
+	ret = adis_initial_startup(adis);
 	if (ret)
 	if (ret)
 		goto error_cleanup_buffer_trigger;
 		goto error_cleanup_buffer_trigger;
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
@@ -377,22 +376,18 @@ static int adis16260_probe(struct spi_device *spi)
 	return 0;
 	return 0;
 
 
 error_cleanup_buffer_trigger:
 error_cleanup_buffer_trigger:
-	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
-error_free_dev:
-	iio_device_free(indio_dev);
-error_ret:
+	adis_cleanup_buffer_and_trigger(adis, indio_dev);
 	return ret;
 	return ret;
 }
 }
 
 
 static int adis16260_remove(struct spi_device *spi)
 static int adis16260_remove(struct spi_device *spi)
 {
 {
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = spi_get_drvdata(spi);
-	struct adis16260_state *st = iio_priv(indio_dev);
+	struct adis *adis = iio_priv(indio_dev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	adis16260_stop_device(indio_dev);
 	adis16260_stop_device(indio_dev);
-	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
-	iio_device_free(indio_dev);
+	adis_cleanup_buffer_and_trigger(adis, indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 11
drivers/iio/gyro/adxrs450.c

@@ -426,11 +426,9 @@ static int adxrs450_probe(struct spi_device *spi)
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 
 
 	/* setup the industrialio driver allocated elements */
 	/* setup the industrialio driver allocated elements */
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 	st->us = spi;
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	mutex_init(&st->buf_lock);
@@ -447,7 +445,7 @@ static int adxrs450_probe(struct spi_device *spi)
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
 	/* Get the device into a sane initial state */
 	/* Get the device into a sane initial state */
 	ret = adxrs450_initial_setup(indio_dev);
 	ret = adxrs450_initial_setup(indio_dev);
@@ -456,17 +454,12 @@ static int adxrs450_probe(struct spi_device *spi)
 	return 0;
 	return 0;
 error_initial:
 error_initial:
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
-error_free_dev:
-	iio_device_free(indio_dev);
-
-error_ret:
 	return ret;
 	return ret;
 }
 }
 
 
 static int adxrs450_remove(struct spi_device *spi)
 static int adxrs450_remove(struct spi_device *spi)
 {
 {
 	iio_device_unregister(spi_get_drvdata(spi));
 	iio_device_unregister(spi_get_drvdata(spi));
-	iio_device_free(spi_get_drvdata(spi));
 
 
 	return 0;
 	return 0;
 }
 }

+ 16 - 25
drivers/iio/gyro/hid-sensor-gyro-3d.c

@@ -30,10 +30,6 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/triggered_buffer.h>
 #include "../common/hid-sensors/hid-sensor-trigger.h"
 #include "../common/hid-sensors/hid-sensor-trigger.h"
 
 
-/*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Gyro-3D: 0x200076*/
-#define DRIVER_NAME "HID-SENSOR-200076"
-
 enum gyro_3d_channel {
 enum gyro_3d_channel {
 	CHANNEL_SCAN_INDEX_X,
 	CHANNEL_SCAN_INDEX_X,
 	CHANNEL_SCAN_INDEX_Y,
 	CHANNEL_SCAN_INDEX_Y,
@@ -179,18 +175,10 @@ static int gyro_3d_write_raw(struct iio_dev *indio_dev,
 	return ret;
 	return ret;
 }
 }
 
 
-static int gyro_3d_write_raw_get_fmt(struct iio_dev *indio_dev,
-			       struct iio_chan_spec const *chan,
-			       long mask)
-{
-	return IIO_VAL_INT_PLUS_MICRO;
-}
-
 static const struct iio_info gyro_3d_info = {
 static const struct iio_info gyro_3d_info = {
 	.driver_module = THIS_MODULE,
 	.driver_module = THIS_MODULE,
 	.read_raw = &gyro_3d_read_raw,
 	.read_raw = &gyro_3d_read_raw,
 	.write_raw = &gyro_3d_write_raw,
 	.write_raw = &gyro_3d_write_raw,
-	.write_raw_get_fmt = &gyro_3d_write_raw_get_fmt,
 };
 };
 
 
 /* Function to push data to buffer */
 /* Function to push data to buffer */
@@ -286,11 +274,9 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 	struct iio_chan_spec *channels;
 	struct iio_chan_spec *channels;
 
 
-	indio_dev = iio_device_alloc(sizeof(struct gyro_3d_state));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*gyro_state));
+	if (!indio_dev)
+		return -ENOMEM;
 	platform_set_drvdata(pdev, indio_dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 
 	gyro_state = iio_priv(indio_dev);
 	gyro_state = iio_priv(indio_dev);
@@ -302,15 +288,14 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
 						&gyro_state->common_attributes);
 						&gyro_state->common_attributes);
 	if (ret) {
 	if (ret) {
 		dev_err(&pdev->dev, "failed to setup common attributes\n");
 		dev_err(&pdev->dev, "failed to setup common attributes\n");
-		goto error_free_dev;
+		return ret;
 	}
 	}
 
 
 	channels = kmemdup(gyro_3d_channels, sizeof(gyro_3d_channels),
 	channels = kmemdup(gyro_3d_channels, sizeof(gyro_3d_channels),
 			   GFP_KERNEL);
 			   GFP_KERNEL);
 	if (!channels) {
 	if (!channels) {
-		ret = -ENOMEM;
 		dev_err(&pdev->dev, "failed to duplicate channels\n");
 		dev_err(&pdev->dev, "failed to duplicate channels\n");
-		goto error_free_dev;
+		return -ENOMEM;
 	}
 	}
 
 
 	ret = gyro_3d_parse_report(pdev, hsdev, channels,
 	ret = gyro_3d_parse_report(pdev, hsdev, channels,
@@ -367,9 +352,6 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 error_free_dev_mem:
 error_free_dev_mem:
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-error_free_dev:
-	iio_device_free(indio_dev);
-error_ret:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -384,14 +366,23 @@ static int hid_gyro_3d_remove(struct platform_device *pdev)
 	hid_sensor_remove_trigger(indio_dev);
 	hid_sensor_remove_trigger(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+static struct platform_device_id hid_gyro_3d_ids[] = {
+	{
+		/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+		.name = "HID-SENSOR-200076",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_gyro_3d_ids);
+
 static struct platform_driver hid_gyro_3d_platform_driver = {
 static struct platform_driver hid_gyro_3d_platform_driver = {
+	.id_table = hid_gyro_3d_ids,
 	.driver = {
 	.driver = {
-		.name	= DRIVER_NAME,
+		.name	= KBUILD_MODNAME,
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= hid_gyro_3d_probe,
 	.probe		= hid_gyro_3d_probe,

+ 4 - 11
drivers/iio/gyro/itg3200_core.c

@@ -309,11 +309,9 @@ static int itg3200_probe(struct i2c_client *client,
 
 
 	dev_dbg(&client->dev, "probe I2C dev with IRQ %i", client->irq);
 	dev_dbg(&client->dev, "probe I2C dev with IRQ %i", client->irq);
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		ret =  -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
 
 
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 
 
@@ -330,7 +328,7 @@ static int itg3200_probe(struct i2c_client *client,
 
 
 	ret = itg3200_buffer_configure(indio_dev);
 	ret = itg3200_buffer_configure(indio_dev);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
 	if (client->irq) {
 	if (client->irq) {
 		ret = itg3200_probe_trigger(indio_dev);
 		ret = itg3200_probe_trigger(indio_dev);
@@ -353,9 +351,6 @@ static int itg3200_probe(struct i2c_client *client,
 		itg3200_remove_trigger(indio_dev);
 		itg3200_remove_trigger(indio_dev);
 error_unconfigure_buffer:
 error_unconfigure_buffer:
 	itg3200_buffer_unconfigure(indio_dev);
 	itg3200_buffer_unconfigure(indio_dev);
-error_free_dev:
-	iio_device_free(indio_dev);
-error_ret:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -370,8 +365,6 @@ static int itg3200_remove(struct i2c_client *client)
 
 
 	itg3200_buffer_unconfigure(indio_dev);
 	itg3200_buffer_unconfigure(indio_dev);
 
 
-	iio_device_free(indio_dev);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 10 - 1
drivers/iio/gyro/st_gyro.h

@@ -23,7 +23,16 @@
 #define L3G4IS_GYRO_DEV_NAME		"l3g4is_ui"
 #define L3G4IS_GYRO_DEV_NAME		"l3g4is_ui"
 #define LSM330_GYRO_DEV_NAME		"lsm330_gyro"
 #define LSM330_GYRO_DEV_NAME		"lsm330_gyro"
 
 
-int st_gyro_common_probe(struct iio_dev *indio_dev);
+/**
+ * struct st_sensors_platform_data - gyro platform data
+ * @drdy_int_pin: DRDY on gyros is available only on INT2 pin.
+ */
+static const struct st_sensors_platform_data gyro_pdata = {
+	.drdy_int_pin = 2,
+};
+
+int st_gyro_common_probe(struct iio_dev *indio_dev,
+					struct st_sensors_platform_data *pdata);
 void st_gyro_common_remove(struct iio_dev *indio_dev);
 void st_gyro_common_remove(struct iio_dev *indio_dev);
 
 
 #ifdef CONFIG_IIO_BUFFER
 #ifdef CONFIG_IIO_BUFFER

+ 7 - 7
drivers/iio/gyro/st_gyro_core.c

@@ -60,7 +60,7 @@
 #define ST_GYRO_1_BDU_ADDR			0x23
 #define ST_GYRO_1_BDU_ADDR			0x23
 #define ST_GYRO_1_BDU_MASK			0x80
 #define ST_GYRO_1_BDU_MASK			0x80
 #define ST_GYRO_1_DRDY_IRQ_ADDR			0x22
 #define ST_GYRO_1_DRDY_IRQ_ADDR			0x22
-#define ST_GYRO_1_DRDY_IRQ_MASK			0x08
+#define ST_GYRO_1_DRDY_IRQ_INT2_MASK		0x08
 #define ST_GYRO_1_MULTIREAD_BIT			true
 #define ST_GYRO_1_MULTIREAD_BIT			true
 
 
 /* CUSTOM VALUES FOR SENSOR 2 */
 /* CUSTOM VALUES FOR SENSOR 2 */
@@ -84,7 +84,7 @@
 #define ST_GYRO_2_BDU_ADDR			0x23
 #define ST_GYRO_2_BDU_ADDR			0x23
 #define ST_GYRO_2_BDU_MASK			0x80
 #define ST_GYRO_2_BDU_MASK			0x80
 #define ST_GYRO_2_DRDY_IRQ_ADDR			0x22
 #define ST_GYRO_2_DRDY_IRQ_ADDR			0x22
-#define ST_GYRO_2_DRDY_IRQ_MASK			0x08
+#define ST_GYRO_2_DRDY_IRQ_INT2_MASK		0x08
 #define ST_GYRO_2_MULTIREAD_BIT			true
 #define ST_GYRO_2_MULTIREAD_BIT			true
 
 
 static const struct iio_chan_spec st_gyro_16bit_channels[] = {
 static const struct iio_chan_spec st_gyro_16bit_channels[] = {
@@ -158,7 +158,7 @@ static const struct st_sensors st_gyro_sensors[] = {
 		},
 		},
 		.drdy_irq = {
 		.drdy_irq = {
 			.addr = ST_GYRO_1_DRDY_IRQ_ADDR,
 			.addr = ST_GYRO_1_DRDY_IRQ_ADDR,
-			.mask = ST_GYRO_1_DRDY_IRQ_MASK,
+			.mask_int2 = ST_GYRO_1_DRDY_IRQ_INT2_MASK,
 		},
 		},
 		.multi_read_bit = ST_GYRO_1_MULTIREAD_BIT,
 		.multi_read_bit = ST_GYRO_1_MULTIREAD_BIT,
 		.bootime = 2,
 		.bootime = 2,
@@ -221,7 +221,7 @@ static const struct st_sensors st_gyro_sensors[] = {
 		},
 		},
 		.drdy_irq = {
 		.drdy_irq = {
 			.addr = ST_GYRO_2_DRDY_IRQ_ADDR,
 			.addr = ST_GYRO_2_DRDY_IRQ_ADDR,
-			.mask = ST_GYRO_2_DRDY_IRQ_MASK,
+			.mask_int2 = ST_GYRO_2_DRDY_IRQ_INT2_MASK,
 		},
 		},
 		.multi_read_bit = ST_GYRO_2_MULTIREAD_BIT,
 		.multi_read_bit = ST_GYRO_2_MULTIREAD_BIT,
 		.bootime = 2,
 		.bootime = 2,
@@ -302,7 +302,8 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = {
 #define ST_GYRO_TRIGGER_OPS NULL
 #define ST_GYRO_TRIGGER_OPS NULL
 #endif
 #endif
 
 
-int st_gyro_common_probe(struct iio_dev *indio_dev)
+int st_gyro_common_probe(struct iio_dev *indio_dev,
+					struct st_sensors_platform_data *pdata)
 {
 {
 	int err;
 	int err;
 	struct st_sensor_data *gdata = iio_priv(indio_dev);
 	struct st_sensor_data *gdata = iio_priv(indio_dev);
@@ -324,7 +325,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev)
 						&gdata->sensor->fs.fs_avl[0];
 						&gdata->sensor->fs.fs_avl[0];
 	gdata->odr = gdata->sensor->odr.odr_avl[0].hz;
 	gdata->odr = gdata->sensor->odr.odr_avl[0].hz;
 
 
-	err = st_sensors_init_sensor(indio_dev);
+	err = st_sensors_init_sensor(indio_dev, pdata);
 	if (err < 0)
 	if (err < 0)
 		goto st_gyro_common_probe_error;
 		goto st_gyro_common_probe_error;
 
 
@@ -365,7 +366,6 @@ void st_gyro_common_remove(struct iio_dev *indio_dev)
 		st_sensors_deallocate_trigger(indio_dev);
 		st_sensors_deallocate_trigger(indio_dev);
 		st_gyro_deallocate_ring(indio_dev);
 		st_gyro_deallocate_ring(indio_dev);
 	}
 	}
-	iio_device_free(indio_dev);
 }
 }
 EXPORT_SYMBOL(st_gyro_common_remove);
 EXPORT_SYMBOL(st_gyro_common_remove);
 
 

+ 6 - 12
drivers/iio/gyro/st_gyro_i2c.c

@@ -25,27 +25,21 @@ static int st_gyro_i2c_probe(struct i2c_client *client,
 	struct st_sensor_data *gdata;
 	struct st_sensor_data *gdata;
 	int err;
 	int err;
 
 
-	indio_dev = iio_device_alloc(sizeof(*gdata));
-	if (indio_dev == NULL) {
-		err = -ENOMEM;
-		goto iio_device_alloc_error;
-	}
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*gdata));
+	if (!indio_dev)
+		return -ENOMEM;
 
 
 	gdata = iio_priv(indio_dev);
 	gdata = iio_priv(indio_dev);
 	gdata->dev = &client->dev;
 	gdata->dev = &client->dev;
 
 
 	st_sensors_i2c_configure(indio_dev, client, gdata);
 	st_sensors_i2c_configure(indio_dev, client, gdata);
 
 
-	err = st_gyro_common_probe(indio_dev);
+	err = st_gyro_common_probe(indio_dev,
+				(struct st_sensors_platform_data *)&gyro_pdata);
 	if (err < 0)
 	if (err < 0)
-		goto st_gyro_common_probe_error;
+		return err;
 
 
 	return 0;
 	return 0;
-
-st_gyro_common_probe_error:
-	iio_device_free(indio_dev);
-iio_device_alloc_error:
-	return err;
 }
 }
 
 
 static int st_gyro_i2c_remove(struct i2c_client *client)
 static int st_gyro_i2c_remove(struct i2c_client *client)

+ 6 - 12
drivers/iio/gyro/st_gyro_spi.c

@@ -24,27 +24,21 @@ static int st_gyro_spi_probe(struct spi_device *spi)
 	struct st_sensor_data *gdata;
 	struct st_sensor_data *gdata;
 	int err;
 	int err;
 
 
-	indio_dev = iio_device_alloc(sizeof(*gdata));
-	if (indio_dev == NULL) {
-		err = -ENOMEM;
-		goto iio_device_alloc_error;
-	}
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*gdata));
+	if (!indio_dev)
+		return -ENOMEM;
 
 
 	gdata = iio_priv(indio_dev);
 	gdata = iio_priv(indio_dev);
 	gdata->dev = &spi->dev;
 	gdata->dev = &spi->dev;
 
 
 	st_sensors_spi_configure(indio_dev, spi, gdata);
 	st_sensors_spi_configure(indio_dev, spi, gdata);
 
 
-	err = st_gyro_common_probe(indio_dev);
+	err = st_gyro_common_probe(indio_dev,
+				(struct st_sensors_platform_data *)&gyro_pdata);
 	if (err < 0)
 	if (err < 0)
-		goto st_gyro_common_probe_error;
+		return err;
 
 
 	return 0;
 	return 0;
-
-st_gyro_common_probe_error:
-	iio_device_free(indio_dev);
-iio_device_alloc_error:
-	return err;
 }
 }
 
 
 static int st_gyro_spi_remove(struct spi_device *spi)
 static int st_gyro_spi_remove(struct spi_device *spi)

+ 2 - 5
drivers/iio/iio_core_trigger.h

@@ -30,7 +30,7 @@ void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev);
 static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
 static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
 {
 {
 	return 0;
 	return 0;
-};
+}
 
 
 /**
 /**
  * iio_device_unregister_trigger_consumer() - reverse the registration process
  * iio_device_unregister_trigger_consumer() - reverse the registration process
@@ -38,9 +38,6 @@ static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
  **/
  **/
 static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev)
 static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev)
 {
 {
-};
+}
 
 
 #endif /* CONFIG_TRIGGER_CONSUMER */
 #endif /* CONFIG_TRIGGER_CONSUMER */
-
-
-

+ 2 - 0
drivers/iio/imu/Kconfig

@@ -1,6 +1,8 @@
 #
 #
 # IIO imu drivers configuration
 # IIO imu drivers configuration
 #
 #
+# When adding new entries keep the list in alphabetical order
+
 menu "Inertial measurement units"
 menu "Inertial measurement units"
 
 
 config ADIS16400
 config ADIS16400

+ 1 - 0
drivers/iio/imu/Makefile

@@ -2,6 +2,7 @@
 # Makefile for Inertial Measurement Units
 # Makefile for Inertial Measurement Units
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
 adis16400-y             := adis16400_core.o
 adis16400-y             := adis16400_core.o
 adis16400-$(CONFIG_IIO_BUFFER) += adis16400_buffer.o
 adis16400-$(CONFIG_IIO_BUFFER) += adis16400_buffer.o
 obj-$(CONFIG_ADIS16400) += adis16400.o
 obj-$(CONFIG_ADIS16400) += adis16400.o

+ 3 - 7
drivers/iio/imu/adis16400_core.c

@@ -871,7 +871,7 @@ static int adis16400_probe(struct spi_device *spi)
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -893,12 +893,12 @@ static int adis16400_probe(struct spi_device *spi)
 
 
 	ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
 	ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
 	ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev,
 	ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev,
 			adis16400_trigger_handler);
 			adis16400_trigger_handler);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
 	/* Get the device into a sane initial state */
 	/* Get the device into a sane initial state */
 	ret = adis16400_initial_setup(indio_dev);
 	ret = adis16400_initial_setup(indio_dev);
@@ -913,8 +913,6 @@ static int adis16400_probe(struct spi_device *spi)
 
 
 error_cleanup_buffer:
 error_cleanup_buffer:
 	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
-error_free_dev:
-	iio_device_free(indio_dev);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -928,8 +926,6 @@ static int adis16400_remove(struct spi_device *spi)
 
 
 	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 
 
-	iio_device_free(indio_dev);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 3 - 7
drivers/iio/imu/adis16480.c

@@ -839,7 +839,7 @@ static int adis16480_probe(struct spi_device *spi)
 	struct adis16480 *st;
 	struct adis16480 *st;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*st));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 	if (indio_dev == NULL)
 	if (indio_dev == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -857,11 +857,11 @@ static int adis16480_probe(struct spi_device *spi)
 
 
 	ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data);
 	ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
 	ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
 	ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
 	if (ret)
 	if (ret)
-		goto error_free_dev;
+		return ret;
 
 
 	ret = adis16480_initial_setup(indio_dev);
 	ret = adis16480_initial_setup(indio_dev);
 	if (ret)
 	if (ret)
@@ -879,8 +879,6 @@ static int adis16480_probe(struct spi_device *spi)
 	adis16480_stop_device(indio_dev);
 	adis16480_stop_device(indio_dev);
 error_cleanup_buffer:
 error_cleanup_buffer:
 	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
-error_free_dev:
-	iio_device_free(indio_dev);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -894,8 +892,6 @@ static int adis16480_remove(struct spi_device *spi)
 
 
 	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 	adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
 
 
-	iio_device_free(indio_dev);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 11 - 18
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c

@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/kfifo.h>
 #include <linux/kfifo.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
+#include <linux/iio/iio.h>
 #include "inv_mpu_iio.h"
 #include "inv_mpu_iio.h"
 
 
 /*
 /*
@@ -663,16 +664,13 @@ static int inv_mpu_probe(struct i2c_client *client,
 	int result;
 	int result;
 
 
 	if (!i2c_check_functionality(client->adapter,
 	if (!i2c_check_functionality(client->adapter,
-					I2C_FUNC_SMBUS_READ_I2C_BLOCK |
-					I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
-		result = -ENOSYS;
-		goto out_no_free;
-	}
-	indio_dev = iio_device_alloc(sizeof(*st));
-	if (indio_dev == NULL) {
-		result =  -ENOMEM;
-		goto out_no_free;
-	}
+		I2C_FUNC_SMBUS_I2C_BLOCK))
+		return -ENOSYS;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
+
 	st = iio_priv(indio_dev);
 	st = iio_priv(indio_dev);
 	st->client = client;
 	st->client = client;
 	st->plat_data = *(struct inv_mpu6050_platform_data
 	st->plat_data = *(struct inv_mpu6050_platform_data
@@ -680,13 +678,13 @@ static int inv_mpu_probe(struct i2c_client *client,
 	/* power is turned on inside check chip type*/
 	/* power is turned on inside check chip type*/
 	result = inv_check_and_setup_chip(st, id);
 	result = inv_check_and_setup_chip(st, id);
 	if (result)
 	if (result)
-		goto out_free;
+		return result;
 
 
 	result = inv_mpu6050_init_config(indio_dev);
 	result = inv_mpu6050_init_config(indio_dev);
 	if (result) {
 	if (result) {
 		dev_err(&client->dev,
 		dev_err(&client->dev,
 			"Could not initialize device.\n");
 			"Could not initialize device.\n");
-		goto out_free;
+		return result;
 	}
 	}
 
 
 	i2c_set_clientdata(client, indio_dev);
 	i2c_set_clientdata(client, indio_dev);
@@ -705,7 +703,7 @@ static int inv_mpu_probe(struct i2c_client *client,
 	if (result) {
 	if (result) {
 		dev_err(&st->client->dev, "configure buffer fail %d\n",
 		dev_err(&st->client->dev, "configure buffer fail %d\n",
 				result);
 				result);
-		goto out_free;
+		return result;
 	}
 	}
 	result = inv_mpu6050_probe_trigger(indio_dev);
 	result = inv_mpu6050_probe_trigger(indio_dev);
 	if (result) {
 	if (result) {
@@ -727,10 +725,6 @@ static int inv_mpu_probe(struct i2c_client *client,
 	inv_mpu6050_remove_trigger(st);
 	inv_mpu6050_remove_trigger(st);
 out_unreg_ring:
 out_unreg_ring:
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
-out_free:
-	iio_device_free(indio_dev);
-out_no_free:
-
 	return result;
 	return result;
 }
 }
 
 
@@ -742,7 +736,6 @@ static int inv_mpu_remove(struct i2c_client *client)
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	inv_mpu6050_remove_trigger(st);
 	inv_mpu6050_remove_trigger(st);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 49 - 2
drivers/iio/industrialio-core.c

@@ -383,14 +383,14 @@ static ssize_t iio_read_channel_info(struct device *dev,
 		scale_db = true;
 		scale_db = true;
 	case IIO_VAL_INT_PLUS_MICRO:
 	case IIO_VAL_INT_PLUS_MICRO:
 		if (val2 < 0)
 		if (val2 < 0)
-			return sprintf(buf, "-%d.%06u%s\n", val, -val2,
+			return sprintf(buf, "-%ld.%06u%s\n", abs(val), -val2,
 				scale_db ? " dB" : "");
 				scale_db ? " dB" : "");
 		else
 		else
 			return sprintf(buf, "%d.%06u%s\n", val, val2,
 			return sprintf(buf, "%d.%06u%s\n", val, val2,
 				scale_db ? " dB" : "");
 				scale_db ? " dB" : "");
 	case IIO_VAL_INT_PLUS_NANO:
 	case IIO_VAL_INT_PLUS_NANO:
 		if (val2 < 0)
 		if (val2 < 0)
-			return sprintf(buf, "-%d.%09u\n", val, -val2);
+			return sprintf(buf, "-%ld.%09u\n", abs(val), -val2);
 		else
 		else
 			return sprintf(buf, "%d.%09u\n", val, val2);
 			return sprintf(buf, "%d.%09u\n", val, val2);
 	case IIO_VAL_FRACTIONAL:
 	case IIO_VAL_FRACTIONAL:
@@ -912,6 +912,53 @@ void iio_device_free(struct iio_dev *dev)
 }
 }
 EXPORT_SYMBOL(iio_device_free);
 EXPORT_SYMBOL(iio_device_free);
 
 
+static void devm_iio_device_release(struct device *dev, void *res)
+{
+	iio_device_free(*(struct iio_dev **)res);
+}
+
+static int devm_iio_device_match(struct device *dev, void *res, void *data)
+{
+	struct iio_dev **r = res;
+	if (!r || !*r) {
+		WARN_ON(!r || !*r);
+		return 0;
+	}
+	return *r == data;
+}
+
+struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
+{
+	struct iio_dev **ptr, *iio_dev;
+
+	ptr = devres_alloc(devm_iio_device_release, sizeof(*ptr),
+			   GFP_KERNEL);
+	if (!ptr)
+		return NULL;
+
+	/* use raw alloc_dr for kmalloc caller tracing */
+	iio_dev = iio_device_alloc(sizeof_priv);
+	if (iio_dev) {
+		*ptr = iio_dev;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return iio_dev;
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_alloc);
+
+void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev)
+{
+	int rc;
+
+	rc = devres_release(dev, devm_iio_device_release,
+			    devm_iio_device_match, iio_dev);
+	WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_iio_device_free);
+
 /**
 /**
  * iio_chrdev_open() - chrdev file open for buffer access and ioctls
  * iio_chrdev_open() - chrdev file open for buffer access and ioctls
  **/
  **/

+ 68 - 4
drivers/iio/industrialio-trigger.c

@@ -424,9 +424,8 @@ static void iio_trig_subirqunmask(struct irq_data *d)
 	trig->subirqs[d->irq - trig->subirq_base].enabled = true;
 	trig->subirqs[d->irq - trig->subirq_base].enabled = true;
 }
 }
 
 
-struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
+static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs)
 {
 {
-	va_list vargs;
 	struct iio_trigger *trig;
 	struct iio_trigger *trig;
 	trig = kzalloc(sizeof *trig, GFP_KERNEL);
 	trig = kzalloc(sizeof *trig, GFP_KERNEL);
 	if (trig) {
 	if (trig) {
@@ -444,9 +443,8 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
 			kfree(trig);
 			kfree(trig);
 			return NULL;
 			return NULL;
 		}
 		}
-		va_start(vargs, fmt);
+
 		trig->name = kvasprintf(GFP_KERNEL, fmt, vargs);
 		trig->name = kvasprintf(GFP_KERNEL, fmt, vargs);
-		va_end(vargs);
 		if (trig->name == NULL) {
 		if (trig->name == NULL) {
 			irq_free_descs(trig->subirq_base,
 			irq_free_descs(trig->subirq_base,
 				       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
 				       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
@@ -467,6 +465,19 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
 		}
 		}
 		get_device(&trig->dev);
 		get_device(&trig->dev);
 	}
 	}
+
+	return trig;
+}
+
+struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
+{
+	struct iio_trigger *trig;
+	va_list vargs;
+
+	va_start(vargs, fmt);
+	trig = viio_trigger_alloc(fmt, vargs);
+	va_end(vargs);
+
 	return trig;
 	return trig;
 }
 }
 EXPORT_SYMBOL(iio_trigger_alloc);
 EXPORT_SYMBOL(iio_trigger_alloc);
@@ -478,6 +489,59 @@ void iio_trigger_free(struct iio_trigger *trig)
 }
 }
 EXPORT_SYMBOL(iio_trigger_free);
 EXPORT_SYMBOL(iio_trigger_free);
 
 
+static void devm_iio_trigger_release(struct device *dev, void *res)
+{
+	iio_trigger_free(*(struct iio_trigger **)res);
+}
+
+static int devm_iio_trigger_match(struct device *dev, void *res, void *data)
+{
+	struct iio_trigger **r = res;
+
+	if (!r || !*r) {
+		WARN_ON(!r || !*r);
+		return 0;
+	}
+
+	return *r == data;
+}
+
+struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
+						const char *fmt, ...)
+{
+	struct iio_trigger **ptr, *trig;
+	va_list vargs;
+
+	ptr = devres_alloc(devm_iio_trigger_release, sizeof(*ptr),
+			   GFP_KERNEL);
+	if (!ptr)
+		return NULL;
+
+	/* use raw alloc_dr for kmalloc caller tracing */
+	va_start(vargs, fmt);
+	trig = viio_trigger_alloc(fmt, vargs);
+	va_end(vargs);
+	if (trig) {
+		*ptr = trig;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return trig;
+}
+EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc);
+
+void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig)
+{
+	int rc;
+
+	rc = devres_release(dev, devm_iio_trigger_release,
+			    devm_iio_trigger_match, iio_trig);
+	WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_iio_trigger_free);
+
 void iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
 void iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
 {
 {
 	indio_dev->groups[indio_dev->groupcounter++] =
 	indio_dev->groups[indio_dev->groupcounter++] =

+ 23 - 11
drivers/iio/light/Kconfig

@@ -1,6 +1,8 @@
 #
 #
 # Light sensors
 # Light sensors
 #
 #
+# When adding new entries keep the list in alphabetical order
+
 menu "Light sensors"
 menu "Light sensors"
 
 
 config ADJD_S311
 config ADJD_S311
@@ -15,6 +17,27 @@ config ADJD_S311
 	 This driver can also be built as a module.  If so, the module
 	 This driver can also be built as a module.  If so, the module
 	 will be called adjd_s311.
 	 will be called adjd_s311.
 
 
+config APDS9300
+	tristate "APDS9300 ambient light sensor"
+	depends on I2C
+	help
+	 Say Y here if you want to build a driver for the Avago APDS9300
+	 ambient light sensor.
+
+	 To compile this driver as a module, choose M here: the
+	 module will be called apds9300.
+
+config HID_SENSOR_ALS
+	depends on HID_SENSOR_HUB
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	select HID_SENSOR_IIO_COMMON
+	select HID_SENSOR_IIO_TRIGGER
+	tristate "HID ALS"
+	help
+	  Say yes here to build support for the HID SENSOR
+	  Ambient light sensor.
+
 config SENSORS_LM3533
 config SENSORS_LM3533
 	tristate "LM3533 ambient light sensor"
 	tristate "LM3533 ambient light sensor"
 	depends on MFD_LM3533
 	depends on MFD_LM3533
@@ -52,15 +75,4 @@ config VCNL4000
 	 To compile this driver as a module, choose M here: the
 	 To compile this driver as a module, choose M here: the
 	 module will be called vcnl4000.
 	 module will be called vcnl4000.
 
 
-config HID_SENSOR_ALS
-	depends on HID_SENSOR_HUB
-	select IIO_BUFFER
-	select IIO_TRIGGERED_BUFFER
-	select HID_SENSOR_IIO_COMMON
-	select HID_SENSOR_IIO_TRIGGER
-	tristate "HID ALS"
-	help
-	  Say yes here to build support for the HID SENSOR
-	  Ambient light sensor.
-
 endmenu
 endmenu

+ 3 - 1
drivers/iio/light/Makefile

@@ -2,8 +2,10 @@
 # Makefile for IIO Light sensors
 # Makefile for IIO Light sensors
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADJD_S311)		+= adjd_s311.o
 obj-$(CONFIG_ADJD_S311)		+= adjd_s311.o
+obj-$(CONFIG_APDS9300)		+= apds9300.o
+obj-$(CONFIG_HID_SENSOR_ALS)	+= hid-sensor-als.o
 obj-$(CONFIG_SENSORS_LM3533)	+= lm3533-als.o
 obj-$(CONFIG_SENSORS_LM3533)	+= lm3533-als.o
 obj-$(CONFIG_SENSORS_TSL2563)	+= tsl2563.o
 obj-$(CONFIG_SENSORS_TSL2563)	+= tsl2563.o
 obj-$(CONFIG_VCNL4000)		+= vcnl4000.o
 obj-$(CONFIG_VCNL4000)		+= vcnl4000.o
-obj-$(CONFIG_HID_SENSOR_ALS)	+= hid-sensor-als.o

+ 15 - 28
drivers/iio/light/adjd_s311.c

@@ -37,22 +37,14 @@
 #define ADJD_S311_CAP_GREEN	0x07
 #define ADJD_S311_CAP_GREEN	0x07
 #define ADJD_S311_CAP_BLUE	0x08
 #define ADJD_S311_CAP_BLUE	0x08
 #define ADJD_S311_CAP_CLEAR	0x09
 #define ADJD_S311_CAP_CLEAR	0x09
-#define ADJD_S311_INT_RED_LO	0x0a
-#define ADJD_S311_INT_RED_HI	0x0b
-#define ADJD_S311_INT_GREEN_LO	0x0c
-#define ADJD_S311_INT_GREEN_HI	0x0d
-#define ADJD_S311_INT_BLUE_LO	0x0e
-#define ADJD_S311_INT_BLUE_HI	0x0f
-#define ADJD_S311_INT_CLEAR_LO	0x10
-#define ADJD_S311_INT_CLEAR_HI	0x11
-#define ADJD_S311_DATA_RED_LO	0x40
-#define ADJD_S311_DATA_RED_HI	0x41
-#define ADJD_S311_DATA_GREEN_LO	0x42
-#define ADJD_S311_DATA_GREEN_HI	0x43
-#define ADJD_S311_DATA_BLUE_LO	0x44
-#define ADJD_S311_DATA_BLUE_HI	0x45
-#define ADJD_S311_DATA_CLEAR_LO	0x46
-#define ADJD_S311_DATA_CLEAR_HI	0x47
+#define ADJD_S311_INT_RED	0x0a
+#define ADJD_S311_INT_GREEN	0x0c
+#define ADJD_S311_INT_BLUE	0x0e
+#define ADJD_S311_INT_CLEAR	0x10
+#define ADJD_S311_DATA_RED	0x40
+#define ADJD_S311_DATA_GREEN	0x42
+#define ADJD_S311_DATA_BLUE	0x44
+#define ADJD_S311_DATA_CLEAR	0x46
 #define ADJD_S311_OFFSET_RED	0x48
 #define ADJD_S311_OFFSET_RED	0x48
 #define ADJD_S311_OFFSET_GREEN	0x49
 #define ADJD_S311_OFFSET_GREEN	0x49
 #define ADJD_S311_OFFSET_BLUE	0x4a
 #define ADJD_S311_OFFSET_BLUE	0x4a
@@ -73,8 +65,8 @@ enum adjd_s311_channel_idx {
 	IDX_RED, IDX_GREEN, IDX_BLUE, IDX_CLEAR
 	IDX_RED, IDX_GREEN, IDX_BLUE, IDX_CLEAR
 };
 };
 
 
-#define ADJD_S311_DATA_REG(chan) (ADJD_S311_DATA_RED_LO + (chan) * 2)
-#define ADJD_S311_INT_REG(chan) (ADJD_S311_INT_RED_LO + (chan) * 2)
+#define ADJD_S311_DATA_REG(chan) (ADJD_S311_DATA_RED + (chan) * 2)
+#define ADJD_S311_INT_REG(chan) (ADJD_S311_INT_RED + (chan) * 2)
 #define ADJD_S311_CAP_REG(chan) (ADJD_S311_CAP_RED + (chan))
 #define ADJD_S311_CAP_REG(chan) (ADJD_S311_CAP_RED + (chan))
 
 
 static int adjd_s311_req_data(struct iio_dev *indio_dev)
 static int adjd_s311_req_data(struct iio_dev *indio_dev)
@@ -294,11 +286,10 @@ static int adjd_s311_probe(struct i2c_client *client,
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int err;
 	int err;
 
 
-	indio_dev = iio_device_alloc(sizeof(*data));
-	if (indio_dev == NULL) {
-		err = -ENOMEM;
-		goto exit;
-	}
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
 	data = iio_priv(indio_dev);
 	data = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
 	i2c_set_clientdata(client, indio_dev);
 	data->client = client;
 	data->client = client;
@@ -313,7 +304,7 @@ static int adjd_s311_probe(struct i2c_client *client,
 	err = iio_triggered_buffer_setup(indio_dev, NULL,
 	err = iio_triggered_buffer_setup(indio_dev, NULL,
 		adjd_s311_trigger_handler, NULL);
 		adjd_s311_trigger_handler, NULL);
 	if (err < 0)
 	if (err < 0)
-		goto exit_free_device;
+		return err;
 
 
 	err = iio_device_register(indio_dev);
 	err = iio_device_register(indio_dev);
 	if (err)
 	if (err)
@@ -325,9 +316,6 @@ static int adjd_s311_probe(struct i2c_client *client,
 
 
 exit_unreg_buffer:
 exit_unreg_buffer:
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
-exit_free_device:
-	iio_device_free(indio_dev);
-exit:
 	return err;
 	return err;
 }
 }
 
 
@@ -339,7 +327,6 @@ static int adjd_s311_remove(struct i2c_client *client)
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	kfree(data->buffer);
 	kfree(data->buffer);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 512 - 0
drivers/iio/light/apds9300.c

@@ -0,0 +1,512 @@
+/*
+ * apds9300.c - IIO driver for Avago APDS9300 ambient light sensor
+ *
+ * Copyright 2013 Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+
+#define APDS9300_DRV_NAME "apds9300"
+#define APDS9300_IRQ_NAME "apds9300_event"
+
+/* Command register bits */
+#define APDS9300_CMD	BIT(7) /* Select command register. Must write as 1 */
+#define APDS9300_WORD	BIT(5) /* I2C write/read: if 1 word, if 0 byte */
+#define APDS9300_CLEAR	BIT(6) /* Interrupt clear. Clears pending interrupt */
+
+/* Register set */
+#define APDS9300_CONTROL	0x00 /* Control of basic functions */
+#define APDS9300_THRESHLOWLOW	0x02 /* Low byte of low interrupt threshold */
+#define APDS9300_THRESHHIGHLOW	0x04 /* Low byte of high interrupt threshold */
+#define APDS9300_INTERRUPT	0x06 /* Interrupt control */
+#define APDS9300_DATA0LOW	0x0c /* Low byte of ADC channel 0 */
+#define APDS9300_DATA1LOW	0x0e /* Low byte of ADC channel 1 */
+
+/* Power on/off value for APDS9300_CONTROL register */
+#define APDS9300_POWER_ON	0x03
+#define APDS9300_POWER_OFF	0x00
+
+/* Interrupts */
+#define APDS9300_INTR_ENABLE	0x10
+/* Interrupt Persist Function: Any value outside of threshold range */
+#define APDS9300_THRESH_INTR	0x01
+
+#define APDS9300_THRESH_MAX	0xffff /* Max threshold value */
+
+struct apds9300_data {
+	struct i2c_client *client;
+	struct mutex mutex;
+	int power_state;
+	int thresh_low;
+	int thresh_hi;
+	int intr_en;
+};
+
+/* Lux calculation */
+
+/* Calculated values 1000 * (CH1/CH0)^1.4 for CH1/CH0 from 0 to 0.52 */
+static const u16 apds9300_lux_ratio[] = {
+	0, 2, 4, 7, 11, 15, 19, 24, 29, 34, 40, 45, 51, 57, 64, 70, 77, 84, 91,
+	98, 105, 112, 120, 128, 136, 144, 152, 160, 168, 177, 185, 194, 203,
+	212, 221, 230, 239, 249, 258, 268, 277, 287, 297, 307, 317, 327, 337,
+	347, 358, 368, 379, 390, 400,
+};
+
+static unsigned long apds9300_calculate_lux(u16 ch0, u16 ch1)
+{
+	unsigned long lux, tmp;
+
+	/* avoid division by zero */
+	if (ch0 == 0)
+		return 0;
+
+	tmp = DIV_ROUND_UP(ch1 * 100, ch0);
+	if (tmp <= 52) {
+		lux = 3150 * ch0 - (unsigned long)DIV_ROUND_UP_ULL(ch0
+				* apds9300_lux_ratio[tmp] * 5930ull, 1000);
+	} else if (tmp <= 65) {
+		lux = 2290 * ch0 - 2910 * ch1;
+	} else if (tmp <= 80) {
+		lux = 1570 * ch0 - 1800 * ch1;
+	} else if (tmp <= 130) {
+		lux = 338 * ch0 - 260 * ch1;
+	} else {
+		lux = 0;
+	}
+
+	return lux / 100000;
+}
+
+static int apds9300_get_adc_val(struct apds9300_data *data, int adc_number)
+{
+	int ret;
+	u8 flags = APDS9300_CMD | APDS9300_WORD;
+
+	if (!data->power_state)
+		return -EBUSY;
+
+	/* Select ADC0 or ADC1 data register */
+	flags |= adc_number ? APDS9300_DATA1LOW : APDS9300_DATA0LOW;
+
+	ret = i2c_smbus_read_word_data(data->client, flags);
+	if (ret < 0)
+		dev_err(&data->client->dev,
+			"failed to read ADC%d value\n", adc_number);
+
+	return ret;
+}
+
+static int apds9300_set_thresh_low(struct apds9300_data *data, int value)
+{
+	int ret;
+
+	if (!data->power_state)
+		return -EBUSY;
+
+	if (value > APDS9300_THRESH_MAX)
+		return -EINVAL;
+
+	ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHLOWLOW
+			| APDS9300_CMD | APDS9300_WORD, value);
+	if (ret) {
+		dev_err(&data->client->dev, "failed to set thresh_low\n");
+		return ret;
+	}
+	data->thresh_low = value;
+
+	return 0;
+}
+
+static int apds9300_set_thresh_hi(struct apds9300_data *data, int value)
+{
+	int ret;
+
+	if (!data->power_state)
+		return -EBUSY;
+
+	if (value > APDS9300_THRESH_MAX)
+		return -EINVAL;
+
+	ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHHIGHLOW
+			| APDS9300_CMD | APDS9300_WORD, value);
+	if (ret) {
+		dev_err(&data->client->dev, "failed to set thresh_hi\n");
+		return ret;
+	}
+	data->thresh_hi = value;
+
+	return 0;
+}
+
+static int apds9300_set_intr_state(struct apds9300_data *data, int state)
+{
+	int ret;
+	u8 cmd;
+
+	if (!data->power_state)
+		return -EBUSY;
+
+	cmd = state ? APDS9300_INTR_ENABLE | APDS9300_THRESH_INTR : 0x00;
+	ret = i2c_smbus_write_byte_data(data->client,
+			APDS9300_INTERRUPT | APDS9300_CMD, cmd);
+	if (ret) {
+		dev_err(&data->client->dev,
+			"failed to set interrupt state %d\n", state);
+		return ret;
+	}
+	data->intr_en = state;
+
+	return 0;
+}
+
+static int apds9300_set_power_state(struct apds9300_data *data, int state)
+{
+	int ret;
+	u8 cmd;
+
+	cmd = state ? APDS9300_POWER_ON : APDS9300_POWER_OFF;
+	ret = i2c_smbus_write_byte_data(data->client,
+			APDS9300_CONTROL | APDS9300_CMD, cmd);
+	if (ret) {
+		dev_err(&data->client->dev,
+			"failed to set power state %d\n", state);
+		return ret;
+	}
+	data->power_state = state;
+
+	return 0;
+}
+
+static void apds9300_clear_intr(struct apds9300_data *data)
+{
+	int ret;
+
+	ret = i2c_smbus_write_byte(data->client, APDS9300_CLEAR | APDS9300_CMD);
+	if (ret < 0)
+		dev_err(&data->client->dev, "failed to clear interrupt\n");
+}
+
+static int apds9300_chip_init(struct apds9300_data *data)
+{
+	int ret;
+
+	/* Need to set power off to ensure that the chip is off */
+	ret = apds9300_set_power_state(data, 0);
+	if (ret < 0)
+		goto err;
+	/*
+	 * Probe the chip. To do so we try to power up the device and then to
+	 * read back the 0x03 code
+	 */
+	ret = apds9300_set_power_state(data, 1);
+	if (ret < 0)
+		goto err;
+	ret = i2c_smbus_read_byte_data(data->client,
+			APDS9300_CONTROL | APDS9300_CMD);
+	if (ret != APDS9300_POWER_ON) {
+		ret = -ENODEV;
+		goto err;
+	}
+	/*
+	 * Disable interrupt to ensure thai it is doesn't enable
+	 * i.e. after device soft reset
+	 */
+	ret = apds9300_set_intr_state(data, 0);
+	if (ret < 0)
+		goto err;
+
+	return 0;
+
+err:
+	dev_err(&data->client->dev, "failed to init the chip\n");
+	return ret;
+}
+
+static int apds9300_read_raw(struct iio_dev *indio_dev,
+		struct iio_chan_spec const *chan, int *val, int *val2,
+		long mask)
+{
+	int ch0, ch1, ret = -EINVAL;
+	struct apds9300_data *data = iio_priv(indio_dev);
+
+	mutex_lock(&data->mutex);
+	switch (chan->type) {
+	case IIO_LIGHT:
+		ch0 = apds9300_get_adc_val(data, 0);
+		if (ch0 < 0) {
+			ret = ch0;
+			break;
+		}
+		ch1 = apds9300_get_adc_val(data, 1);
+		if (ch1 < 0) {
+			ret = ch1;
+			break;
+		}
+		*val = apds9300_calculate_lux(ch0, ch1);
+		ret = IIO_VAL_INT;
+		break;
+	case IIO_INTENSITY:
+		ret = apds9300_get_adc_val(data, chan->channel);
+		if (ret < 0)
+			break;
+		*val = ret;
+		ret = IIO_VAL_INT;
+		break;
+	default:
+		break;
+	}
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static int apds9300_read_thresh(struct iio_dev *indio_dev, u64 event_code,
+		int *val)
+{
+	struct apds9300_data *data = iio_priv(indio_dev);
+
+	switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+	case IIO_EV_DIR_RISING:
+		*val = data->thresh_hi;
+		break;
+	case IIO_EV_DIR_FALLING:
+		*val = data->thresh_low;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int apds9300_write_thresh(struct iio_dev *indio_dev, u64 event_code,
+		int val)
+{
+	struct apds9300_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+		ret = apds9300_set_thresh_hi(data, val);
+	else
+		ret = apds9300_set_thresh_low(data, val);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static int apds9300_read_interrupt_config(struct iio_dev *indio_dev,
+		u64 event_code)
+{
+	struct apds9300_data *data = iio_priv(indio_dev);
+
+	return data->intr_en;
+}
+
+static int apds9300_write_interrupt_config(struct iio_dev *indio_dev,
+		u64 event_code, int state)
+{
+	struct apds9300_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = apds9300_set_intr_state(data, state);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static const struct iio_info apds9300_info_no_irq = {
+	.driver_module	= THIS_MODULE,
+	.read_raw	= apds9300_read_raw,
+};
+
+static const struct iio_info apds9300_info = {
+	.driver_module		= THIS_MODULE,
+	.read_raw		= apds9300_read_raw,
+	.read_event_value	= apds9300_read_thresh,
+	.write_event_value	= apds9300_write_thresh,
+	.read_event_config	= apds9300_read_interrupt_config,
+	.write_event_config	= apds9300_write_interrupt_config,
+};
+
+static const struct iio_chan_spec apds9300_channels[] = {
+	{
+		.type = IIO_LIGHT,
+		.channel = 0,
+		.indexed = true,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+	}, {
+		.type = IIO_INTENSITY,
+		.channel = 0,
+		.channel2 = IIO_MOD_LIGHT_BOTH,
+		.indexed = true,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
+					  IIO_EV_DIR_RISING) |
+			       IIO_EV_BIT(IIO_EV_TYPE_THRESH,
+					  IIO_EV_DIR_FALLING)),
+	}, {
+		.type = IIO_INTENSITY,
+		.channel = 1,
+		.channel2 = IIO_MOD_LIGHT_IR,
+		.indexed = true,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+	},
+};
+
+static irqreturn_t apds9300_interrupt_handler(int irq, void *private)
+{
+	struct iio_dev *dev_info = private;
+	struct apds9300_data *data = iio_priv(dev_info);
+
+	iio_push_event(dev_info,
+		       IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
+					    IIO_EV_TYPE_THRESH,
+					    IIO_EV_DIR_EITHER),
+		       iio_get_time_ns());
+
+	apds9300_clear_intr(data);
+
+	return IRQ_HANDLED;
+}
+
+static int apds9300_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct apds9300_data *data;
+	struct iio_dev *indio_dev;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+
+	ret = apds9300_chip_init(data);
+	if (ret < 0)
+		goto err;
+
+	mutex_init(&data->mutex);
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->channels = apds9300_channels;
+	indio_dev->num_channels = ARRAY_SIZE(apds9300_channels);
+	indio_dev->name = APDS9300_DRV_NAME;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	if (client->irq)
+		indio_dev->info = &apds9300_info;
+	else
+		indio_dev->info = &apds9300_info_no_irq;
+
+	if (client->irq) {
+		ret = devm_request_threaded_irq(&client->dev, client->irq,
+				NULL, apds9300_interrupt_handler,
+				IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+				APDS9300_IRQ_NAME, indio_dev);
+		if (ret) {
+			dev_err(&client->dev, "irq request error %d\n", -ret);
+			goto err;
+		}
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		goto err;
+
+	return 0;
+
+err:
+	/* Ensure that power off in case of error */
+	apds9300_set_power_state(data, 0);
+	return ret;
+}
+
+static int apds9300_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct apds9300_data *data = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+
+	/* Ensure that power off and interrupts are disabled */
+	apds9300_set_intr_state(data, 0);
+	apds9300_set_power_state(data, 0);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int apds9300_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct apds9300_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = apds9300_set_power_state(data, 0);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static int apds9300_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct apds9300_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = apds9300_set_power_state(data, 1);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend, apds9300_resume);
+#define APDS9300_PM_OPS (&apds9300_pm_ops)
+#else
+#define APDS9300_PM_OPS NULL
+#endif
+
+static struct i2c_device_id apds9300_id[] = {
+	{ APDS9300_DRV_NAME, 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, apds9300_id);
+
+static struct i2c_driver apds9300_driver = {
+	.driver = {
+		.name	= APDS9300_DRV_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= APDS9300_PM_OPS,
+	},
+	.probe		= apds9300_probe,
+	.remove		= apds9300_remove,
+	.id_table	= apds9300_id,
+};
+
+module_i2c_driver(apds9300_driver);
+
+MODULE_AUTHOR("Kravchenko Oleksandr <o.v.kravchenko@globallogic.com>");
+MODULE_AUTHOR("GlobalLogic inc.");
+MODULE_DESCRIPTION("APDS9300 ambient light photo sensor driver");
+MODULE_LICENSE("GPL");

+ 16 - 25
drivers/iio/light/hid-sensor-als.c

@@ -30,10 +30,6 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/triggered_buffer.h>
 #include "../common/hid-sensors/hid-sensor-trigger.h"
 #include "../common/hid-sensors/hid-sensor-trigger.h"
 
 
-/*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Ambiant-Light: 0x200041*/
-#define DRIVER_NAME "HID-SENSOR-200041"
-
 #define CHANNEL_SCAN_INDEX_ILLUM 0
 #define CHANNEL_SCAN_INDEX_ILLUM 0
 
 
 struct als_state {
 struct als_state {
@@ -158,18 +154,10 @@ static int als_write_raw(struct iio_dev *indio_dev,
 	return ret;
 	return ret;
 }
 }
 
 
-static int als_write_raw_get_fmt(struct iio_dev *indio_dev,
-			       struct iio_chan_spec const *chan,
-			       long mask)
-{
-	return IIO_VAL_INT_PLUS_MICRO;
-}
-
 static const struct iio_info als_info = {
 static const struct iio_info als_info = {
 	.driver_module = THIS_MODULE,
 	.driver_module = THIS_MODULE,
 	.read_raw = &als_read_raw,
 	.read_raw = &als_read_raw,
 	.write_raw = &als_write_raw,
 	.write_raw = &als_write_raw,
-	.write_raw_get_fmt = &als_write_raw_get_fmt,
 };
 };
 
 
 /* Function to push data to buffer */
 /* Function to push data to buffer */
@@ -253,11 +241,9 @@ static int hid_als_probe(struct platform_device *pdev)
 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 	struct iio_chan_spec *channels;
 	struct iio_chan_spec *channels;
 
 
-	indio_dev = iio_device_alloc(sizeof(struct als_state));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct als_state));
+	if (!indio_dev)
+		return -ENOMEM;
 	platform_set_drvdata(pdev, indio_dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 
 	als_state = iio_priv(indio_dev);
 	als_state = iio_priv(indio_dev);
@@ -268,14 +254,13 @@ static int hid_als_probe(struct platform_device *pdev)
 					&als_state->common_attributes);
 					&als_state->common_attributes);
 	if (ret) {
 	if (ret) {
 		dev_err(&pdev->dev, "failed to setup common attributes\n");
 		dev_err(&pdev->dev, "failed to setup common attributes\n");
-		goto error_free_dev;
+		return ret;
 	}
 	}
 
 
 	channels = kmemdup(als_channels, sizeof(als_channels), GFP_KERNEL);
 	channels = kmemdup(als_channels, sizeof(als_channels), GFP_KERNEL);
 	if (!channels) {
 	if (!channels) {
-		ret = -ENOMEM;
 		dev_err(&pdev->dev, "failed to duplicate channels\n");
 		dev_err(&pdev->dev, "failed to duplicate channels\n");
-		goto error_free_dev;
+		return -ENOMEM;
 	}
 	}
 
 
 	ret = als_parse_report(pdev, hsdev, channels,
 	ret = als_parse_report(pdev, hsdev, channels,
@@ -333,9 +318,6 @@ static int hid_als_probe(struct platform_device *pdev)
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 error_free_dev_mem:
 error_free_dev_mem:
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-error_free_dev:
-	iio_device_free(indio_dev);
-error_ret:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -350,14 +332,23 @@ static int hid_als_remove(struct platform_device *pdev)
 	hid_sensor_remove_trigger(indio_dev);
 	hid_sensor_remove_trigger(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+static struct platform_device_id hid_als_ids[] = {
+	{
+		/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+		.name = "HID-SENSOR-200041",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_als_ids);
+
 static struct platform_driver hid_als_platform_driver = {
 static struct platform_driver hid_als_platform_driver = {
+	.id_table = hid_als_ids,
 	.driver = {
 	.driver = {
-		.name	= DRIVER_NAME,
+		.name	= KBUILD_MODNAME,
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= hid_als_probe,
 	.probe		= hid_als_probe,

+ 2 - 5
drivers/iio/light/lm3533-als.c

@@ -847,7 +847,7 @@ static int lm3533_als_probe(struct platform_device *pdev)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	indio_dev = iio_device_alloc(sizeof(*als));
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als));
 	if (!indio_dev)
 	if (!indio_dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -870,7 +870,7 @@ static int lm3533_als_probe(struct platform_device *pdev)
 	if (als->irq) {
 	if (als->irq) {
 		ret = lm3533_als_setup_irq(als, indio_dev);
 		ret = lm3533_als_setup_irq(als, indio_dev);
 		if (ret)
 		if (ret)
-			goto err_free_dev;
+			return ret;
 	}
 	}
 
 
 	ret = lm3533_als_setup(als, pdata);
 	ret = lm3533_als_setup(als, pdata);
@@ -894,8 +894,6 @@ static int lm3533_als_probe(struct platform_device *pdev)
 err_free_irq:
 err_free_irq:
 	if (als->irq)
 	if (als->irq)
 		free_irq(als->irq, indio_dev);
 		free_irq(als->irq, indio_dev);
-err_free_dev:
-	iio_device_free(indio_dev);
 
 
 	return ret;
 	return ret;
 }
 }
@@ -910,7 +908,6 @@ static int lm3533_als_remove(struct platform_device *pdev)
 	lm3533_als_disable(als);
 	lm3533_als_disable(als);
 	if (als->irq)
 	if (als->irq)
 		free_irq(als->irq, indio_dev);
 		free_irq(als->irq, indio_dev);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 8 - 17
drivers/iio/light/tsl2563.c

@@ -702,7 +702,7 @@ static int tsl2563_probe(struct i2c_client *client,
 	int err = 0;
 	int err = 0;
 	u8 id = 0;
 	u8 id = 0;
 
 
-	indio_dev = iio_device_alloc(sizeof(*chip));
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
 	if (!indio_dev)
 	if (!indio_dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -714,13 +714,13 @@ static int tsl2563_probe(struct i2c_client *client,
 	err = tsl2563_detect(chip);
 	err = tsl2563_detect(chip);
 	if (err) {
 	if (err) {
 		dev_err(&client->dev, "detect error %d\n", -err);
 		dev_err(&client->dev, "detect error %d\n", -err);
-		goto fail1;
+		return err;
 	}
 	}
 
 
 	err = tsl2563_read_id(chip, &id);
 	err = tsl2563_read_id(chip, &id);
 	if (err) {
 	if (err) {
 		dev_err(&client->dev, "read id error %d\n", -err);
 		dev_err(&client->dev, "read id error %d\n", -err);
-		goto fail1;
+		return err;
 	}
 	}
 
 
 	mutex_init(&chip->lock);
 	mutex_init(&chip->lock);
@@ -751,7 +751,7 @@ static int tsl2563_probe(struct i2c_client *client,
 		indio_dev->info = &tsl2563_info_no_irq;
 		indio_dev->info = &tsl2563_info_no_irq;
 
 
 	if (client->irq) {
 	if (client->irq) {
-		err = request_threaded_irq(client->irq,
+		err = devm_request_threaded_irq(&client->dev, client->irq,
 					   NULL,
 					   NULL,
 					   &tsl2563_event_handler,
 					   &tsl2563_event_handler,
 					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
 					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -759,14 +759,14 @@ static int tsl2563_probe(struct i2c_client *client,
 					   indio_dev);
 					   indio_dev);
 		if (err) {
 		if (err) {
 			dev_err(&client->dev, "irq request error %d\n", -err);
 			dev_err(&client->dev, "irq request error %d\n", -err);
-			goto fail1;
+			return err;
 		}
 		}
 	}
 	}
 
 
 	err = tsl2563_configure(chip);
 	err = tsl2563_configure(chip);
 	if (err) {
 	if (err) {
 		dev_err(&client->dev, "configure error %d\n", -err);
 		dev_err(&client->dev, "configure error %d\n", -err);
-		goto fail2;
+		return err;
 	}
 	}
 
 
 	INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
 	INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
@@ -777,19 +777,14 @@ static int tsl2563_probe(struct i2c_client *client,
 	err = iio_device_register(indio_dev);
 	err = iio_device_register(indio_dev);
 	if (err) {
 	if (err) {
 		dev_err(&client->dev, "iio registration error %d\n", -err);
 		dev_err(&client->dev, "iio registration error %d\n", -err);
-		goto fail3;
+		goto fail;
 	}
 	}
 
 
 	return 0;
 	return 0;
 
 
-fail3:
+fail:
 	cancel_delayed_work(&chip->poweroff_work);
 	cancel_delayed_work(&chip->poweroff_work);
 	flush_scheduled_work();
 	flush_scheduled_work();
-fail2:
-	if (client->irq)
-		free_irq(client->irq, indio_dev);
-fail1:
-	iio_device_free(indio_dev);
 	return err;
 	return err;
 }
 }
 
 
@@ -807,10 +802,6 @@ static int tsl2563_remove(struct i2c_client *client)
 				  chip->intr);
 				  chip->intr);
 	flush_scheduled_work();
 	flush_scheduled_work();
 	tsl2563_set_power(chip, 0);
 	tsl2563_set_power(chip, 0);
-	if (client->irq)
-		free_irq(client->irq, indio_dev);
-
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }

+ 4 - 12
drivers/iio/light/vcnl4000.c

@@ -157,7 +157,7 @@ static int vcnl4000_probe(struct i2c_client *client,
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int ret;
 	int ret;
 
 
-	indio_dev = iio_device_alloc(sizeof(*data));
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 	if (!indio_dev)
 	if (!indio_dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -167,7 +167,7 @@ static int vcnl4000_probe(struct i2c_client *client,
 
 
 	ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
 	ret = i2c_smbus_read_byte_data(data->client, VCNL4000_PROD_REV);
 	if (ret < 0)
 	if (ret < 0)
-		goto error_free_dev;
+		return ret;
 
 
 	dev_info(&client->dev, "VCNL4000 Ambient light/proximity sensor, Prod %02x, Rev: %02x\n",
 	dev_info(&client->dev, "VCNL4000 Ambient light/proximity sensor, Prod %02x, Rev: %02x\n",
 		ret >> 4, ret & 0xf);
 		ret >> 4, ret & 0xf);
@@ -181,22 +181,14 @@ static int vcnl4000_probe(struct i2c_client *client,
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret < 0)
 	if (ret < 0)
-		goto error_free_dev;
+		return ret;
 
 
 	return 0;
 	return 0;
-
-error_free_dev:
-	iio_device_free(indio_dev);
-	return ret;
 }
 }
 
 
 static int vcnl4000_remove(struct i2c_client *client)
 static int vcnl4000_remove(struct i2c_client *client)
 {
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(client);
-
-	iio_device_unregister(indio_dev);
-	iio_device_free(indio_dev);
-
+	iio_device_unregister(i2c_get_clientdata(client));
 	return 0;
 	return 0;
 }
 }
 
 

+ 4 - 2
drivers/iio/magnetometer/Kconfig

@@ -1,6 +1,8 @@
 #
 #
 # Magnetometer sensors
 # Magnetometer sensors
 #
 #
+# When adding new entries keep the list in alphabetical order
+
 menu "Magnetometer sensors"
 menu "Magnetometer sensors"
 
 
 config AK8975
 config AK8975
@@ -36,8 +38,8 @@ config IIO_ST_MAGN_3AXIS
 	  Say yes here to build support for STMicroelectronics magnetometers:
 	  Say yes here to build support for STMicroelectronics magnetometers:
 	  LSM303DLHC, LSM303DLM, LIS3MDL.
 	  LSM303DLHC, LSM303DLM, LIS3MDL.
 
 
-	  This driver can also be built as a module. If so, will be created
-	  these modules:
+	  This driver can also be built as a module. If so, these modules
+	  will be created:
 	  - st_magn (core functions for the driver [it is mandatory]);
 	  - st_magn (core functions for the driver [it is mandatory]);
 	  - st_magn_i2c (necessary for the I2C devices [optional*]);
 	  - st_magn_i2c (necessary for the I2C devices [optional*]);
 	  - st_magn_spi (necessary for the SPI devices [optional*]);
 	  - st_magn_spi (necessary for the SPI devices [optional*]);

+ 1 - 0
drivers/iio/magnetometer/Makefile

@@ -2,6 +2,7 @@
 # Makefile for industrial I/O Magnetometer sensor drivers
 # Makefile for industrial I/O Magnetometer sensor drivers
 #
 #
 
 
+# When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AK8975)	+= ak8975.o
 obj-$(CONFIG_AK8975)	+= ak8975.o
 obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
 obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
 
 

+ 18 - 25
drivers/iio/magnetometer/hid-sensor-magn-3d.c

@@ -30,10 +30,6 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/triggered_buffer.h>
 #include "../common/hid-sensors/hid-sensor-trigger.h"
 #include "../common/hid-sensors/hid-sensor-trigger.h"
 
 
-/*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Magnetometer-3D: 0x200083*/
-#define DRIVER_NAME "HID-SENSOR-200083"
-
 enum magn_3d_channel {
 enum magn_3d_channel {
 	CHANNEL_SCAN_INDEX_X,
 	CHANNEL_SCAN_INDEX_X,
 	CHANNEL_SCAN_INDEX_Y,
 	CHANNEL_SCAN_INDEX_Y,
@@ -180,18 +176,10 @@ static int magn_3d_write_raw(struct iio_dev *indio_dev,
 	return ret;
 	return ret;
 }
 }
 
 
-static int magn_3d_write_raw_get_fmt(struct iio_dev *indio_dev,
-			       struct iio_chan_spec const *chan,
-			       long mask)
-{
-	return IIO_VAL_INT_PLUS_MICRO;
-}
-
 static const struct iio_info magn_3d_info = {
 static const struct iio_info magn_3d_info = {
 	.driver_module = THIS_MODULE,
 	.driver_module = THIS_MODULE,
 	.read_raw = &magn_3d_read_raw,
 	.read_raw = &magn_3d_read_raw,
 	.write_raw = &magn_3d_write_raw,
 	.write_raw = &magn_3d_write_raw,
-	.write_raw_get_fmt = &magn_3d_write_raw_get_fmt,
 };
 };
 
 
 /* Function to push data to buffer */
 /* Function to push data to buffer */
@@ -287,11 +275,11 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 	struct iio_chan_spec *channels;
 	struct iio_chan_spec *channels;
 
 
-	indio_dev = iio_device_alloc(sizeof(struct magn_3d_state));
-	if (indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	indio_dev = devm_iio_device_alloc(&pdev->dev,
+					  sizeof(struct magn_3d_state));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
 	platform_set_drvdata(pdev, indio_dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 
 	magn_state = iio_priv(indio_dev);
 	magn_state = iio_priv(indio_dev);
@@ -303,15 +291,14 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
 				&magn_state->common_attributes);
 				&magn_state->common_attributes);
 	if (ret) {
 	if (ret) {
 		dev_err(&pdev->dev, "failed to setup common attributes\n");
 		dev_err(&pdev->dev, "failed to setup common attributes\n");
-		goto error_free_dev;
+		return ret;
 	}
 	}
 
 
 	channels = kmemdup(magn_3d_channels, sizeof(magn_3d_channels),
 	channels = kmemdup(magn_3d_channels, sizeof(magn_3d_channels),
 			   GFP_KERNEL);
 			   GFP_KERNEL);
 	if (!channels) {
 	if (!channels) {
-		ret = -ENOMEM;
 		dev_err(&pdev->dev, "failed to duplicate channels\n");
 		dev_err(&pdev->dev, "failed to duplicate channels\n");
-		goto error_free_dev;
+		return -ENOMEM;
 	}
 	}
 
 
 	ret = magn_3d_parse_report(pdev, hsdev, channels,
 	ret = magn_3d_parse_report(pdev, hsdev, channels,
@@ -368,9 +355,6 @@ static int hid_magn_3d_probe(struct platform_device *pdev)
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 error_free_dev_mem:
 error_free_dev_mem:
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-error_free_dev:
-	iio_device_free(indio_dev);
-error_ret:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -385,14 +369,23 @@ static int hid_magn_3d_remove(struct platform_device *pdev)
 	hid_sensor_remove_trigger(indio_dev);
 	hid_sensor_remove_trigger(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	kfree(indio_dev->channels);
 	kfree(indio_dev->channels);
-	iio_device_free(indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+static struct platform_device_id hid_magn_3d_ids[] = {
+	{
+		/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+		.name = "HID-SENSOR-200083",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_magn_3d_ids);
+
 static struct platform_driver hid_magn_3d_platform_driver = {
 static struct platform_driver hid_magn_3d_platform_driver = {
+	.id_table = hid_magn_3d_ids,
 	.driver = {
 	.driver = {
-		.name	= DRIVER_NAME,
+		.name	= KBUILD_MODNAME,
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= hid_magn_3d_probe,
 	.probe		= hid_magn_3d_probe,

+ 2 - 1
drivers/iio/magnetometer/st_magn.h

@@ -18,7 +18,8 @@
 #define LSM303DLM_MAGN_DEV_NAME		"lsm303dlm_magn"
 #define LSM303DLM_MAGN_DEV_NAME		"lsm303dlm_magn"
 #define LIS3MDL_MAGN_DEV_NAME		"lis3mdl"
 #define LIS3MDL_MAGN_DEV_NAME		"lis3mdl"
 
 
-int st_magn_common_probe(struct iio_dev *indio_dev);
+int st_magn_common_probe(struct iio_dev *indio_dev,
+					struct st_sensors_platform_data *pdata);
 void st_magn_common_remove(struct iio_dev *indio_dev);
 void st_magn_common_remove(struct iio_dev *indio_dev);
 
 
 #ifdef CONFIG_IIO_BUFFER
 #ifdef CONFIG_IIO_BUFFER

Неке датотеке нису приказане због велике количине промена