Browse Source

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

Pull staging driver updates from Greg KH:
 "Here is the big staging driver updates for 4.3-rc1.

  Lots of things all over the place, almost all of them trivial fixups
  and changes.  The usual IIO updates and new drivers and we have added
  the MOST driver subsystem which is getting cleaned up in the tree.
  The ozwpan driver is finally being deleted as it is obviously
  abandoned and no one cares about it.

  Full details are in the shortlog, and all of these have been in
  linux-next with no reported issues"

* tag 'staging-4.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (912 commits)
  staging/lustre/o2iblnd: remove references to ib_reg_phsy_mr()
  staging: wilc1000: fix build warning with setup_timer()
  staging: wilc1000: remove DECLARE_WILC_BUFFER()
  staging: wilc1000: remove void function return statements that are not useful
  staging: wilc1000: coreconfigurator.c: fix kmalloc error check
  staging: wilc1000: coreconfigurator.c: use kmalloc instead of WILC_MALLOC
  staging: wilc1000: remove unused codes of gps8ConfigPacket
  staging: wilc1000: remove unnecessary void pointer cast
  staging: wilc1000: remove WILC_NEW and WILC_NEW_EX
  staging: wilc1000: use kmalloc instead of WILC_NEW
  staging: wilc1000: Process WARN, INFO options of debug levels from user
  staging: wilc1000: remove unneeded tstrWILC_MsgQueueAttrs typedef
  staging: wilc1000: delete wilc_osconfig.h
  staging: wilc1000: delete wilc_log.h
  staging: wilc1000: delete wilc_timer.h
  staging: wilc1000: remove WILC_TimerStart()
  staging: wilc1000: remove WILC_TimerCreate()
  staging: wilc1000: remove WILC_TimerDestroy()
  staging: wilc1000: remove WILC_TimerStop()
  staging: wilc1000: remove tstrWILC_TimerAttrs typedef
  ...
Linus Torvalds 10 years ago
parent
commit
2f37d65a6a
100 changed files with 4613 additions and 752 deletions
  1. 8 10
      Documentation/ABI/testing/sysfs-bus-iio
  2. 9 0
      Documentation/ABI/testing/sysfs-bus-iio-trigger-sysfs
  3. 1 1
      Documentation/DocBook/Makefile
  4. 697 0
      Documentation/DocBook/iio.tmpl
  5. 1 0
      Documentation/devicetree/bindings/iio/adc/mcp320x.txt
  6. 5 0
      Documentation/devicetree/bindings/iio/adc/vf610-adc.txt
  7. 13 0
      Documentation/devicetree/bindings/iio/magnetometer/mmc35240.txt
  8. 2 0
      Documentation/devicetree/bindings/iio/st-sensors.txt
  9. 1 1
      Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
  10. 31 0
      Documentation/fb/sm712fb.txt
  11. 9 13
      MAINTAINERS
  12. 14 12
      drivers/iio/accel/Kconfig
  13. 0 1
      drivers/iio/accel/bma180.c
  14. 121 122
      drivers/iio/accel/bmc150-accel.c
  15. 1 4
      drivers/iio/accel/kxcjk-1013.c
  16. 123 94
      drivers/iio/accel/mma8452.c
  17. 16 19
      drivers/iio/accel/mma9551_core.c
  18. 3 3
      drivers/iio/accel/mma9551_core.h
  19. 43 40
      drivers/iio/accel/mma9553.c
  20. 1 0
      drivers/iio/accel/st_accel.h
  21. 6 0
      drivers/iio/accel/st_accel_core.c
  22. 5 1
      drivers/iio/accel/st_accel_i2c.c
  23. 1 0
      drivers/iio/accel/st_accel_spi.c
  24. 371 58
      drivers/iio/accel/stk8312.c
  25. 333 36
      drivers/iio/accel/stk8ba50.c
  26. 40 12
      drivers/iio/adc/Kconfig
  27. 10 12
      drivers/iio/adc/berlin2-adc.c
  28. 21 5
      drivers/iio/adc/cc10001_adc.c
  29. 15 1
      drivers/iio/adc/mcp320x.c
  30. 0 1
      drivers/iio/adc/mcp3422.c
  31. 0 1
      drivers/iio/adc/ti-adc081c.c
  32. 75 4
      drivers/iio/adc/vf610_adc.c
  33. 0 1
      drivers/iio/common/ssp_sensors/ssp_dev.c
  34. 26 26
      drivers/iio/common/st_sensors/st_sensors_core.c
  35. 0 1
      drivers/iio/dac/ad5064.c
  36. 0 1
      drivers/iio/dac/ad5380.c
  37. 0 1
      drivers/iio/dac/ad5446.c
  38. 0 1
      drivers/iio/dac/max5821.c
  39. 0 1
      drivers/iio/frequency/adf4350.c
  40. 2 1
      drivers/iio/gyro/Kconfig
  41. 6 0
      drivers/iio/gyro/adis16136.c
  42. 98 39
      drivers/iio/gyro/adis16260.c
  43. 0 1
      drivers/iio/gyro/itg3200_core.c
  44. 3 0
      drivers/iio/gyro/st_gyro_core.c
  45. 0 1
      drivers/iio/gyro/st_gyro_i2c.c
  46. 35 30
      drivers/iio/humidity/dht11.c
  47. 0 1
      drivers/iio/humidity/si7005.c
  48. 44 2
      drivers/iio/imu/adis16400_core.c
  49. 33 6
      drivers/iio/imu/adis16480.c
  50. 6 1
      drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
  51. 4 4
      drivers/iio/imu/kmx61.c
  52. 24 11
      drivers/iio/industrialio-buffer.c
  53. 28 5
      drivers/iio/industrialio-core.c
  54. 7 1
      drivers/iio/industrialio-event.c
  55. 24 3
      drivers/iio/industrialio-trigger.c
  56. 6 6
      drivers/iio/industrialio-triggered-buffer.c
  57. 33 1
      drivers/iio/light/Kconfig
  58. 3 0
      drivers/iio/light/Makefile
  59. 9 9
      drivers/iio/light/acpi-als.c
  60. 0 1
      drivers/iio/light/apds9300.c
  61. 0 1
      drivers/iio/light/bh1750.c
  62. 1 1
      drivers/iio/light/cm32181.c
  63. 1 1
      drivers/iio/light/cm3232.c
  64. 12 7
      drivers/iio/light/cm3323.c
  65. 1 1
      drivers/iio/light/cm36651.c
  66. 1 1
      drivers/iio/light/gp2ap020a00f.c
  67. 1 2
      drivers/iio/light/hid-sensor-prox.c
  68. 12 1
      drivers/iio/light/isl29125.c
  69. 0 1
      drivers/iio/light/jsa1212.c
  70. 0 1
      drivers/iio/light/ltr501.c
  71. 804 0
      drivers/iio/light/opt3001.c
  72. 483 0
      drivers/iio/light/pa12203001.c
  73. 615 0
      drivers/iio/light/rpr0521.c
  74. 1 0
      drivers/iio/light/stk3310.c
  75. 0 1
      drivers/iio/light/tcs3414.c
  76. 0 1
      drivers/iio/light/tcs3472.c
  77. 0 1
      drivers/iio/light/tsl4531.c
  78. 0 1
      drivers/iio/light/vcnl4000.c
  79. 52 43
      drivers/iio/magnetometer/bmc150_magn.c
  80. 20 13
      drivers/iio/magnetometer/mmc35240.c
  81. 3 0
      drivers/iio/magnetometer/st_magn.h
  82. 7 0
      drivers/iio/magnetometer/st_magn_buffer.c
  83. 97 1
      drivers/iio/magnetometer/st_magn_core.c
  84. 5 1
      drivers/iio/magnetometer/st_magn_i2c.c
  85. 1 0
      drivers/iio/magnetometer/st_magn_spi.c
  86. 3 3
      drivers/iio/pressure/Kconfig
  87. 14 2
      drivers/iio/pressure/ms5611.h
  88. 68 14
      drivers/iio/pressure/ms5611_core.c
  89. 3 3
      drivers/iio/pressure/ms5611_i2c.c
  90. 4 2
      drivers/iio/pressure/ms5611_spi.c
  91. 3 0
      drivers/iio/pressure/st_pressure_core.c
  92. 0 1
      drivers/iio/pressure/st_pressure_i2c.c
  93. 14 7
      drivers/iio/temperature/mlx90614.c
  94. 2 3
      drivers/iio/temperature/tmp006.c
  95. 2 4
      drivers/staging/Kconfig
  96. 1 2
      drivers/staging/Makefile
  97. 2 1
      drivers/staging/android/Kconfig
  98. 1 9
      drivers/staging/android/TODO
  99. 2 2
      drivers/staging/android/ashmem.c
  100. 10 14
      drivers/staging/android/ion/ion.c

+ 8 - 10
Documentation/ABI/testing/sysfs-bus-iio

@@ -413,6 +413,11 @@ Description:
 		to compute the calories burnt by the user.
 		to compute the calories burnt by the user.
 
 
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_scale_available
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_scale_available
+What:		/sys/.../iio:deviceX/in_anglvel_scale_available
+What:		/sys/.../iio:deviceX/in_magn_scale_available
+What:		/sys/.../iio:deviceX/in_illuminance_scale_available
+What:		/sys/.../iio:deviceX/in_intensity_scale_available
+What:		/sys/.../iio:deviceX/in_proximity_scale_available
 What:		/sys/.../iio:deviceX/in_voltageX_scale_available
 What:		/sys/.../iio:deviceX/in_voltageX_scale_available
 What:		/sys/.../iio:deviceX/in_voltage-voltage_scale_available
 What:		/sys/.../iio:deviceX/in_voltage-voltage_scale_available
 What:		/sys/.../iio:deviceX/out_voltageX_scale_available
 What:		/sys/.../iio:deviceX/out_voltageX_scale_available
@@ -488,7 +493,7 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 Description:
 		Specifies the output powerdown mode.
 		Specifies the output powerdown mode.
 		DAC output stage is disconnected from the amplifier and
 		DAC output stage is disconnected from the amplifier and
-		1kohm_to_gnd: connected	to ground via an 1kOhm resistor,
+		1kohm_to_gnd: connected to ground via an 1kOhm resistor,
 		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,
@@ -498,9 +503,9 @@ Description:
 		outX_powerdown_mode_available. If Y is not present the
 		outX_powerdown_mode_available. If Y is not present the
 		mode is shared across all outputs.
 		mode is shared across all outputs.
 
 
-What:		/sys/.../iio:deviceX/out_votlageY_powerdown_mode_available
+What:		/sys/.../iio:deviceX/out_voltageY_powerdown_mode_available
 What:		/sys/.../iio:deviceX/out_voltage_powerdown_mode_available
 What:		/sys/.../iio:deviceX/out_voltage_powerdown_mode_available
-What:		/sys/.../iio:deviceX/out_altvotlageY_powerdown_mode_available
+What:		/sys/.../iio:deviceX/out_altvoltageY_powerdown_mode_available
 What:		/sys/.../iio:deviceX/out_altvoltage_powerdown_mode_available
 What:		/sys/.../iio:deviceX/out_altvoltage_powerdown_mode_available
 KernelVersion:	2.6.38
 KernelVersion:	2.6.38
 Contact:	linux-iio@vger.kernel.org
 Contact:	linux-iio@vger.kernel.org
@@ -1035,13 +1040,6 @@ Contact:	linux-iio@vger.kernel.org
 Description:
 Description:
 		Number of scans contained by the buffer.
 		Number of scans contained by the buffer.
 
 
-What:		/sys/bus/iio/devices/iio:deviceX/buffer/bytes_per_datum
-KernelVersion:	2.6.37
-Contact:	linux-iio@vger.kernel.org
-Description:
-		Bytes per scan.  Due to alignment fun, the scan may be larger
-		than implied directly by the scan_element parameters.
-
 What:		/sys/bus/iio/devices/iio:deviceX/buffer/enable
 What:		/sys/bus/iio/devices/iio:deviceX/buffer/enable
 KernelVersion:	2.6.35
 KernelVersion:	2.6.35
 Contact:	linux-iio@vger.kernel.org
 Contact:	linux-iio@vger.kernel.org

+ 9 - 0
Documentation/ABI/testing/sysfs-bus-iio-trigger-sysfs

@@ -9,3 +9,12 @@ Description:
 		automated testing or in situations, where other trigger methods
 		automated testing or in situations, where other trigger methods
 		are not applicable. For example no RTC or spare GPIOs.
 		are not applicable. For example no RTC or spare GPIOs.
 		X is the IIO index of the trigger.
 		X is the IIO index of the trigger.
+
+What:		/sys/bus/iio/devices/triggerX/name
+KernelVersion:	2.6.39
+Contact:	linux-iio@vger.kernel.org
+Description:
+		The name attribute holds a description string for the current
+		trigger. In order to associate the trigger with an IIO device
+		one should write this name string to
+		/sys/bus/iio/devices/iio:deviceY/trigger/current_trigger.

+ 1 - 1
Documentation/DocBook/Makefile

@@ -15,7 +15,7 @@ DOCBOOKS := z8530book.xml device-drivers.xml \
 	    80211.xml debugobjects.xml sh.xml regulator.xml \
 	    80211.xml debugobjects.xml sh.xml regulator.xml \
 	    alsa-driver-api.xml writing-an-alsa-driver.xml \
 	    alsa-driver-api.xml writing-an-alsa-driver.xml \
 	    tracepoint.xml drm.xml media_api.xml w1.xml \
 	    tracepoint.xml drm.xml media_api.xml w1.xml \
-	    writing_musb_glue_layer.xml crypto-API.xml
+	    writing_musb_glue_layer.xml crypto-API.xml iio.xml
 
 
 include Documentation/DocBook/media/Makefile
 include Documentation/DocBook/media/Makefile
 
 

+ 697 - 0
Documentation/DocBook/iio.tmpl

@@ -0,0 +1,697 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+
+<book id="iioid">
+  <bookinfo>
+    <title>Industrial I/O driver developer's guide </title>
+
+    <authorgroup>
+      <author>
+        <firstname>Daniel</firstname>
+        <surname>Baluta</surname>
+        <affiliation>
+          <address>
+            <email>daniel.baluta@intel.com</email>
+          </address>
+        </affiliation>
+      </author>
+    </authorgroup>
+
+    <copyright>
+      <year>2015</year>
+      <holder>Intel Corporation</holder>
+    </copyright>
+
+    <legalnotice>
+      <para>
+        This documentation is free software; you can redistribute
+        it and/or modify it under the terms of the GNU General Public
+        License version 2.
+      </para>
+    </legalnotice>
+  </bookinfo>
+
+  <toc></toc>
+
+  <chapter id="intro">
+    <title>Introduction</title>
+    <para>
+      The main purpose of the Industrial I/O subsystem (IIO) is to provide
+      support for devices that in some sense perform either analog-to-digital
+      conversion (ADC) or digital-to-analog conversion (DAC) or both. The aim
+      is to fill the gap between the somewhat similar hwmon and input
+      subsystems.
+      Hwmon is directed at low sample rate sensors used to monitor and
+      control the system itself, like fan speed control or temperature
+      measurement. Input is, as its name suggests, focused on human interaction
+      input devices (keyboard, mouse, touchscreen). In some cases there is
+      considerable overlap between these and IIO.
+  </para>
+  <para>
+    Devices that fall into this category include:
+    <itemizedlist>
+      <listitem>
+        analog to digital converters (ADCs)
+      </listitem>
+      <listitem>
+        accelerometers
+      </listitem>
+      <listitem>
+        capacitance to digital converters (CDCs)
+      </listitem>
+      <listitem>
+        digital to analog converters (DACs)
+      </listitem>
+      <listitem>
+        gyroscopes
+      </listitem>
+      <listitem>
+        inertial measurement units (IMUs)
+      </listitem>
+      <listitem>
+        color and light sensors
+      </listitem>
+      <listitem>
+        magnetometers
+      </listitem>
+      <listitem>
+        pressure sensors
+      </listitem>
+      <listitem>
+        proximity sensors
+      </listitem>
+      <listitem>
+        temperature sensors
+      </listitem>
+    </itemizedlist>
+    Usually these sensors are connected via SPI or I2C. A common use case of the
+    sensors devices is to have combined functionality (e.g. light plus proximity
+    sensor).
+  </para>
+  </chapter>
+  <chapter id='iiosubsys'>
+    <title>Industrial I/O core</title>
+    <para>
+      The Industrial I/O core offers:
+      <itemizedlist>
+        <listitem>
+         a unified framework for writing drivers for many different types of
+         embedded sensors.
+        </listitem>
+        <listitem>
+         a standard interface to user space applications manipulating sensors.
+        </listitem>
+      </itemizedlist>
+      The implementation can be found under <filename>
+      drivers/iio/industrialio-*</filename>
+  </para>
+  <sect1 id="iiodevice">
+    <title> Industrial I/O devices </title>
+
+!Finclude/linux/iio/iio.h iio_dev
+!Fdrivers/iio/industrialio-core.c iio_device_alloc
+!Fdrivers/iio/industrialio-core.c iio_device_free
+!Fdrivers/iio/industrialio-core.c iio_device_register
+!Fdrivers/iio/industrialio-core.c iio_device_unregister
+
+    <para>
+      An IIO device usually corresponds to a single hardware sensor and it
+      provides all the information needed by a driver handling a device.
+      Let's first have a look at the functionality embedded in an IIO
+      device then we will show how a device driver makes use of an IIO
+      device.
+    </para>
+    <para>
+        There are two ways for a user space application to interact
+        with an IIO driver.
+      <itemizedlist>
+        <listitem>
+          <filename>/sys/bus/iio/iio:deviceX/</filename>, this
+          represents a hardware sensor and groups together the data
+          channels of the same chip.
+        </listitem>
+        <listitem>
+          <filename>/dev/iio:deviceX</filename>, character device node
+          interface used for buffered data transfer and for events information
+          retrieval.
+        </listitem>
+      </itemizedlist>
+    </para>
+    A typical IIO driver will register itself as an I2C or SPI driver and will
+    create two routines, <function> probe </function> and <function> remove
+    </function>. At <function>probe</function>:
+    <itemizedlist>
+    <listitem>call <function>iio_device_alloc</function>, which allocates memory
+      for an IIO device.
+    </listitem>
+    <listitem> initialize IIO device fields with driver specific information
+              (e.g. device name, device channels).
+    </listitem>
+    <listitem>call <function> iio_device_register</function>, this registers the
+      device with the IIO core. After this call the device is ready to accept
+      requests from user space applications.
+    </listitem>
+    </itemizedlist>
+      At <function>remove</function>, we free the resources allocated in
+      <function>probe</function> in reverse order:
+    <itemizedlist>
+    <listitem><function>iio_device_unregister</function>, unregister the device
+      from the IIO core.
+    </listitem>
+    <listitem><function>iio_device_free</function>, free the memory allocated
+      for the IIO device.
+    </listitem>
+    </itemizedlist>
+
+    <sect2 id="iioattr"> <title> IIO device sysfs interface </title>
+      <para>
+        Attributes are sysfs files used to expose chip info and also allowing
+        applications to set various configuration parameters. For device
+        with index X, attributes can be found under
+        <filename>/sys/bus/iio/iio:deviceX/ </filename> directory.
+        Common attributes are:
+        <itemizedlist>
+          <listitem><filename>name</filename>, description of the physical
+            chip.
+          </listitem>
+          <listitem><filename>dev</filename>, shows the major:minor pair
+            associated with <filename>/dev/iio:deviceX</filename> node.
+          </listitem>
+          <listitem><filename>sampling_frequency_available</filename>,
+            available discrete set of sampling frequency values for
+            device.
+          </listitem>
+      </itemizedlist>
+      Available standard attributes for IIO devices are described in the
+      <filename>Documentation/ABI/testing/sysfs-bus-iio </filename> file
+      in the Linux kernel sources.
+      </para>
+    </sect2>
+    <sect2 id="iiochannel"> <title> IIO device channels </title>
+!Finclude/linux/iio/iio.h iio_chan_spec structure.
+      <para>
+        An IIO device channel is a representation of a data channel. An
+        IIO device can have one or multiple channels. For example:
+        <itemizedlist>
+          <listitem>
+          a thermometer sensor has one channel representing the
+          temperature measurement.
+          </listitem>
+          <listitem>
+          a light sensor with two channels indicating the measurements in
+          the visible and infrared spectrum.
+          </listitem>
+          <listitem>
+          an accelerometer can have up to 3 channels representing
+          acceleration on X, Y and Z axes.
+          </listitem>
+        </itemizedlist>
+      An IIO channel is described by the <type> struct iio_chan_spec
+      </type>. A thermometer driver for the temperature sensor in the
+      example above would have to describe its channel as follows:
+      <programlisting>
+      static const struct iio_chan_spec temp_channel[] = {
+          {
+              .type = IIO_TEMP,
+              .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+          },
+      };
+
+      </programlisting>
+      Channel sysfs attributes exposed to userspace are specified in
+      the form of <emphasis>bitmasks</emphasis>. Depending on their
+      shared info, attributes can be set in one of the following masks:
+      <itemizedlist>
+      <listitem><emphasis>info_mask_separate</emphasis>, attributes will
+        be specific to this channel</listitem>
+      <listitem><emphasis>info_mask_shared_by_type</emphasis>,
+        attributes are shared by all channels of the same type</listitem>
+      <listitem><emphasis>info_mask_shared_by_dir</emphasis>, attributes
+        are shared by all channels of the same direction </listitem>
+      <listitem><emphasis>info_mask_shared_by_all</emphasis>,
+        attributes are shared by all channels</listitem>
+      </itemizedlist>
+      When there are multiple data channels per channel type we have two
+      ways to distinguish between them:
+      <itemizedlist>
+      <listitem> set <emphasis> .modified</emphasis> field of <type>
+        iio_chan_spec</type> to 1. Modifiers are specified using
+        <emphasis>.channel2</emphasis> field of the same
+        <type>iio_chan_spec</type> structure and are used to indicate a
+        physically unique characteristic of the channel such as its direction
+        or spectral response. For example, a light sensor can have two channels,
+        one for infrared light and one for both infrared and visible light.
+      </listitem>
+      <listitem> set <emphasis>.indexed </emphasis> field of
+        <type>iio_chan_spec</type> to 1. In this case the channel is
+        simply another instance with an index specified by the
+        <emphasis>.channel</emphasis> field.
+      </listitem>
+      </itemizedlist>
+      Here is how we can make use of the channel's modifiers:
+      <programlisting>
+      static const struct iio_chan_spec light_channels[] = {
+          {
+              .type = IIO_INTENSITY,
+              .modified = 1,
+              .channel2 = IIO_MOD_LIGHT_IR,
+              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+              .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+          },
+          {
+              .type = IIO_INTENSITY,
+              .modified = 1,
+              .channel2 = IIO_MOD_LIGHT_BOTH,
+              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+              .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+          },
+          {
+              .type = IIO_LIGHT,
+              .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+              .info_mask_shared = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+          },
+
+      }
+      </programlisting>
+      This channel's definition will generate two separate sysfs files
+      for raw data retrieval:
+      <itemizedlist>
+      <listitem>
+      <filename>/sys/bus/iio/iio:deviceX/in_intensity_ir_raw</filename>
+      </listitem>
+      <listitem>
+      <filename>/sys/bus/iio/iio:deviceX/in_intensity_both_raw</filename>
+      </listitem>
+      </itemizedlist>
+      one file for processed data:
+      <itemizedlist>
+      <listitem>
+      <filename>/sys/bus/iio/iio:deviceX/in_illuminance_input
+      </filename>
+      </listitem>
+      </itemizedlist>
+      and one shared sysfs file for sampling frequency:
+      <itemizedlist>
+      <listitem>
+      <filename>/sys/bus/iio/iio:deviceX/sampling_frequency.
+      </filename>
+      </listitem>
+      </itemizedlist>
+      </para>
+      <para>
+      Here is how we can make use of the channel's indexing:
+      <programlisting>
+      static const struct iio_chan_spec light_channels[] = {
+          {
+              .type = IIO_VOLTAGE,
+              .indexed = 1,
+              .channel = 0,
+              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+          },
+          {
+              .type = IIO_VOLTAGE,
+              .indexed = 1,
+              .channel = 1,
+              .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+          },
+      }
+      </programlisting>
+      This will generate two separate attributes files for raw data
+      retrieval:
+      <itemizedlist>
+      <listitem>
+        <filename>/sys/bus/iio/devices/iio:deviceX/in_voltage0_raw</filename>,
+          representing voltage measurement for channel 0.
+      </listitem>
+      <listitem>
+        <filename>/sys/bus/iio/devices/iio:deviceX/in_voltage1_raw</filename>,
+          representing voltage measurement for channel 1.
+      </listitem>
+      </itemizedlist>
+      </para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="iiobuffer"> <title> Industrial I/O buffers </title>
+!Finclude/linux/iio/buffer.h iio_buffer
+!Edrivers/iio/industrialio-buffer.c
+
+    <para>
+    The Industrial I/O core offers a way for continuous data capture
+    based on a trigger source. Multiple data channels can be read at once
+    from <filename>/dev/iio:deviceX</filename> character device node,
+    thus reducing the CPU load.
+    </para>
+
+    <sect2 id="iiobuffersysfs">
+    <title>IIO buffer sysfs interface </title>
+    <para>
+      An IIO buffer has an associated attributes directory under <filename>
+      /sys/bus/iio/iio:deviceX/buffer/</filename>. Here are the existing
+      attributes:
+      <itemizedlist>
+      <listitem>
+      <emphasis>length</emphasis>, the total number of data samples
+      (capacity) that can be stored by the buffer.
+      </listitem>
+      <listitem>
+        <emphasis>enable</emphasis>, activate buffer capture.
+      </listitem>
+      </itemizedlist>
+
+    </para>
+    </sect2>
+    <sect2 id="iiobuffersetup"> <title> IIO buffer setup </title>
+      <para>The meta information associated with a channel reading
+        placed in a buffer is called a <emphasis> scan element </emphasis>.
+        The important bits configuring scan elements are exposed to
+        userspace applications via the <filename>
+        /sys/bus/iio/iio:deviceX/scan_elements/</filename> directory. This
+        file contains attributes of the following form:
+      <itemizedlist>
+      <listitem><emphasis>enable</emphasis>, used for enabling a channel.
+        If and only if its attribute is non zero, then a triggered capture
+        will contain data samples for this channel.
+      </listitem>
+      <listitem><emphasis>type</emphasis>, description of the scan element
+        data storage within the buffer and hence the form in which it is
+        read from user space. Format is <emphasis>
+        [be|le]:[s|u]bits/storagebitsXrepeat[>>shift] </emphasis>.
+        <itemizedlist>
+        <listitem> <emphasis>be</emphasis> or <emphasis>le</emphasis>, specifies
+          big or little endian.
+        </listitem>
+        <listitem>
+        <emphasis>s </emphasis>or <emphasis>u</emphasis>, specifies if
+          signed (2's complement) or unsigned.
+        </listitem>
+        <listitem><emphasis>bits</emphasis>, is the number of valid data
+          bits.
+        </listitem>
+        <listitem><emphasis>storagebits</emphasis>, is the number of bits
+          (after padding) that it occupies in the buffer.
+        </listitem>
+        <listitem>
+        <emphasis>shift</emphasis>, if specified, is the shift that needs
+          to be applied prior to masking out unused bits.
+        </listitem>
+        <listitem>
+        <emphasis>repeat</emphasis>, specifies the number of bits/storagebits
+        repetitions. When the repeat element is 0 or 1, then the repeat
+        value is omitted.
+        </listitem>
+        </itemizedlist>
+      </listitem>
+      </itemizedlist>
+      For example, a driver for a 3-axis accelerometer with 12 bit
+      resolution where data is stored in two 8-bits registers as
+      follows:
+      <programlisting>
+        7   6   5   4   3   2   1   0
+      +---+---+---+---+---+---+---+---+
+      |D3 |D2 |D1 |D0 | X | X | X | X | (LOW byte, address 0x06)
+      +---+---+---+---+---+---+---+---+
+
+        7   6   5   4   3   2   1   0
+      +---+---+---+---+---+---+---+---+
+      |D11|D10|D9 |D8 |D7 |D6 |D5 |D4 | (HIGH byte, address 0x07)
+      +---+---+---+---+---+---+---+---+
+      </programlisting>
+
+      will have the following scan element type for each axis:
+      <programlisting>
+      $ cat /sys/bus/iio/devices/iio:device0/scan_elements/in_accel_y_type
+      le:s12/16>>4
+      </programlisting>
+      A user space application will interpret data samples read from the
+      buffer as two byte little endian signed data, that needs a 4 bits
+      right shift before masking out the 12 valid bits of data.
+    </para>
+    <para>
+      For implementing buffer support a driver should initialize the following
+      fields in <type>iio_chan_spec</type> definition:
+      <programlisting>
+          struct iio_chan_spec {
+              /* other members */
+              int scan_index
+              struct {
+                  char sign;
+                  u8 realbits;
+                  u8 storagebits;
+                  u8 shift;
+                  u8 repeat;
+                  enum iio_endian endianness;
+              } scan_type;
+          };
+      </programlisting>
+      The driver implementing the accelerometer described above will
+      have the following channel definition:
+      <programlisting>
+      struct struct iio_chan_spec accel_channels[] = {
+          {
+            .type = IIO_ACCEL,
+            .modified = 1,
+            .channel2 = IIO_MOD_X,
+            /* other stuff here */
+            .scan_index = 0,
+            .scan_type = {
+              .sign = 's',
+              .realbits = 12,
+              .storgebits = 16,
+              .shift = 4,
+              .endianness = IIO_LE,
+            },
+        }
+        /* similar for Y (with channel2 = IIO_MOD_Y, scan_index = 1)
+         * and Z (with channel2 = IIO_MOD_Z, scan_index = 2) axis
+         */
+    }
+    </programlisting>
+    </para>
+    <para>
+    Here <emphasis> scan_index </emphasis> defines the order in which
+    the enabled channels are placed inside the buffer. Channels with a lower
+    scan_index will be placed before channels with a higher index. Each
+    channel needs to have a unique scan_index.
+    </para>
+    <para>
+    Setting scan_index to -1 can be used to indicate that the specific
+    channel does not support buffered capture. In this case no entries will
+    be created for the channel in the scan_elements directory.
+    </para>
+    </sect2>
+  </sect1>
+
+  <sect1 id="iiotrigger"> <title> Industrial I/O triggers  </title>
+!Finclude/linux/iio/trigger.h iio_trigger
+!Edrivers/iio/industrialio-trigger.c
+    <para>
+      In many situations it is useful for a driver to be able to
+      capture data based on some external event (trigger) as opposed
+      to periodically polling for data. An IIO trigger can be provided
+      by a device driver that also has an IIO device based on hardware
+      generated events (e.g. data ready or threshold exceeded) or
+      provided by a separate driver from an independent interrupt
+      source (e.g. GPIO line connected to some external system, timer
+      interrupt or user space writing a specific file in sysfs). A
+      trigger may initiate data capture for a number of sensors and
+      also it may be completely unrelated to the sensor itself.
+    </para>
+
+    <sect2 id="iiotrigsysfs"> <title> IIO trigger sysfs interface </title>
+      There are two locations in sysfs related to triggers:
+      <itemizedlist>
+        <listitem><filename>/sys/bus/iio/devices/triggerY</filename>,
+          this file is created once an IIO trigger is registered with
+          the IIO core and corresponds to trigger with index Y. Because
+          triggers can be very different depending on type there are few
+          standard attributes that we can describe here:
+          <itemizedlist>
+            <listitem>
+              <emphasis>name</emphasis>, trigger name that can be later
+                used for association with a device.
+            </listitem>
+            <listitem>
+            <emphasis>sampling_frequency</emphasis>, some timer based
+              triggers use this attribute to specify the frequency for
+              trigger calls.
+            </listitem>
+          </itemizedlist>
+        </listitem>
+        <listitem>
+          <filename>/sys/bus/iio/devices/iio:deviceX/trigger/</filename>, this
+          directory is created once the device supports a triggered
+          buffer. We can associate a trigger with our device by writing
+          the trigger's name in the <filename>current_trigger</filename> file.
+        </listitem>
+      </itemizedlist>
+    </sect2>
+
+    <sect2 id="iiotrigattr"> <title> IIO trigger setup</title>
+
+    <para>
+      Let's see a simple example of how to setup a trigger to be used
+      by a driver.
+
+      <programlisting>
+      struct iio_trigger_ops trigger_ops = {
+          .set_trigger_state = sample_trigger_state,
+          .validate_device = sample_validate_device,
+      }
+
+      struct iio_trigger *trig;
+
+      /* first, allocate memory for our trigger */
+      trig = iio_trigger_alloc(dev, "trig-%s-%d", name, idx);
+
+      /* setup trigger operations field */
+      trig->ops = &amp;trigger_ops;
+
+      /* now register the trigger with the IIO core */
+      iio_trigger_register(trig);
+      </programlisting>
+    </para>
+    </sect2>
+
+    <sect2 id="iiotrigsetup"> <title> IIO trigger ops</title>
+!Finclude/linux/iio/trigger.h iio_trigger_ops
+     <para>
+        Notice that a trigger has a set of operations attached:
+        <itemizedlist>
+        <listitem>
+          <function>set_trigger_state</function>, switch the trigger on/off
+          on demand.
+        </listitem>
+        <listitem>
+          <function>validate_device</function>, function to validate the
+          device when the current trigger gets changed.
+        </listitem>
+        </itemizedlist>
+      </para>
+    </sect2>
+  </sect1>
+  <sect1 id="iiotriggered_buffer">
+    <title> Industrial I/O triggered buffers </title>
+    <para>
+    Now that we know what buffers and triggers are let's see how they
+    work together.
+    </para>
+    <sect2 id="iiotrigbufsetup"> <title> IIO triggered buffer setup</title>
+!Edrivers/iio/industrialio-triggered-buffer.c
+!Finclude/linux/iio/iio.h iio_buffer_setup_ops
+
+
+    <para>
+    A typical triggered buffer setup looks like this:
+    <programlisting>
+    const struct iio_buffer_setup_ops sensor_buffer_setup_ops = {
+      .preenable    = sensor_buffer_preenable,
+      .postenable   = sensor_buffer_postenable,
+      .postdisable  = sensor_buffer_postdisable,
+      .predisable   = sensor_buffer_predisable,
+    };
+
+    irqreturn_t sensor_iio_pollfunc(int irq, void *p)
+    {
+        pf->timestamp = iio_get_time_ns();
+        return IRQ_WAKE_THREAD;
+    }
+
+    irqreturn_t sensor_trigger_handler(int irq, void *p)
+    {
+        u16 buf[8];
+        int i = 0;
+
+        /* read data for each active channel */
+        for_each_set_bit(bit, active_scan_mask, masklength)
+            buf[i++] = sensor_get_data(bit)
+
+        iio_push_to_buffers_with_timestamp(indio_dev, buf, timestamp);
+
+        iio_trigger_notify_done(trigger);
+        return IRQ_HANDLED;
+    }
+
+    /* setup triggered buffer, usually in probe function */
+    iio_triggered_buffer_setup(indio_dev, sensor_iio_polfunc,
+                               sensor_trigger_handler,
+                               sensor_buffer_setup_ops);
+    </programlisting>
+    </para>
+    The important things to notice here are:
+    <itemizedlist>
+    <listitem><function> iio_buffer_setup_ops</function>, the buffer setup
+    functions to be called at predefined points in the buffer configuration
+    sequence (e.g. before enable, after disable). If not specified, the
+    IIO core uses the default <type>iio_triggered_buffer_setup_ops</type>.
+    </listitem>
+    <listitem><function>sensor_iio_pollfunc</function>, the function that
+    will be used as top half of poll function. It should do as little
+    processing as possible, because it runs in interrupt context. The most
+    common operation is recording of the current timestamp and for this reason
+    one can use the IIO core defined <function>iio_pollfunc_store_time
+    </function> function.
+    </listitem>
+    <listitem><function>sensor_trigger_handler</function>, the function that
+    will be used as bottom half of the poll function. This runs in the
+    context of a kernel thread and all the processing takes place here.
+    It usually reads data from the device and stores it in the internal
+    buffer together with the timestamp recorded in the top half.
+    </listitem>
+    </itemizedlist>
+    </sect2>
+  </sect1>
+  </chapter>
+  <chapter id='iioresources'>
+    <title> Resources </title>
+      IIO core may change during time so the best documentation to read is the
+      source code. There are several locations where you should look:
+      <itemizedlist>
+        <listitem>
+          <filename>drivers/iio/</filename>, contains the IIO core plus
+          and directories for each sensor type (e.g. accel, magnetometer,
+          etc.)
+        </listitem>
+        <listitem>
+          <filename>include/linux/iio/</filename>, contains the header
+          files, nice to read for the internal kernel interfaces.
+        </listitem>
+        <listitem>
+        <filename>include/uapi/linux/iio/</filename>, contains files to be
+          used by user space applications.
+        </listitem>
+        <listitem>
+         <filename>tools/iio/</filename>, contains tools for rapidly
+          testing buffers, events and device creation.
+        </listitem>
+        <listitem>
+          <filename>drivers/staging/iio/</filename>, contains code for some
+          drivers or experimental features that are not yet mature enough
+          to be moved out.
+        </listitem>
+      </itemizedlist>
+    <para>
+    Besides the code, there are some good online documentation sources:
+    <itemizedlist>
+    <listitem>
+      <ulink url="http://marc.info/?l=linux-iio"> Industrial I/O mailing
+      list </ulink>
+    </listitem>
+    <listitem>
+      <ulink url="http://wiki.analog.com/software/linux/docs/iio/iio">
+      Analog Device IIO wiki page </ulink>
+    </listitem>
+    <listitem>
+      <ulink url="https://fosdem.org/2015/schedule/event/iiosdr/">
+      Using the Linux IIO framework for SDR, Lars-Peter Clausen's
+      presentation at FOSDEM </ulink>
+    </listitem>
+    </itemizedlist>
+    </para>
+  </chapter>
+</book>
+
+<!--
+vim: softtabstop=2:shiftwidth=2:expandtab:textwidth=72
+-->

+ 1 - 0
Documentation/devicetree/bindings/iio/adc/mcp320x.txt

@@ -18,6 +18,7 @@ Required properties:
 				"mcp3202"
 				"mcp3202"
 				"mcp3204"
 				"mcp3204"
 				"mcp3208"
 				"mcp3208"
+				"mcp3301"
 
 
 
 
 Examples:
 Examples:

+ 5 - 0
Documentation/devicetree/bindings/iio/adc/vf610-adc.txt

@@ -17,6 +17,11 @@ Recommended properties:
   - Frequency in normal mode (ADLPC=0, ADHSC=0)
   - Frequency in normal mode (ADLPC=0, ADHSC=0)
   - Frequency in high-speed mode (ADLPC=0, ADHSC=1)
   - Frequency in high-speed mode (ADLPC=0, ADHSC=1)
   - Frequency in low-power mode (ADLPC=1, ADHSC=0)
   - Frequency in low-power mode (ADLPC=1, ADHSC=0)
+- min-sample-time: Minimum sampling time in nanoseconds. This value has
+  to be chosen according to the conversion mode and the connected analog
+  source resistance (R_as) and capacitance (C_as). Refer the datasheet's
+  operating requirements. A safe default across a wide range of R_as and
+  C_as as well as conversion modes is 1000ns.
 
 
 Example:
 Example:
 adc0: adc@4003b000 {
 adc0: adc@4003b000 {

+ 13 - 0
Documentation/devicetree/bindings/iio/magnetometer/mmc35240.txt

@@ -0,0 +1,13 @@
+* MEMSIC MMC35240 magnetometer sensor
+
+Required properties:
+
+  - compatible : should be "memsic,mmc35240"
+  - reg : the I2C address of the magnetometer
+
+Example:
+
+mmc35240@30 {
+        compatible = "memsic,mmc35240";
+        reg = <0x30>;
+};

+ 2 - 0
Documentation/devicetree/bindings/iio/st-sensors.txt

@@ -35,6 +35,7 @@ Accelerometers:
 - st,lsm303dl-accel
 - st,lsm303dl-accel
 - st,lsm303dlm-accel
 - st,lsm303dlm-accel
 - st,lsm330-accel
 - st,lsm330-accel
+- st,lsm303agr-accel
 
 
 Gyroscopes:
 Gyroscopes:
 - st,l3g4200d-gyro
 - st,l3g4200d-gyro
@@ -46,6 +47,7 @@ Gyroscopes:
 - st,lsm330-gyro
 - st,lsm330-gyro
 
 
 Magnetometers:
 Magnetometers:
+- st,lsm303agr-magn
 - st,lsm303dlh-magn
 - st,lsm303dlh-magn
 - st,lsm303dlhc-magn
 - st,lsm303dlhc-magn
 - st,lsm303dlm-magn
 - st,lsm303dlm-magn

+ 1 - 1
Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt

@@ -1,4 +1,4 @@
-* Freescale i.MX28 LRADC device driver
+* Freescale MXS LRADC device driver
 
 
 Required properties:
 Required properties:
 - compatible: Should be "fsl,imx23-lradc" for i.MX23 SoC and "fsl,imx28-lradc"
 - compatible: Should be "fsl,imx23-lradc" for i.MX23 SoC and "fsl,imx28-lradc"

+ 31 - 0
Documentation/fb/sm712fb.txt

@@ -0,0 +1,31 @@
+What is sm712fb?
+=================
+
+This is a graphics framebuffer driver for Silicon Motion SM712 based processors.
+
+How to use it?
+==============
+
+Switching modes is done using the video=sm712fb:... boot parameter.
+
+If you want, for example, enable a resolution of 1280x1024x24bpp you should
+pass to the kernel this command line: "video=sm712fb:0x31B".
+
+You should not compile-in vesafb.
+
+Currently supported video modes are:
+
+[Graphic modes]
+
+bpp | 640x480  800x600  1024x768  1280x1024
+----+--------------------------------------------
+  8 | 0x301    0x303    0x305    0x307
+ 16 | 0x311    0x314    0x317    0x31A
+ 24 | 0x312    0x315    0x318    0x31B
+
+Missing Features
+================
+(alias TODO list)
+
+	* 2D acceleratrion
+	* dual-head support

+ 9 - 13
MAINTAINERS

@@ -9348,6 +9348,15 @@ S:	Maintained
 F:	drivers/media/i2c/ov2659.c
 F:	drivers/media/i2c/ov2659.c
 F:	include/media/ov2659.h
 F:	include/media/ov2659.h
 
 
+SILICON MOTION SM712 FRAME BUFFER DRIVER
+M:	Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+M:	Teddy Wang <teddy.wang@siliconmotion.com>
+M:	Sudip Mukherjee <sudip@vectorindia.org>
+L:	linux-fbdev@vger.kernel.org
+S:	Maintained
+F:	drivers/video/fbdev/sm712*
+F:	Documentation/fb/sm712fb.txt
+
 SIS 190 ETHERNET DRIVER
 SIS 190 ETHERNET DRIVER
 M:	Francois Romieu <romieu@fr.zoreil.com>
 M:	Francois Romieu <romieu@fr.zoreil.com>
 L:	netdev@vger.kernel.org
 L:	netdev@vger.kernel.org
@@ -9745,11 +9754,6 @@ W:	http://wiki.laptop.org/go/DCON
 S:	Maintained
 S:	Maintained
 F:	drivers/staging/olpc_dcon/
 F:	drivers/staging/olpc_dcon/
 
 
-STAGING - OZMO DEVICES USB OVER WIFI DRIVER
-M:	Shigekatsu Tateno <shigekatsu.tateno@atmel.com>
-S:	Maintained
-F:	drivers/staging/ozwpan/
-
 STAGING - PARALLEL LCD/KEYPAD PANEL DRIVER
 STAGING - PARALLEL LCD/KEYPAD PANEL DRIVER
 M:	Willy Tarreau <willy@meta-x.org>
 M:	Willy Tarreau <willy@meta-x.org>
 S:	Odd Fixes
 S:	Odd Fixes
@@ -9768,14 +9772,6 @@ L:	linux-wireless@vger.kernel.org
 S:	Maintained
 S:	Maintained
 F:	drivers/staging/rtl8723au/
 F:	drivers/staging/rtl8723au/
 
 
-STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER
-M:	Sudip Mukherjee <sudipm.mukherjee@gmail.com>
-M:	Teddy Wang <teddy.wang@siliconmotion.com>
-M:	Sudip Mukherjee <sudip@vectorindia.org>
-L:	linux-fbdev@vger.kernel.org
-S:	Maintained
-F:	drivers/staging/sm7xxfb/
-
 STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER
 STAGING - SILICON MOTION SM750 FRAME BUFFER DRIVER
 M:	Sudip Mukherjee <sudipm.mukherjee@gmail.com>
 M:	Sudip Mukherjee <sudipm.mukherjee@gmail.com>
 M:	Teddy Wang <teddy.wang@siliconmotion.com>
 M:	Teddy Wang <teddy.wang@siliconmotion.com>

+ 14 - 12
drivers/iio/accel/Kconfig

@@ -86,18 +86,6 @@ config KXSD9
 	  To compile this driver as a module, choose M here: the module
 	  To compile this driver as a module, choose M here: the module
 	  will be called kxsd9.
 	  will be called kxsd9.
 
 
-config MMA8452
-	tristate "Freescale MMA8452Q Accelerometer Driver"
-	depends on I2C
-	select IIO_BUFFER
-	select IIO_TRIGGERED_BUFFER
-	help
-	  Say yes here to build support for the Freescale MMA8452Q 3-axis
-	  accelerometer.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called mma8452.
-
 config KXCJK1013
 config KXCJK1013
 	tristate "Kionix 3-Axis Accelerometer Driver"
 	tristate "Kionix 3-Axis Accelerometer Driver"
 	depends on I2C
 	depends on I2C
@@ -111,6 +99,18 @@ config KXCJK1013
 	  To compile this driver as a module, choose M here: the module will
 	  To compile this driver as a module, choose M here: the module will
 	  be called kxcjk-1013.
 	  be called kxcjk-1013.
 
 
+config MMA8452
+	tristate "Freescale MMA8452Q Accelerometer Driver"
+	depends on I2C
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	  Say yes here to build support for the Freescale MMA8452Q 3-axis
+	  accelerometer.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called mma8452.
+
 config MMA9551_CORE
 config MMA9551_CORE
 	tristate
 	tristate
 
 
@@ -140,6 +140,8 @@ config MMA9553
 config STK8312
 config STK8312
 	tristate "Sensortek STK8312 3-Axis Accelerometer Driver"
 	tristate "Sensortek STK8312 3-Axis Accelerometer Driver"
 	depends on I2C
 	depends on I2C
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	help
 	  Say yes here to get support for the Sensortek STK8312 3-axis
 	  Say yes here to get support for the Sensortek STK8312 3-axis
 	  accelerometer.
 	  accelerometer.

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

@@ -846,7 +846,6 @@ MODULE_DEVICE_TABLE(i2c, bma180_ids);
 static struct i2c_driver bma180_driver = {
 static struct i2c_driver bma180_driver = {
 	.driver = {
 	.driver = {
 		.name	= "bma180",
 		.name	= "bma180",
-		.owner	= THIS_MODULE,
 		.pm	= BMA180_PM_OPS,
 		.pm	= BMA180_PM_OPS,
 	},
 	},
 	.probe		= bma180_probe,
 	.probe		= bma180_probe,

+ 121 - 122
drivers/iio/accel/bmc150-accel.c

@@ -151,6 +151,7 @@ struct bmc150_scale_info {
 };
 };
 
 
 struct bmc150_accel_chip_info {
 struct bmc150_accel_chip_info {
+	const char *name;
 	u8 chip_id;
 	u8 chip_id;
 	const struct iio_chan_spec *channels;
 	const struct iio_chan_spec *channels;
 	int num_channels;
 	int num_channels;
@@ -241,7 +242,6 @@ static const struct {
 				       {500000, BMC150_ACCEL_SLEEP_500_MS},
 				       {500000, BMC150_ACCEL_SLEEP_500_MS},
 				       {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
 				       {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
 
 
-
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 				 enum bmc150_power_modes mode,
 				 enum bmc150_power_modes mode,
 				 int dur_us)
 				 int dur_us)
@@ -259,8 +259,9 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 				dur_val =
 				dur_val =
 				bmc150_accel_sleep_value_table[i].reg_value;
 				bmc150_accel_sleep_value_table[i].reg_value;
 		}
 		}
-	} else
+	} else {
 		dur_val = 0;
 		dur_val = 0;
+	}
 
 
 	if (dur_val < 0)
 	if (dur_val < 0)
 		return -EINVAL;
 		return -EINVAL;
@@ -288,7 +289,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
 
 
 	for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
 	for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
 		if (bmc150_accel_samp_freq_table[i].val == val &&
 		if (bmc150_accel_samp_freq_table[i].val == val &&
-				bmc150_accel_samp_freq_table[i].val2 == val2) {
+		    bmc150_accel_samp_freq_table[i].val2 == val2) {
 			ret = i2c_smbus_write_byte_data(
 			ret = i2c_smbus_write_byte_data(
 				data->client,
 				data->client,
 				BMC150_ACCEL_REG_PMU_BW,
 				BMC150_ACCEL_REG_PMU_BW,
@@ -345,65 +346,6 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
 	return 0;
 	return 0;
 }
 }
 
 
-static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
-{
-	int ret;
-
-	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
-	if (ret < 0) {
-		dev_err(&data->client->dev,
-			"Error: Reading chip id\n");
-		return ret;
-	}
-
-	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
-	if (ret != data->chip_info->chip_id) {
-		dev_err(&data->client->dev, "Invalid chip %x\n", ret);
-		return -ENODEV;
-	}
-
-	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
-	if (ret < 0)
-		return ret;
-
-	/* Set Bandwidth */
-	ret = bmc150_accel_set_bw(data, BMC150_ACCEL_DEF_BW, 0);
-	if (ret < 0)
-		return ret;
-
-	/* Set Default Range */
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_PMU_RANGE,
-					BMC150_ACCEL_DEF_RANGE_4G);
-	if (ret < 0) {
-		dev_err(&data->client->dev,
-					"Error writing reg_pmu_range\n");
-		return ret;
-	}
-
-	data->range = BMC150_ACCEL_DEF_RANGE_4G;
-
-	/* Set default slope duration and thresholds */
-	data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD;
-	data->slope_dur = BMC150_ACCEL_DEF_SLOPE_DURATION;
-	ret = bmc150_accel_update_slope(data);
-	if (ret < 0)
-		return ret;
-
-	/* Set default as latched interrupts */
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_INT_RST_LATCH,
-					BMC150_ACCEL_INT_MODE_LATCH_INT |
-					BMC150_ACCEL_INT_MODE_LATCH_RESET);
-	if (ret < 0) {
-		dev_err(&data->client->dev,
-			"Error writing reg_int_rst_latch\n");
-		return ret;
-	}
-
-	return 0;
-}
-
 static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val,
 static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val,
 			       int *val2)
 			       int *val2)
 {
 {
@@ -437,12 +379,13 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
 {
 {
 	int ret;
 	int ret;
 
 
-	if (on)
+	if (on) {
 		ret = pm_runtime_get_sync(&data->client->dev);
 		ret = pm_runtime_get_sync(&data->client->dev);
-	else {
+	} else {
 		pm_runtime_mark_last_busy(&data->client->dev);
 		pm_runtime_mark_last_busy(&data->client->dev);
 		ret = pm_runtime_put_autosuspend(&data->client->dev);
 		ret = pm_runtime_put_autosuspend(&data->client->dev);
 	}
 	}
+
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 		dev_err(&data->client->dev,
 			"Failed: bmc150_accel_set_power_state for %d\n", on);
 			"Failed: bmc150_accel_set_power_state for %d\n", on);
@@ -514,13 +457,13 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
 	}
 	}
 
 
 	/*
 	/*
-	 * We will expect the enable and disable to do operation in
-	 * in reverse order. This will happen here anyway as our
-	 * resume operation uses sync mode runtime pm calls, the
-	 * suspend operation will be delayed by autosuspend delay
-	 * So the disable operation will still happen in reverse of
-	 * enable operation. When runtime pm is disabled the mode
-	 * is always on so sequence doesn't matter
+	 * We will expect the enable and disable to do operation in reverse
+	 * order. This will happen here anyway, as our resume operation uses
+	 * sync mode runtime pm calls. The suspend operation will be delayed
+	 * by autosuspend delay.
+	 * So the disable operation will still happen in reverse order of
+	 * enable operation. When runtime pm is disabled the mode is always on,
+	 * so sequence doesn't matter.
 	 */
 	 */
 	ret = bmc150_accel_set_power_state(data, state);
 	ret = bmc150_accel_set_power_state(data, state);
 	if (ret < 0)
 	if (ret < 0)
@@ -574,7 +517,6 @@ out_fix_power_state:
 	return ret;
 	return ret;
 }
 }
 
 
-
 static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
 static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
 {
 {
 	int ret, i;
 	int ret, i;
@@ -674,8 +616,9 @@ static int bmc150_accel_read_raw(struct iio_dev *indio_dev,
 		if (chan->type == IIO_TEMP) {
 		if (chan->type == IIO_TEMP) {
 			*val = BMC150_ACCEL_TEMP_CENTER_VAL;
 			*val = BMC150_ACCEL_TEMP_CENTER_VAL;
 			return IIO_VAL_INT;
 			return IIO_VAL_INT;
-		} else
+		} else {
 			return -EINVAL;
 			return -EINVAL;
+		}
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
 		*val = 0;
 		switch (chan->type) {
 		switch (chan->type) {
@@ -776,7 +719,7 @@ static int bmc150_accel_write_event(struct iio_dev *indio_dev,
 
 
 	switch (info) {
 	switch (info) {
 	case IIO_EV_INFO_VALUE:
 	case IIO_EV_INFO_VALUE:
-		data->slope_thres = val & 0xFF;
+		data->slope_thres = val & BMC150_ACCEL_SLOPE_THRES_MASK;
 		break;
 		break;
 	case IIO_EV_INFO_PERIOD:
 	case IIO_EV_INFO_PERIOD:
 		data->slope_dur = val & BMC150_ACCEL_SLOPE_DUR_MASK;
 		data->slope_dur = val & BMC150_ACCEL_SLOPE_DUR_MASK;
@@ -793,7 +736,6 @@ static int bmc150_accel_read_event_config(struct iio_dev *indio_dev,
 					  enum iio_event_type type,
 					  enum iio_event_type type,
 					  enum iio_event_direction dir)
 					  enum iio_event_direction dir)
 {
 {
-
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
 
 	return data->ev_enable_state;
 	return data->ev_enable_state;
@@ -827,7 +769,7 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev,
 }
 }
 
 
 static int bmc150_accel_validate_trigger(struct iio_dev *indio_dev,
 static int bmc150_accel_validate_trigger(struct iio_dev *indio_dev,
-				   struct iio_trigger *trig)
+					 struct iio_trigger *trig)
 {
 {
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 	int i;
 	int i;
@@ -963,6 +905,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
 	u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
 	u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
 	int64_t tstamp;
 	int64_t tstamp;
 	uint64_t sample_period;
 	uint64_t sample_period;
+
 	ret = i2c_smbus_read_byte_data(data->client,
 	ret = i2c_smbus_read_byte_data(data->client,
 				       BMC150_ACCEL_REG_FIFO_STATUS);
 				       BMC150_ACCEL_REG_FIFO_STATUS);
 	if (ret < 0) {
 	if (ret < 0) {
@@ -1120,6 +1063,7 @@ enum {
 
 
 static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 	[bmc150] = {
 	[bmc150] = {
+		.name = "BMC150A",
 		.chip_id = 0xFA,
 		.chip_id = 0xFA,
 		.channels = bmc150_accel_channels,
 		.channels = bmc150_accel_channels,
 		.num_channels = ARRAY_SIZE(bmc150_accel_channels),
 		.num_channels = ARRAY_SIZE(bmc150_accel_channels),
@@ -1129,6 +1073,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 				 {76590, BMC150_ACCEL_DEF_RANGE_16G} },
 				 {76590, BMC150_ACCEL_DEF_RANGE_16G} },
 	},
 	},
 	[bmi055] = {
 	[bmi055] = {
+		.name = "BMI055A",
 		.chip_id = 0xFA,
 		.chip_id = 0xFA,
 		.channels = bmc150_accel_channels,
 		.channels = bmc150_accel_channels,
 		.num_channels = ARRAY_SIZE(bmc150_accel_channels),
 		.num_channels = ARRAY_SIZE(bmc150_accel_channels),
@@ -1138,6 +1083,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 				 {76590, BMC150_ACCEL_DEF_RANGE_16G} },
 				 {76590, BMC150_ACCEL_DEF_RANGE_16G} },
 	},
 	},
 	[bma255] = {
 	[bma255] = {
+		.name = "BMA0255",
 		.chip_id = 0xFA,
 		.chip_id = 0xFA,
 		.channels = bmc150_accel_channels,
 		.channels = bmc150_accel_channels,
 		.num_channels = ARRAY_SIZE(bmc150_accel_channels),
 		.num_channels = ARRAY_SIZE(bmc150_accel_channels),
@@ -1147,6 +1093,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 				 {76590, BMC150_ACCEL_DEF_RANGE_16G} },
 				 {76590, BMC150_ACCEL_DEF_RANGE_16G} },
 	},
 	},
 	[bma250e] = {
 	[bma250e] = {
+		.name = "BMA250E",
 		.chip_id = 0xF9,
 		.chip_id = 0xF9,
 		.channels = bma250e_accel_channels,
 		.channels = bma250e_accel_channels,
 		.num_channels = ARRAY_SIZE(bma250e_accel_channels),
 		.num_channels = ARRAY_SIZE(bma250e_accel_channels),
@@ -1156,6 +1103,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 				 {306457, BMC150_ACCEL_DEF_RANGE_16G} },
 				 {306457, BMC150_ACCEL_DEF_RANGE_16G} },
 	},
 	},
 	[bma222e] = {
 	[bma222e] = {
+		.name = "BMA222E",
 		.chip_id = 0xF8,
 		.chip_id = 0xF8,
 		.channels = bma222e_accel_channels,
 		.channels = bma222e_accel_channels,
 		.num_channels = ARRAY_SIZE(bma222e_accel_channels),
 		.num_channels = ARRAY_SIZE(bma222e_accel_channels),
@@ -1165,6 +1113,7 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 				 {1225831, BMC150_ACCEL_DEF_RANGE_16G} },
 				 {1225831, BMC150_ACCEL_DEF_RANGE_16G} },
 	},
 	},
 	[bma280] = {
 	[bma280] = {
+		.name = "BMA0280",
 		.chip_id = 0xFB,
 		.chip_id = 0xFB,
 		.channels = bma280_accel_channels,
 		.channels = bma280_accel_channels,
 		.num_channels = ARRAY_SIZE(bma280_accel_channels),
 		.num_channels = ARRAY_SIZE(bma280_accel_channels),
@@ -1255,7 +1204,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
 }
 }
 
 
 static int bmc150_accel_trigger_set_state(struct iio_trigger *trig,
 static int bmc150_accel_trigger_set_state(struct iio_trigger *trig,
-						   bool state)
+					  bool state)
 {
 {
 	struct bmc150_accel_trigger *t = iio_trigger_get_drvdata(trig);
 	struct bmc150_accel_trigger *t = iio_trigger_get_drvdata(trig);
 	struct bmc150_accel_data *data = t->data;
 	struct bmc150_accel_data *data = t->data;
@@ -1314,26 +1263,32 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
 		dir = IIO_EV_DIR_RISING;
 		dir = IIO_EV_DIR_RISING;
 
 
 	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
 	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
-		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
-							0,
-							IIO_MOD_X,
-							IIO_EV_TYPE_ROC,
-							dir),
-							data->timestamp);
+		iio_push_event(indio_dev,
+			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+						  0,
+						  IIO_MOD_X,
+						  IIO_EV_TYPE_ROC,
+						  dir),
+			       data->timestamp);
+
 	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
 	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
-		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
-							0,
-							IIO_MOD_Y,
-							IIO_EV_TYPE_ROC,
-							dir),
-							data->timestamp);
+		iio_push_event(indio_dev,
+			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+						  0,
+						  IIO_MOD_Y,
+						  IIO_EV_TYPE_ROC,
+						  dir),
+			       data->timestamp);
+
 	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
 	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
-		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
-							0,
-							IIO_MOD_Z,
-							IIO_EV_TYPE_ROC,
-							dir),
-							data->timestamp);
+		iio_push_event(indio_dev,
+			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+						  0,
+						  IIO_MOD_Z,
+						  IIO_EV_TYPE_ROC,
+						  dir),
+			       data->timestamp);
+
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1365,7 +1320,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
 					BMC150_ACCEL_INT_MODE_LATCH_INT |
 					BMC150_ACCEL_INT_MODE_LATCH_INT |
 					BMC150_ACCEL_INT_MODE_LATCH_RESET);
 					BMC150_ACCEL_INT_MODE_LATCH_RESET);
 		if (ret)
 		if (ret)
-			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
+			dev_err(&data->client->dev,
+				"Error writing reg_int_rst_latch\n");
+
 		ret = IRQ_HANDLED;
 		ret = IRQ_HANDLED;
 	} else {
 	} else {
 		ret = IRQ_NONE;
 		ret = IRQ_NONE;
@@ -1403,22 +1360,8 @@ static irqreturn_t bmc150_accel_irq_handler(int irq, void *private)
 	return IRQ_NONE;
 	return IRQ_NONE;
 }
 }
 
 
-static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
-{
-	const struct acpi_device_id *id;
-
-	id = acpi_match_device(dev->driver->acpi_match_table, dev);
-
-	if (!id)
-		return NULL;
-
-	*data = (int) id->driver_data;
-
-	return dev_name(dev);
-}
-
 static int bmc150_accel_gpio_probe(struct i2c_client *client,
 static int bmc150_accel_gpio_probe(struct i2c_client *client,
-					struct bmc150_accel_data *data)
+				   struct bmc150_accel_data *data)
 {
 {
 	struct device *dev;
 	struct device *dev;
 	struct gpio_desc *gpio;
 	struct gpio_desc *gpio;
@@ -1611,6 +1554,70 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
 	.postdisable = bmc150_accel_buffer_postdisable,
 	.postdisable = bmc150_accel_buffer_postdisable,
 };
 };
 
 
+static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
+{
+	int ret, i;
+
+	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error: Reading chip id\n");
+		return ret;
+	}
+
+	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
+	for (i = 0; i < ARRAY_SIZE(bmc150_accel_chip_info_tbl); i++) {
+		if (bmc150_accel_chip_info_tbl[i].chip_id == ret) {
+			data->chip_info = &bmc150_accel_chip_info_tbl[i];
+			break;
+		}
+	}
+
+	if (!data->chip_info) {
+		dev_err(&data->client->dev, "Unsupported chip %x\n", ret);
+		return -ENODEV;
+	}
+
+	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
+	if (ret < 0)
+		return ret;
+
+	/* Set Bandwidth */
+	ret = bmc150_accel_set_bw(data, BMC150_ACCEL_DEF_BW, 0);
+	if (ret < 0)
+		return ret;
+
+	/* Set Default Range */
+	ret = i2c_smbus_write_byte_data(data->client,
+					BMC150_ACCEL_REG_PMU_RANGE,
+					BMC150_ACCEL_DEF_RANGE_4G);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_pmu_range\n");
+		return ret;
+	}
+
+	data->range = BMC150_ACCEL_DEF_RANGE_4G;
+
+	/* Set default slope duration and thresholds */
+	data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD;
+	data->slope_dur = BMC150_ACCEL_DEF_SLOPE_DURATION;
+	ret = bmc150_accel_update_slope(data);
+	if (ret < 0)
+		return ret;
+
+	/* Set default as latched interrupts */
+	ret = i2c_smbus_write_byte_data(data->client,
+					BMC150_ACCEL_REG_INT_RST_LATCH,
+					BMC150_ACCEL_INT_MODE_LATCH_INT |
+					BMC150_ACCEL_INT_MODE_LATCH_RESET);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"Error writing reg_int_rst_latch\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int bmc150_accel_probe(struct i2c_client *client,
 static int bmc150_accel_probe(struct i2c_client *client,
 			      const struct i2c_device_id *id)
 			      const struct i2c_device_id *id)
 {
 {
@@ -1618,7 +1625,6 @@ static int bmc150_accel_probe(struct i2c_client *client,
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int ret;
 	int ret;
 	const char *name = NULL;
 	const char *name = NULL;
-	int chip_id = 0;
 
 
 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 	if (!indio_dev)
 	if (!indio_dev)
@@ -1628,15 +1634,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, indio_dev);
 	i2c_set_clientdata(client, indio_dev);
 	data->client = client;
 	data->client = client;
 
 
-	if (id) {
+	if (id)
 		name = id->name;
 		name = id->name;
-		chip_id = id->driver_data;
-	}
-
-	if (ACPI_HANDLE(&client->dev))
-		name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
-
-	data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
 
 
 	ret = bmc150_accel_chip_init(data);
 	ret = bmc150_accel_chip_init(data);
 	if (ret < 0)
 	if (ret < 0)
@@ -1647,7 +1646,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->channels = data->chip_info->channels;
 	indio_dev->channels = data->chip_info->channels;
 	indio_dev->num_channels = data->chip_info->num_channels;
 	indio_dev->num_channels = data->chip_info->num_channels;
-	indio_dev->name = name;
+	indio_dev->name = name ? name : data->chip_info->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &bmc150_accel_info;
 	indio_dev->info = &bmc150_accel_info;
 
 
@@ -1663,7 +1662,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 	if (client->irq < 0)
 	if (client->irq < 0)
 		client->irq = bmc150_accel_gpio_probe(client, data);
 		client->irq = bmc150_accel_gpio_probe(client, data);
 
 
-	if (client->irq >= 0) {
+	if (client->irq > 0) {
 		ret = devm_request_threaded_irq(
 		ret = devm_request_threaded_irq(
 						&client->dev, client->irq,
 						&client->dev, client->irq,
 						bmc150_accel_irq_handler,
 						bmc150_accel_irq_handler,

+ 1 - 4
drivers/iio/accel/kxcjk-1013.c

@@ -658,10 +658,8 @@ static int kxcjk1013_set_scale(struct kxcjk1013_data *data, int val)
 	int ret, i;
 	int ret, i;
 	enum kxcjk1013_mode store_mode;
 	enum kxcjk1013_mode store_mode;
 
 
-
 	for (i = 0; i < ARRAY_SIZE(KXCJK1013_scale_table); ++i) {
 	for (i = 0; i < ARRAY_SIZE(KXCJK1013_scale_table); ++i) {
 		if (KXCJK1013_scale_table[i].scale == val) {
 		if (KXCJK1013_scale_table[i].scale == val) {
-
 			ret = kxcjk1013_get_mode(data, &store_mode);
 			ret = kxcjk1013_get_mode(data, &store_mode);
 			if (ret < 0)
 			if (ret < 0)
 				return ret;
 				return ret;
@@ -820,7 +818,6 @@ static int kxcjk1013_read_event_config(struct iio_dev *indio_dev,
 					  enum iio_event_type type,
 					  enum iio_event_type type,
 					  enum iio_event_direction dir)
 					  enum iio_event_direction dir)
 {
 {
-
 	struct kxcjk1013_data *data = iio_priv(indio_dev);
 	struct kxcjk1013_data *data = iio_priv(indio_dev);
 
 
 	return data->ev_enable_state;
 	return data->ev_enable_state;
@@ -1243,7 +1240,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
 	if (client->irq < 0)
 	if (client->irq < 0)
 		client->irq = kxcjk1013_gpio_probe(client, data);
 		client->irq = kxcjk1013_gpio_probe(client, data);
 
 
-	if (client->irq >= 0) {
+	if (client->irq > 0) {
 		ret = devm_request_threaded_irq(&client->dev, client->irq,
 		ret = devm_request_threaded_irq(&client->dev, client->irq,
 						kxcjk1013_data_rdy_trig_poll,
 						kxcjk1013_data_rdy_trig_poll,
 						kxcjk1013_event_handler,
 						kxcjk1013_event_handler,

+ 123 - 94
drivers/iio/accel/mma8452.c

@@ -16,7 +16,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/sysfs.h>
-#include <linux/iio/trigger_consumer.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/trigger_consumer.h>
@@ -24,54 +23,51 @@
 #include <linux/iio/events.h>
 #include <linux/iio/events.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 
 
-#define MMA8452_STATUS 0x00
-#define MMA8452_OUT_X 0x01 /* MSB first, 12-bit  */
-#define MMA8452_OUT_Y 0x03
-#define MMA8452_OUT_Z 0x05
-#define MMA8452_INT_SRC 0x0c
-#define MMA8452_WHO_AM_I 0x0d
-#define MMA8452_DATA_CFG 0x0e
-#define MMA8452_HP_FILTER_CUTOFF 0x0f
-#define MMA8452_HP_FILTER_CUTOFF_SEL_MASK	(BIT(0) | BIT(1))
-#define MMA8452_TRANSIENT_CFG 0x1d
-#define MMA8452_TRANSIENT_CFG_ELE		BIT(4)
-#define MMA8452_TRANSIENT_CFG_CHAN(chan)	BIT(chan + 1)
-#define MMA8452_TRANSIENT_CFG_HPF_BYP		BIT(0)
-#define MMA8452_TRANSIENT_SRC 0x1e
-#define MMA8452_TRANSIENT_SRC_XTRANSE		BIT(1)
-#define MMA8452_TRANSIENT_SRC_YTRANSE		BIT(3)
-#define MMA8452_TRANSIENT_SRC_ZTRANSE		BIT(5)
-#define MMA8452_TRANSIENT_THS 0x1f
-#define MMA8452_TRANSIENT_THS_MASK	0x7f
-#define MMA8452_TRANSIENT_COUNT 0x20
-#define MMA8452_OFF_X 0x2f
-#define MMA8452_OFF_Y 0x30
-#define MMA8452_OFF_Z 0x31
-#define MMA8452_CTRL_REG1 0x2a
-#define MMA8452_CTRL_REG2 0x2b
-#define MMA8452_CTRL_REG2_RST		BIT(6)
-#define MMA8452_CTRL_REG4 0x2d
-#define MMA8452_CTRL_REG5 0x2e
-
-#define MMA8452_MAX_REG 0x31
-
-#define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0))
-
-#define MMA8452_CTRL_DR_MASK (BIT(5) | BIT(4) | BIT(3))
-#define MMA8452_CTRL_DR_SHIFT 3
-#define MMA8452_CTRL_DR_DEFAULT 0x4 /* 50 Hz sample frequency */
-#define MMA8452_CTRL_ACTIVE BIT(0)
-
-#define MMA8452_DATA_CFG_FS_MASK (BIT(1) | BIT(0))
-#define MMA8452_DATA_CFG_FS_2G 0
-#define MMA8452_DATA_CFG_FS_4G 1
-#define MMA8452_DATA_CFG_FS_8G 2
-#define MMA8452_DATA_CFG_HPF_MASK BIT(4)
-
-#define MMA8452_INT_DRDY	BIT(0)
-#define MMA8452_INT_TRANS	BIT(5)
-
-#define MMA8452_DEVICE_ID 0x2a
+#define MMA8452_STATUS				0x00
+#define  MMA8452_STATUS_DRDY			(BIT(2) | BIT(1) | BIT(0))
+#define MMA8452_OUT_X				0x01 /* MSB first, 12-bit  */
+#define MMA8452_OUT_Y				0x03
+#define MMA8452_OUT_Z				0x05
+#define MMA8452_INT_SRC				0x0c
+#define MMA8452_WHO_AM_I			0x0d
+#define MMA8452_DATA_CFG			0x0e
+#define  MMA8452_DATA_CFG_FS_MASK		GENMASK(1, 0)
+#define  MMA8452_DATA_CFG_FS_2G			0
+#define  MMA8452_DATA_CFG_FS_4G			1
+#define  MMA8452_DATA_CFG_FS_8G			2
+#define  MMA8452_DATA_CFG_HPF_MASK		BIT(4)
+#define MMA8452_HP_FILTER_CUTOFF		0x0f
+#define  MMA8452_HP_FILTER_CUTOFF_SEL_MASK	GENMASK(1, 0)
+#define MMA8452_TRANSIENT_CFG			0x1d
+#define  MMA8452_TRANSIENT_CFG_HPF_BYP		BIT(0)
+#define  MMA8452_TRANSIENT_CFG_CHAN(chan)	BIT(chan + 1)
+#define  MMA8452_TRANSIENT_CFG_ELE		BIT(4)
+#define MMA8452_TRANSIENT_SRC			0x1e
+#define  MMA8452_TRANSIENT_SRC_XTRANSE		BIT(1)
+#define  MMA8452_TRANSIENT_SRC_YTRANSE		BIT(3)
+#define  MMA8452_TRANSIENT_SRC_ZTRANSE		BIT(5)
+#define MMA8452_TRANSIENT_THS			0x1f
+#define  MMA8452_TRANSIENT_THS_MASK		GENMASK(6, 0)
+#define MMA8452_TRANSIENT_COUNT			0x20
+#define MMA8452_CTRL_REG1			0x2a
+#define  MMA8452_CTRL_ACTIVE			BIT(0)
+#define  MMA8452_CTRL_DR_MASK			GENMASK(5, 3)
+#define  MMA8452_CTRL_DR_SHIFT			3
+#define  MMA8452_CTRL_DR_DEFAULT		0x4 /* 50 Hz sample frequency */
+#define MMA8452_CTRL_REG2			0x2b
+#define  MMA8452_CTRL_REG2_RST			BIT(6)
+#define MMA8452_CTRL_REG4			0x2d
+#define MMA8452_CTRL_REG5			0x2e
+#define MMA8452_OFF_X				0x2f
+#define MMA8452_OFF_Y				0x30
+#define MMA8452_OFF_Z				0x31
+
+#define MMA8452_MAX_REG				0x31
+
+#define  MMA8452_INT_DRDY			BIT(0)
+#define  MMA8452_INT_TRANS			BIT(5)
+
+#define  MMA8452_DEVICE_ID			0x2a
 
 
 struct mma8452_data {
 struct mma8452_data {
 	struct i2c_client *client;
 	struct i2c_client *client;
@@ -91,30 +87,34 @@ static int mma8452_drdy(struct mma8452_data *data)
 			return ret;
 			return ret;
 		if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY)
 		if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY)
 			return 0;
 			return 0;
+
 		msleep(20);
 		msleep(20);
 	}
 	}
 
 
 	dev_err(&data->client->dev, "data not ready\n");
 	dev_err(&data->client->dev, "data not ready\n");
+
 	return -EIO;
 	return -EIO;
 }
 }
 
 
 static int mma8452_read(struct mma8452_data *data, __be16 buf[3])
 static int mma8452_read(struct mma8452_data *data, __be16 buf[3])
 {
 {
 	int ret = mma8452_drdy(data);
 	int ret = mma8452_drdy(data);
+
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
-	return i2c_smbus_read_i2c_block_data(data->client,
-		MMA8452_OUT_X, 3 * sizeof(__be16), (u8 *) buf);
+
+	return i2c_smbus_read_i2c_block_data(data->client, MMA8452_OUT_X,
+					     3 * sizeof(__be16), (u8 *)buf);
 }
 }
 
 
-static ssize_t mma8452_show_int_plus_micros(char *buf,
-	const int (*vals)[2], int n)
+static ssize_t mma8452_show_int_plus_micros(char *buf, const int (*vals)[2],
+					    int n)
 {
 {
 	size_t len = 0;
 	size_t len = 0;
 
 
 	while (n-- > 0)
 	while (n-- > 0)
-		len += scnprintf(buf + len, PAGE_SIZE - len,
-			"%d.%06d ", vals[n][0], vals[n][1]);
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
+				 vals[n][0], vals[n][1]);
 
 
 	/* replace trailing space by newline */
 	/* replace trailing space by newline */
 	buf[len - 1] = '\n';
 	buf[len - 1] = '\n';
@@ -123,7 +123,7 @@ static ssize_t mma8452_show_int_plus_micros(char *buf,
 }
 }
 
 
 static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n,
 static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n,
-					int val, int val2)
+					     int val, int val2)
 {
 {
 	while (n-- > 0)
 	while (n-- > 0)
 		if (val == vals[n][0] && val2 == vals[n][1])
 		if (val == vals[n][0] && val2 == vals[n][1])
@@ -147,7 +147,7 @@ static const int mma8452_samp_freq[8][2] = {
  * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048
  * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048
  * The userspace interface uses m/s^2 and we declare micro units
  * The userspace interface uses m/s^2 and we declare micro units
  * So scale factor is given by:
  * So scale factor is given by:
- * 	g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665
+ *	g * N * 1000000 / 2048 for N = 2, 4, 8 and g = 9.80665
  */
  */
 static const int mma8452_scales[3][2] = {
 static const int mma8452_scales[3][2] = {
 	{0, 9577}, {0, 19154}, {0, 38307}
 	{0, 9577}, {0, 19154}, {0, 38307}
@@ -178,17 +178,19 @@ static const int mma8452_hp_filter_cutoff[8][4][2] = {
 };
 };
 
 
 static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
 static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
-				struct device_attribute *attr, char *buf)
+					    struct device_attribute *attr,
+					    char *buf)
 {
 {
 	return mma8452_show_int_plus_micros(buf, mma8452_samp_freq,
 	return mma8452_show_int_plus_micros(buf, mma8452_samp_freq,
-		ARRAY_SIZE(mma8452_samp_freq));
+					    ARRAY_SIZE(mma8452_samp_freq));
 }
 }
 
 
 static ssize_t mma8452_show_scale_avail(struct device *dev,
 static ssize_t mma8452_show_scale_avail(struct device *dev,
-				struct device_attribute *attr, char *buf)
+					struct device_attribute *attr,
+					char *buf)
 {
 {
 	return mma8452_show_int_plus_micros(buf, mma8452_scales,
 	return mma8452_show_int_plus_micros(buf, mma8452_scales,
-		ARRAY_SIZE(mma8452_scales));
+					    ARRAY_SIZE(mma8452_scales));
 }
 }
 
 
 static ssize_t mma8452_show_hp_cutoff_avail(struct device *dev,
 static ssize_t mma8452_show_hp_cutoff_avail(struct device *dev,
@@ -205,22 +207,23 @@ static ssize_t mma8452_show_hp_cutoff_avail(struct device *dev,
 
 
 static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail);
 static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail);
 static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO,
 static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO,
-	mma8452_show_scale_avail, NULL, 0);
+		       mma8452_show_scale_avail, NULL, 0);
 static IIO_DEVICE_ATTR(in_accel_filter_high_pass_3db_frequency_available,
 static IIO_DEVICE_ATTR(in_accel_filter_high_pass_3db_frequency_available,
-			S_IRUGO, mma8452_show_hp_cutoff_avail, NULL, 0);
+		       S_IRUGO, mma8452_show_hp_cutoff_avail, NULL, 0);
 
 
 static int mma8452_get_samp_freq_index(struct mma8452_data *data,
 static int mma8452_get_samp_freq_index(struct mma8452_data *data,
-	int val, int val2)
+				       int val, int val2)
 {
 {
 	return mma8452_get_int_plus_micros_index(mma8452_samp_freq,
 	return mma8452_get_int_plus_micros_index(mma8452_samp_freq,
-		ARRAY_SIZE(mma8452_samp_freq), val, val2);
+						 ARRAY_SIZE(mma8452_samp_freq),
+						 val, val2);
 }
 }
 
 
-static int mma8452_get_scale_index(struct mma8452_data *data,
-	int val, int val2)
+static int mma8452_get_scale_index(struct mma8452_data *data, int val, int val2)
 {
 {
 	return mma8452_get_int_plus_micros_index(mma8452_scales,
 	return mma8452_get_int_plus_micros_index(mma8452_scales,
-		ARRAY_SIZE(mma8452_scales), val, val2);
+						 ARRAY_SIZE(mma8452_scales),
+						 val, val2);
 }
 }
 
 
 static int mma8452_get_hp_filter_index(struct mma8452_data *data,
 static int mma8452_get_hp_filter_index(struct mma8452_data *data,
@@ -229,7 +232,7 @@ static int mma8452_get_hp_filter_index(struct mma8452_data *data,
 	int i = mma8452_get_odr_index(data);
 	int i = mma8452_get_odr_index(data);
 
 
 	return mma8452_get_int_plus_micros_index(mma8452_hp_filter_cutoff[i],
 	return mma8452_get_int_plus_micros_index(mma8452_hp_filter_cutoff[i],
-		ARRAY_SIZE(mma8452_scales[0]), val, val2);
+		ARRAY_SIZE(mma8452_hp_filter_cutoff[0]), val, val2);
 }
 }
 
 
 static int mma8452_read_hp_filter(struct mma8452_data *data, int *hz, int *uHz)
 static int mma8452_read_hp_filter(struct mma8452_data *data, int *hz, int *uHz)
@@ -266,25 +269,31 @@ static int mma8452_read_raw(struct iio_dev *indio_dev,
 		mutex_unlock(&data->lock);
 		mutex_unlock(&data->lock);
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			return ret;
-		*val = sign_extend32(
-			be16_to_cpu(buffer[chan->scan_index]) >> 4, 11);
+
+		*val = sign_extend32(be16_to_cpu(buffer[chan->scan_index]) >> 4,
+				     11);
+
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_SCALE:
 		i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
 		i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
 		*val = mma8452_scales[i][0];
 		*val = mma8452_scales[i][0];
 		*val2 = mma8452_scales[i][1];
 		*val2 = mma8452_scales[i][1];
+
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
 	case IIO_CHAN_INFO_SAMP_FREQ:
 	case IIO_CHAN_INFO_SAMP_FREQ:
 		i = mma8452_get_odr_index(data);
 		i = mma8452_get_odr_index(data);
 		*val = mma8452_samp_freq[i][0];
 		*val = mma8452_samp_freq[i][0];
 		*val2 = mma8452_samp_freq[i][1];
 		*val2 = mma8452_samp_freq[i][1];
+
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
 	case IIO_CHAN_INFO_CALIBBIAS:
 	case IIO_CHAN_INFO_CALIBBIAS:
-		ret = i2c_smbus_read_byte_data(data->client, MMA8452_OFF_X +
-			chan->scan_index);
+		ret = i2c_smbus_read_byte_data(data->client,
+					      MMA8452_OFF_X + chan->scan_index);
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			return ret;
+
 		*val = sign_extend32(ret, 7);
 		*val = sign_extend32(ret, 7);
+
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
 	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
 		if (data->data_cfg & MMA8452_DATA_CFG_HPF_MASK) {
 		if (data->data_cfg & MMA8452_DATA_CFG_HPF_MASK) {
@@ -295,21 +304,23 @@ static int mma8452_read_raw(struct iio_dev *indio_dev,
 			*val = 0;
 			*val = 0;
 			*val2 = 0;
 			*val2 = 0;
 		}
 		}
+
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
 	}
 	}
+
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
 static int mma8452_standby(struct mma8452_data *data)
 static int mma8452_standby(struct mma8452_data *data)
 {
 {
 	return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
 	return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
-		data->ctrl_reg1 & ~MMA8452_CTRL_ACTIVE);
+					data->ctrl_reg1 & ~MMA8452_CTRL_ACTIVE);
 }
 }
 
 
 static int mma8452_active(struct mma8452_data *data)
 static int mma8452_active(struct mma8452_data *data)
 {
 {
 	return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
 	return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
-		data->ctrl_reg1);
+					 data->ctrl_reg1);
 }
 }
 
 
 static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
 static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
@@ -334,6 +345,7 @@ static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
 	ret = 0;
 	ret = 0;
 fail:
 fail:
 	mutex_unlock(&data->lock);
 	mutex_unlock(&data->lock);
+
 	return ret;
 	return ret;
 }
 }
 
 
@@ -344,12 +356,13 @@ static int mma8452_set_hp_filter_frequency(struct mma8452_data *data,
 
 
 	i = mma8452_get_hp_filter_index(data, val, val2);
 	i = mma8452_get_hp_filter_index(data, val, val2);
 	if (i < 0)
 	if (i < 0)
-		return -EINVAL;
+		return i;
 
 
 	reg = i2c_smbus_read_byte_data(data->client,
 	reg = i2c_smbus_read_byte_data(data->client,
 				       MMA8452_HP_FILTER_CUTOFF);
 				       MMA8452_HP_FILTER_CUTOFF);
 	if (reg < 0)
 	if (reg < 0)
 		return reg;
 		return reg;
+
 	reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
 	reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
 	reg |= i;
 	reg |= i;
 
 
@@ -370,25 +383,30 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_SAMP_FREQ:
 	case IIO_CHAN_INFO_SAMP_FREQ:
 		i = mma8452_get_samp_freq_index(data, val, val2);
 		i = mma8452_get_samp_freq_index(data, val, val2);
 		if (i < 0)
 		if (i < 0)
-			return -EINVAL;
+			return i;
 
 
 		data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
 		data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
 		data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;
 		data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;
+
 		return mma8452_change_config(data, MMA8452_CTRL_REG1,
 		return mma8452_change_config(data, MMA8452_CTRL_REG1,
-			data->ctrl_reg1);
+					     data->ctrl_reg1);
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_SCALE:
 		i = mma8452_get_scale_index(data, val, val2);
 		i = mma8452_get_scale_index(data, val, val2);
 		if (i < 0)
 		if (i < 0)
-			return -EINVAL;
+			return i;
+
 		data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK;
 		data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK;
 		data->data_cfg |= i;
 		data->data_cfg |= i;
+
 		return mma8452_change_config(data, MMA8452_DATA_CFG,
 		return mma8452_change_config(data, MMA8452_DATA_CFG,
-			data->data_cfg);
+					     data->data_cfg);
 	case IIO_CHAN_INFO_CALIBBIAS:
 	case IIO_CHAN_INFO_CALIBBIAS:
 		if (val < -128 || val > 127)
 		if (val < -128 || val > 127)
 			return -EINVAL;
 			return -EINVAL;
-		return mma8452_change_config(data, MMA8452_OFF_X +
-			chan->scan_index, val);
+
+		return mma8452_change_config(data,
+					     MMA8452_OFF_X + chan->scan_index,
+					     val);
 
 
 	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
 	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
 		if (val == 0 && val2 == 0) {
 		if (val == 0 && val2 == 0) {
@@ -399,8 +417,9 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
 			if (ret < 0)
 			if (ret < 0)
 				return ret;
 				return ret;
 		}
 		}
+
 		return mma8452_change_config(data, MMA8452_DATA_CFG,
 		return mma8452_change_config(data, MMA8452_DATA_CFG,
-						data->data_cfg);
+					     data->data_cfg);
 
 
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
@@ -425,6 +444,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev,
 			return ret;
 			return ret;
 
 
 		*val = ret & MMA8452_TRANSIENT_THS_MASK;
 		*val = ret & MMA8452_TRANSIENT_THS_MASK;
+
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 
 
 	case IIO_EV_INFO_PERIOD:
 	case IIO_EV_INFO_PERIOD:
@@ -437,6 +457,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev,
 				mma8452_get_odr_index(data)];
 				mma8452_get_odr_index(data)];
 		*val = us / USEC_PER_SEC;
 		*val = us / USEC_PER_SEC;
 		*val2 = us % USEC_PER_SEC;
 		*val2 = us % USEC_PER_SEC;
+
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
 
 
 	case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
 	case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
@@ -453,6 +474,7 @@ static int mma8452_read_thresh(struct iio_dev *indio_dev,
 			if (ret < 0)
 			if (ret < 0)
 				return ret;
 				return ret;
 		}
 		}
+
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
 
 
 	default:
 	default:
@@ -472,19 +494,22 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev,
 
 
 	switch (info) {
 	switch (info) {
 	case IIO_EV_INFO_VALUE:
 	case IIO_EV_INFO_VALUE:
-		return mma8452_change_config(data, MMA8452_TRANSIENT_THS,
-					     val & MMA8452_TRANSIENT_THS_MASK);
+		if (val < 0 || val > MMA8452_TRANSIENT_THS_MASK)
+			return -EINVAL;
+
+		return mma8452_change_config(data, MMA8452_TRANSIENT_THS, val);
 
 
 	case IIO_EV_INFO_PERIOD:
 	case IIO_EV_INFO_PERIOD:
 		steps = (val * USEC_PER_SEC + val2) /
 		steps = (val * USEC_PER_SEC + val2) /
 				mma8452_transient_time_step_us[
 				mma8452_transient_time_step_us[
 					mma8452_get_odr_index(data)];
 					mma8452_get_odr_index(data)];
 
 
-		if (steps > 0xff)
+		if (steps < 0 || steps > 0xff)
 			return -EINVAL;
 			return -EINVAL;
 
 
 		return mma8452_change_config(data, MMA8452_TRANSIENT_COUNT,
 		return mma8452_change_config(data, MMA8452_TRANSIENT_COUNT,
 					     steps);
 					     steps);
+
 	case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
 	case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
 		reg = i2c_smbus_read_byte_data(data->client,
 		reg = i2c_smbus_read_byte_data(data->client,
 					       MMA8452_TRANSIENT_CFG);
 					       MMA8452_TRANSIENT_CFG);
@@ -499,6 +524,7 @@ static int mma8452_write_thresh(struct iio_dev *indio_dev,
 			if (ret < 0)
 			if (ret < 0)
 				return ret;
 				return ret;
 		}
 		}
+
 		return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, reg);
 		return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, reg);
 
 
 	default:
 	default:
@@ -608,15 +634,16 @@ static irqreturn_t mma8452_trigger_handler(int irq, void *p)
 	u8 buffer[16]; /* 3 16-bit channels + padding + ts */
 	u8 buffer[16]; /* 3 16-bit channels + padding + ts */
 	int ret;
 	int ret;
 
 
-	ret = mma8452_read(data, (__be16 *) buffer);
+	ret = mma8452_read(data, (__be16 *)buffer);
 	if (ret < 0)
 	if (ret < 0)
 		goto done;
 		goto done;
 
 
 	iio_push_to_buffers_with_timestamp(indio_dev, buffer,
 	iio_push_to_buffers_with_timestamp(indio_dev, buffer,
-		iio_get_time_ns());
+					   iio_get_time_ns());
 
 
 done:
 done:
 	iio_trigger_notify_done(indio_dev->trig);
 	iio_trigger_notify_done(indio_dev->trig);
+
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
@@ -674,10 +701,10 @@ static struct attribute_group mma8452_event_attribute_group = {
 	.modified = 1, \
 	.modified = 1, \
 	.channel2 = IIO_MOD_##axis, \
 	.channel2 = IIO_MOD_##axis, \
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
-		BIT(IIO_CHAN_INFO_CALIBBIAS), \
+			      BIT(IIO_CHAN_INFO_CALIBBIAS), \
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
-		BIT(IIO_CHAN_INFO_SCALE) | \
-		BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \
+			BIT(IIO_CHAN_INFO_SCALE) | \
+			BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \
 	.scan_index = idx, \
 	.scan_index = idx, \
 	.scan_type = { \
 	.scan_type = { \
 		.sign = 's', \
 		.sign = 's', \
@@ -780,6 +807,7 @@ static int mma8452_trigger_setup(struct iio_dev *indio_dev)
 		return ret;
 		return ret;
 
 
 	indio_dev->trig = trig;
 	indio_dev->trig = trig;
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -849,7 +877,7 @@ static int mma8452_probe(struct i2c_client *client,
 
 
 	data->data_cfg = MMA8452_DATA_CFG_FS_2G;
 	data->data_cfg = MMA8452_DATA_CFG_FS_2G;
 	ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG,
 	ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG,
-		data->data_cfg);
+					data->data_cfg);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -891,14 +919,14 @@ static int mma8452_probe(struct i2c_client *client,
 	}
 	}
 
 
 	data->ctrl_reg1 = MMA8452_CTRL_ACTIVE |
 	data->ctrl_reg1 = MMA8452_CTRL_ACTIVE |
-		(MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT);
+			  (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT);
 	ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1,
 	ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1,
 					data->ctrl_reg1);
 					data->ctrl_reg1);
 	if (ret < 0)
 	if (ret < 0)
 		goto trigger_cleanup;
 		goto trigger_cleanup;
 
 
 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
-		mma8452_trigger_handler, NULL);
+					 mma8452_trigger_handler, NULL);
 	if (ret < 0)
 	if (ret < 0)
 		goto trigger_cleanup;
 		goto trigger_cleanup;
 
 
@@ -968,6 +996,7 @@ static const struct of_device_id mma8452_dt_ids[] = {
 	{ .compatible = "fsl,mma8452" },
 	{ .compatible = "fsl,mma8452" },
 	{ }
 	{ }
 };
 };
+MODULE_DEVICE_TABLE(of, mma8452_dt_ids);
 
 
 static struct i2c_driver mma8452_driver = {
 static struct i2c_driver mma8452_driver = {
 	.driver = {
 	.driver = {

+ 16 - 19
drivers/iio/accel/mma9551_core.c

@@ -297,7 +297,7 @@ EXPORT_SYMBOL(mma9551_read_status_byte);
  * Returns: 0 on success, negative value on failure.
  * Returns: 0 on success, negative value on failure.
  */
  */
 int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
 int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
-			    u16 reg, u16 *val)
+			     u16 reg, u16 *val)
 {
 {
 	int ret;
 	int ret;
 	__be16 v;
 	__be16 v;
@@ -328,12 +328,12 @@ EXPORT_SYMBOL(mma9551_read_config_word);
  * Returns: 0 on success, negative value on failure.
  * Returns: 0 on success, negative value on failure.
  */
  */
 int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
 int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
-			     u16 reg, u16 val)
+			      u16 reg, u16 val)
 {
 {
 	__be16 v = cpu_to_be16(val);
 	__be16 v = cpu_to_be16(val);
 
 
 	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
 	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
-				(u8 *) &v, 2, NULL, 0);
+				(u8 *)&v, 2, NULL, 0);
 }
 }
 EXPORT_SYMBOL(mma9551_write_config_word);
 EXPORT_SYMBOL(mma9551_write_config_word);
 
 
@@ -373,7 +373,7 @@ EXPORT_SYMBOL(mma9551_read_status_word);
  * @client:	I2C client
  * @client:	I2C client
  * @app_id:	Application ID
  * @app_id:	Application ID
  * @reg:	Application register
  * @reg:	Application register
- * @len:	Length of array to read in bytes
+ * @len:	Length of array to read (in words)
  * @buf:	Array of words to read
  * @buf:	Array of words to read
  *
  *
  * Read multiple configuration registers (word-sized registers).
  * Read multiple configuration registers (word-sized registers).
@@ -385,23 +385,22 @@ EXPORT_SYMBOL(mma9551_read_status_word);
  * Returns: 0 on success, negative value on failure.
  * Returns: 0 on success, negative value on failure.
  */
  */
 int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
 int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
-			     u16 reg, u8 len, u16 *buf)
+			      u16 reg, u8 len, u16 *buf)
 {
 {
 	int ret, i;
 	int ret, i;
-	int len_words = len / sizeof(u16);
 	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
 	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
 
 
-	if (len_words > ARRAY_SIZE(be_buf)) {
+	if (len > ARRAY_SIZE(be_buf)) {
 		dev_err(&client->dev, "Invalid buffer size %d\n", len);
 		dev_err(&client->dev, "Invalid buffer size %d\n", len);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
-			       reg, NULL, 0, (u8 *) be_buf, len);
+			       reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
-	for (i = 0; i < len_words; i++)
+	for (i = 0; i < len; i++)
 		buf[i] = be16_to_cpu(be_buf[i]);
 		buf[i] = be16_to_cpu(be_buf[i]);
 
 
 	return 0;
 	return 0;
@@ -413,7 +412,7 @@ EXPORT_SYMBOL(mma9551_read_config_words);
  * @client:	I2C client
  * @client:	I2C client
  * @app_id:	Application ID
  * @app_id:	Application ID
  * @reg:	Application register
  * @reg:	Application register
- * @len:	Length of array to read in bytes
+ * @len:	Length of array to read (in words)
  * @buf:	Array of words to read
  * @buf:	Array of words to read
  *
  *
  * Read multiple status registers (word-sized registers).
  * Read multiple status registers (word-sized registers).
@@ -428,20 +427,19 @@ int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
 			      u16 reg, u8 len, u16 *buf)
 			      u16 reg, u8 len, u16 *buf)
 {
 {
 	int ret, i;
 	int ret, i;
-	int len_words = len / sizeof(u16);
 	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
 	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
 
 
-	if (len_words > ARRAY_SIZE(be_buf)) {
+	if (len > ARRAY_SIZE(be_buf)) {
 		dev_err(&client->dev, "Invalid buffer size %d\n", len);
 		dev_err(&client->dev, "Invalid buffer size %d\n", len);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
-			       reg, NULL, 0, (u8 *) be_buf, len);
+			       reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
-	for (i = 0; i < len_words; i++)
+	for (i = 0; i < len; i++)
 		buf[i] = be16_to_cpu(be_buf[i]);
 		buf[i] = be16_to_cpu(be_buf[i]);
 
 
 	return 0;
 	return 0;
@@ -453,7 +451,7 @@ EXPORT_SYMBOL(mma9551_read_status_words);
  * @client:	I2C client
  * @client:	I2C client
  * @app_id:	Application ID
  * @app_id:	Application ID
  * @reg:	Application register
  * @reg:	Application register
- * @len:	Length of array to write in bytes
+ * @len:	Length of array to write (in words)
  * @buf:	Array of words to write
  * @buf:	Array of words to write
  *
  *
  * Write multiple configuration registers (word-sized registers).
  * Write multiple configuration registers (word-sized registers).
@@ -468,19 +466,18 @@ int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
 			       u16 reg, u8 len, u16 *buf)
 			       u16 reg, u8 len, u16 *buf)
 {
 {
 	int i;
 	int i;
-	int len_words = len / sizeof(u16);
 	__be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];
 	__be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];
 
 
-	if (len_words > ARRAY_SIZE(be_buf)) {
+	if (len > ARRAY_SIZE(be_buf)) {
 		dev_err(&client->dev, "Invalid buffer size %d\n", len);
 		dev_err(&client->dev, "Invalid buffer size %d\n", len);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	for (i = 0; i < len_words; i++)
+	for (i = 0; i < len; i++)
 		be_buf[i] = cpu_to_be16(buf[i]);
 		be_buf[i] = cpu_to_be16(buf[i]);
 
 
 	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
 	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
-				reg, (u8 *) be_buf, len, NULL, 0);
+				reg, (u8 *)be_buf, len * sizeof(u16), NULL, 0);
 }
 }
 EXPORT_SYMBOL(mma9551_write_config_words);
 EXPORT_SYMBOL(mma9551_write_config_words);
 
 

+ 3 - 3
drivers/iio/accel/mma9551_core.h

@@ -53,13 +53,13 @@ int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
 int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
 int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
 			     u16 reg, u8 *val);
 			     u16 reg, u8 *val);
 int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
 int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
-			    u16 reg, u16 *val);
+			     u16 reg, u16 *val);
 int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
 int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
-			     u16 reg, u16 val);
+			      u16 reg, u16 val);
 int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
 int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
 			     u16 reg, u16 *val);
 			     u16 reg, u16 *val);
 int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
 int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
-			     u16 reg, u8 len, u16 *buf);
+			      u16 reg, u8 len, u16 *buf);
 int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
 int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
 			      u16 reg, u8 len, u16 *buf);
 			      u16 reg, u8 len, u16 *buf);
 int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
 int mma9551_write_config_words(struct i2c_client *client, u8 app_id,

+ 43 - 40
drivers/iio/accel/mma9553.c

@@ -182,6 +182,10 @@ struct mma9553_conf_regs {
 
 
 struct mma9553_data {
 struct mma9553_data {
 	struct i2c_client *client;
 	struct i2c_client *client;
+	/*
+	 * 1. Serialize access to HW (requested by mma9551_core API).
+	 * 2. Serialize sequences that power on/off the device and access HW.
+	 */
 	struct mutex mutex;
 	struct mutex mutex;
 	struct mma9553_conf_regs conf;
 	struct mma9553_conf_regs conf;
 	struct mma9553_event events[MMA9553_EVENTS_INFO_SIZE];
 	struct mma9553_event events[MMA9553_EVENTS_INFO_SIZE];
@@ -322,7 +326,8 @@ static int mma9553_read_activity_stepcnt(struct mma9553_data *data,
 	int ret;
 	int ret;
 
 
 	ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER,
 	ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER,
-					MMA9553_REG_STATUS, sizeof(u32), buf);
+					MMA9553_REG_STATUS, ARRAY_SIZE(buf),
+					buf);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 		dev_err(&data->client->dev,
 			"error reading status and stepcnt\n");
 			"error reading status and stepcnt\n");
@@ -342,10 +347,10 @@ static int mma9553_conf_gpio(struct mma9553_data *data)
 	struct mma9553_event *ev_step_detect;
 	struct mma9553_event *ev_step_detect;
 	bool activity_enabled;
 	bool activity_enabled;
 
 
-	activity_enabled =
-	    mma9553_is_any_event_enabled(data, true, IIO_ACTIVITY);
-	ev_step_detect =
-	    mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE);
+	activity_enabled = mma9553_is_any_event_enabled(data, true,
+							IIO_ACTIVITY);
+	ev_step_detect = mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD,
+					   IIO_EV_DIR_NONE);
 
 
 	/*
 	/*
 	 * If both step detector and activity are enabled, use the MRGFL bit.
 	 * If both step detector and activity are enabled, use the MRGFL bit.
@@ -371,9 +376,8 @@ static int mma9553_conf_gpio(struct mma9553_data *data)
 			return ret;
 			return ret;
 	}
 	}
 
 
-	ret = mma9551_gpio_config(data->client,
-				  MMA9553_DEFAULT_GPIO_PIN,
-				  appid, bitnum, MMA9553_DEFAULT_GPIO_POLARITY);
+	ret = mma9551_gpio_config(data->client, MMA9553_DEFAULT_GPIO_PIN, appid,
+				  bitnum, MMA9553_DEFAULT_GPIO_POLARITY);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	data->gpio_bitnum = bitnum;
 	data->gpio_bitnum = bitnum;
@@ -394,17 +398,16 @@ static int mma9553_init(struct mma9553_data *data)
 	 * a device identification command to differentiate the MMA9553L
 	 * a device identification command to differentiate the MMA9553L
 	 * from the MMA9550L.
 	 * from the MMA9550L.
 	 */
 	 */
-	ret =
-	    mma9551_read_config_words(data->client, MMA9551_APPID_PEDOMETER,
-				      MMA9553_REG_CONF_SLEEPMIN,
-				      sizeof(data->conf), (u16 *) &data->conf);
+	ret = mma9551_read_config_words(data->client, MMA9551_APPID_PEDOMETER,
+					MMA9553_REG_CONF_SLEEPMIN,
+					sizeof(data->conf) / sizeof(u16),
+					(u16 *)&data->conf);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 		dev_err(&data->client->dev,
 			"failed to read configuration registers\n");
 			"failed to read configuration registers\n");
 		return ret;
 		return ret;
 	}
 	}
 
 
-
 	/* Reset GPIO */
 	/* Reset GPIO */
 	data->gpio_bitnum = MMA9553_MAX_BITNUM;
 	data->gpio_bitnum = MMA9553_MAX_BITNUM;
 	ret = mma9553_conf_gpio(data);
 	ret = mma9553_conf_gpio(data);
@@ -419,18 +422,18 @@ static int mma9553_init(struct mma9553_data *data)
 	data->conf.sleepmin = MMA9553_DEFAULT_SLEEPMIN;
 	data->conf.sleepmin = MMA9553_DEFAULT_SLEEPMIN;
 	data->conf.sleepmax = MMA9553_DEFAULT_SLEEPMAX;
 	data->conf.sleepmax = MMA9553_DEFAULT_SLEEPMAX;
 	data->conf.sleepthd = MMA9553_DEFAULT_SLEEPTHD;
 	data->conf.sleepthd = MMA9553_DEFAULT_SLEEPTHD;
-	data->conf.config =
-	    mma9553_set_bits(data->conf.config, 1, MMA9553_MASK_CONF_CONFIG);
+	data->conf.config = mma9553_set_bits(data->conf.config, 1,
+					     MMA9553_MASK_CONF_CONFIG);
 	/*
 	/*
 	 * Clear the activity debounce counter when the activity level changes,
 	 * Clear the activity debounce counter when the activity level changes,
 	 * so that the confidence level applies for any activity level.
 	 * so that the confidence level applies for any activity level.
 	 */
 	 */
 	data->conf.config = mma9553_set_bits(data->conf.config, 1,
 	data->conf.config = mma9553_set_bits(data->conf.config, 1,
 					     MMA9553_MASK_CONF_ACT_DBCNTM);
 					     MMA9553_MASK_CONF_ACT_DBCNTM);
-	ret =
-	    mma9551_write_config_words(data->client, MMA9551_APPID_PEDOMETER,
-				       MMA9553_REG_CONF_SLEEPMIN,
-				       sizeof(data->conf), (u16 *) &data->conf);
+	ret = mma9551_write_config_words(data->client, MMA9551_APPID_PEDOMETER,
+					 MMA9553_REG_CONF_SLEEPMIN,
+					 sizeof(data->conf) / sizeof(u16),
+					 (u16 *)&data->conf);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 		dev_err(&data->client->dev,
 			"failed to write configuration registers\n");
 			"failed to write configuration registers\n");
@@ -567,7 +570,7 @@ static int mma9553_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBHEIGHT:
 	case IIO_CHAN_INFO_CALIBHEIGHT:
 		tmp = mma9553_get_bits(data->conf.height_weight,
 		tmp = mma9553_get_bits(data->conf.height_weight,
-					MMA9553_MASK_CONF_HEIGHT);
+				       MMA9553_MASK_CONF_HEIGHT);
 		*val = tmp / 100;	/* cm to m */
 		*val = tmp / 100;	/* cm to m */
 		*val2 = (tmp % 100) * 10000;
 		*val2 = (tmp % 100) * 10000;
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
@@ -719,7 +722,6 @@ static int mma9553_read_event_config(struct iio_dev *indio_dev,
 				     enum iio_event_type type,
 				     enum iio_event_type type,
 				     enum iio_event_direction dir)
 				     enum iio_event_direction dir)
 {
 {
-
 	struct mma9553_data *data = iio_priv(indio_dev);
 	struct mma9553_data *data = iio_priv(indio_dev);
 	struct mma9553_event *event;
 	struct mma9553_event *event;
 
 
@@ -1026,22 +1028,22 @@ static irqreturn_t mma9553_event_handler(int irq, void *private)
 		return IRQ_HANDLED;
 		return IRQ_HANDLED;
 	}
 	}
 
 
-	ev_prev_activity =
-	    mma9553_get_event(data, IIO_ACTIVITY,
-			      mma9553_activity_to_mod(data->activity),
-			      IIO_EV_DIR_FALLING);
-	ev_activity =
-	    mma9553_get_event(data, IIO_ACTIVITY,
-			      mma9553_activity_to_mod(activity),
-			      IIO_EV_DIR_RISING);
-	ev_step_detect =
-	    mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE);
+	ev_prev_activity = mma9553_get_event(data, IIO_ACTIVITY,
+					     mma9553_activity_to_mod(
+					     data->activity),
+					     IIO_EV_DIR_FALLING);
+	ev_activity = mma9553_get_event(data, IIO_ACTIVITY,
+					mma9553_activity_to_mod(activity),
+					IIO_EV_DIR_RISING);
+	ev_step_detect = mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD,
+					   IIO_EV_DIR_NONE);
 
 
 	if (ev_step_detect->enabled && (stepcnt != data->stepcnt)) {
 	if (ev_step_detect->enabled && (stepcnt != data->stepcnt)) {
 		data->stepcnt = stepcnt;
 		data->stepcnt = stepcnt;
 		iio_push_event(indio_dev,
 		iio_push_event(indio_dev,
 			       IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
 			       IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
-			       IIO_EV_DIR_NONE, IIO_EV_TYPE_CHANGE, 0, 0, 0),
+					      IIO_EV_DIR_NONE,
+					      IIO_EV_TYPE_CHANGE, 0, 0, 0),
 			       data->timestamp);
 			       data->timestamp);
 	}
 	}
 
 
@@ -1051,17 +1053,19 @@ static irqreturn_t mma9553_event_handler(int irq, void *private)
 		if (ev_prev_activity && ev_prev_activity->enabled)
 		if (ev_prev_activity && ev_prev_activity->enabled)
 			iio_push_event(indio_dev,
 			iio_push_event(indio_dev,
 				       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
 				       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
-				       ev_prev_activity->info->mod,
-				       IIO_EV_DIR_FALLING,
-				       IIO_EV_TYPE_THRESH, 0, 0, 0),
+						    ev_prev_activity->info->mod,
+						    IIO_EV_DIR_FALLING,
+						    IIO_EV_TYPE_THRESH, 0, 0,
+						    0),
 				       data->timestamp);
 				       data->timestamp);
 
 
 		if (ev_activity && ev_activity->enabled)
 		if (ev_activity && ev_activity->enabled)
 			iio_push_event(indio_dev,
 			iio_push_event(indio_dev,
 				       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
 				       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
-				       ev_activity->info->mod,
-				       IIO_EV_DIR_RISING,
-				       IIO_EV_TYPE_THRESH, 0, 0, 0),
+						      ev_activity->info->mod,
+						      IIO_EV_DIR_RISING,
+						      IIO_EV_TYPE_THRESH, 0, 0,
+						      0),
 				       data->timestamp);
 				       data->timestamp);
 	}
 	}
 	mutex_unlock(&data->mutex);
 	mutex_unlock(&data->mutex);
@@ -1145,7 +1149,7 @@ static int mma9553_probe(struct i2c_client *client,
 	if (client->irq < 0)
 	if (client->irq < 0)
 		client->irq = mma9553_gpio_probe(client);
 		client->irq = mma9553_gpio_probe(client);
 
 
-	if (client->irq >= 0) {
+	if (client->irq > 0) {
 		ret = devm_request_threaded_irq(&client->dev, client->irq,
 		ret = devm_request_threaded_irq(&client->dev, client->irq,
 						mma9553_irq_handler,
 						mma9553_irq_handler,
 						mma9553_event_handler,
 						mma9553_event_handler,
@@ -1156,7 +1160,6 @@ static int mma9553_probe(struct i2c_client *client,
 				client->irq);
 				client->irq);
 			goto out_poweroff;
 			goto out_poweroff;
 		}
 		}
-
 	}
 	}
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);

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

@@ -26,6 +26,7 @@
 #define LSM303DLH_ACCEL_DEV_NAME	"lsm303dlh_accel"
 #define LSM303DLH_ACCEL_DEV_NAME	"lsm303dlh_accel"
 #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"
+#define LSM303AGR_ACCEL_DEV_NAME	"lsm303agr_accel"
 
 
 /**
 /**
 * struct st_sensors_platform_data - default accel platform data
 * struct st_sensors_platform_data - default accel platform data

+ 6 - 0
drivers/iio/accel/st_accel_core.c

@@ -226,12 +226,14 @@ static const struct iio_chan_spec st_accel_16bit_channels[] = {
 static const struct st_sensor_settings st_accel_sensors_settings[] = {
 static const struct st_sensor_settings st_accel_sensors_settings[] = {
 	{
 	{
 		.wai = ST_ACCEL_1_WAI_EXP,
 		.wai = ST_ACCEL_1_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LIS3DH_ACCEL_DEV_NAME,
 			[0] = LIS3DH_ACCEL_DEV_NAME,
 			[1] = LSM303DLHC_ACCEL_DEV_NAME,
 			[1] = LSM303DLHC_ACCEL_DEV_NAME,
 			[2] = LSM330D_ACCEL_DEV_NAME,
 			[2] = LSM330D_ACCEL_DEV_NAME,
 			[3] = LSM330DL_ACCEL_DEV_NAME,
 			[3] = LSM330DL_ACCEL_DEV_NAME,
 			[4] = LSM330DLC_ACCEL_DEV_NAME,
 			[4] = LSM330DLC_ACCEL_DEV_NAME,
+			[5] = LSM303AGR_ACCEL_DEV_NAME,
 		},
 		},
 		.ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 		.ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 		.odr = {
 		.odr = {
@@ -297,6 +299,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_ACCEL_2_WAI_EXP,
 		.wai = ST_ACCEL_2_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LIS331DLH_ACCEL_DEV_NAME,
 			[0] = LIS331DLH_ACCEL_DEV_NAME,
 			[1] = LSM303DL_ACCEL_DEV_NAME,
 			[1] = LSM303DL_ACCEL_DEV_NAME,
@@ -359,6 +362,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_ACCEL_3_WAI_EXP,
 		.wai = ST_ACCEL_3_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LSM330_ACCEL_DEV_NAME,
 			[0] = LSM330_ACCEL_DEV_NAME,
 		},
 		},
@@ -437,6 +441,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_ACCEL_4_WAI_EXP,
 		.wai = ST_ACCEL_4_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LIS3LV02DL_ACCEL_DEV_NAME,
 			[0] = LIS3LV02DL_ACCEL_DEV_NAME,
 		},
 		},
@@ -494,6 +499,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_ACCEL_5_WAI_EXP,
 		.wai = ST_ACCEL_5_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LIS331DL_ACCEL_DEV_NAME,
 			[0] = LIS331DL_ACCEL_DEV_NAME,
 		},
 		},

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

@@ -68,6 +68,10 @@ static const struct of_device_id st_accel_of_match[] = {
 		.compatible = "st,lsm330-accel",
 		.compatible = "st,lsm330-accel",
 		.data = LSM330_ACCEL_DEV_NAME,
 		.data = LSM330_ACCEL_DEV_NAME,
 	},
 	},
+	{
+		.compatible = "st,lsm303agr-accel",
+		.data = LSM303AGR_ACCEL_DEV_NAME,
+	},
 	{},
 	{},
 };
 };
 MODULE_DEVICE_TABLE(of, st_accel_of_match);
 MODULE_DEVICE_TABLE(of, st_accel_of_match);
@@ -116,13 +120,13 @@ static const struct i2c_device_id st_accel_id_table[] = {
 	{ LSM303DL_ACCEL_DEV_NAME },
 	{ LSM303DL_ACCEL_DEV_NAME },
 	{ LSM303DLM_ACCEL_DEV_NAME },
 	{ LSM303DLM_ACCEL_DEV_NAME },
 	{ LSM330_ACCEL_DEV_NAME },
 	{ LSM330_ACCEL_DEV_NAME },
+	{ LSM303AGR_ACCEL_DEV_NAME },
 	{},
 	{},
 };
 };
 MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
 MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
 
 
 static struct i2c_driver st_accel_driver = {
 static struct i2c_driver st_accel_driver = {
 	.driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name = "st-accel-i2c",
 		.name = "st-accel-i2c",
 		.of_match_table = of_match_ptr(st_accel_of_match),
 		.of_match_table = of_match_ptr(st_accel_of_match),
 	},
 	},

+ 1 - 0
drivers/iio/accel/st_accel_spi.c

@@ -57,6 +57,7 @@ static const struct spi_device_id st_accel_id_table[] = {
 	{ LSM303DL_ACCEL_DEV_NAME },
 	{ LSM303DL_ACCEL_DEV_NAME },
 	{ LSM303DLM_ACCEL_DEV_NAME },
 	{ LSM303DLM_ACCEL_DEV_NAME },
 	{ LSM330_ACCEL_DEV_NAME },
 	{ LSM330_ACCEL_DEV_NAME },
+	{ LSM303AGR_ACCEL_DEV_NAME },
 	{},
 	{},
 };
 };
 MODULE_DEVICE_TABLE(spi, st_accel_id_table);
 MODULE_DEVICE_TABLE(spi, st_accel_id_table);

+ 371 - 58
drivers/iio/accel/stk8312.c

@@ -11,17 +11,25 @@
  */
  */
 
 
 #include <linux/acpi.h>
 #include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
+#include <linux/iio/buffer.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
 
 
 #define STK8312_REG_XOUT		0x00
 #define STK8312_REG_XOUT		0x00
 #define STK8312_REG_YOUT		0x01
 #define STK8312_REG_YOUT		0x01
 #define STK8312_REG_ZOUT		0x02
 #define STK8312_REG_ZOUT		0x02
+#define STK8312_REG_INTSU		0x06
 #define STK8312_REG_MODE		0x07
 #define STK8312_REG_MODE		0x07
+#define STK8312_REG_SR			0x08
 #define STK8312_REG_STH			0x13
 #define STK8312_REG_STH			0x13
 #define STK8312_REG_RESET		0x20
 #define STK8312_REG_RESET		0x20
 #define STK8312_REG_AFECTRL		0x24
 #define STK8312_REG_AFECTRL		0x24
@@ -29,14 +37,21 @@
 #define STK8312_REG_OTPDATA		0x3E
 #define STK8312_REG_OTPDATA		0x3E
 #define STK8312_REG_OTPCTRL		0x3F
 #define STK8312_REG_OTPCTRL		0x3F
 
 
-#define STK8312_MODE_ACTIVE		1
-#define STK8312_MODE_STANDBY		0
-#define STK8312_MODE_MASK		0x01
-#define STK8312_RNG_MASK		0xC0
+#define STK8312_MODE_ACTIVE		BIT(0)
+#define STK8312_MODE_STANDBY		0x00
+#define STK8312_MODE_INT_AH_PP		0xC0	/* active-high, push-pull */
+#define STK8312_DREADY_BIT		BIT(4)
+#define STK8312_RNG_6G			1
 #define STK8312_RNG_SHIFT		6
 #define STK8312_RNG_SHIFT		6
-#define STK8312_READ_RETRIES		16
+#define STK8312_RNG_MASK		GENMASK(7, 6)
+#define STK8312_SR_MASK			GENMASK(2, 0)
+#define STK8312_SR_400HZ_IDX		0
+#define STK8312_ALL_CHANNEL_MASK	GENMASK(2, 0)
+#define STK8312_ALL_CHANNEL_SIZE	3
 
 
 #define STK8312_DRIVER_NAME		"stk8312"
 #define STK8312_DRIVER_NAME		"stk8312"
+#define STK8312_GPIO			"stk8312_gpio"
+#define STK8312_IRQ_NAME		"stk8312_event"
 
 
 /*
 /*
  * The accelerometer has two measurement ranges:
  * The accelerometer has two measurement ranges:
@@ -53,32 +68,56 @@ static const int stk8312_scale_table[][2] = {
 	{0, 461600}, {1, 231100}
 	{0, 461600}, {1, 231100}
 };
 };
 
 
-#define STK8312_ACCEL_CHANNEL(reg, axis) {			\
-	.type = IIO_ACCEL,					\
-	.address = reg,						\
-	.modified = 1,						\
-	.channel2 = IIO_MOD_##axis,				\
-	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
-	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
+static const struct {
+	int val;
+	int val2;
+} stk8312_samp_freq_table[] = {
+	{400, 0}, {200, 0}, {100, 0}, {50, 0}, {25, 0},
+	{12, 500000}, {6, 250000}, {3, 125000}
+};
+
+#define STK8312_ACCEL_CHANNEL(index, reg, axis) {			\
+	.type = IIO_ACCEL,						\
+	.address = reg,							\
+	.modified = 1,							\
+	.channel2 = IIO_MOD_##axis,					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |		\
+				    BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
+	.scan_index = index,						\
+	.scan_type = {							\
+		.sign = 's',						\
+		.realbits = 8,						\
+		.storagebits = 8,					\
+		.endianness = IIO_CPU,					\
+	},								\
 }
 }
 
 
 static const struct iio_chan_spec stk8312_channels[] = {
 static const struct iio_chan_spec stk8312_channels[] = {
-	STK8312_ACCEL_CHANNEL(STK8312_REG_XOUT, X),
-	STK8312_ACCEL_CHANNEL(STK8312_REG_YOUT, Y),
-	STK8312_ACCEL_CHANNEL(STK8312_REG_ZOUT, Z),
+	STK8312_ACCEL_CHANNEL(0, STK8312_REG_XOUT, X),
+	STK8312_ACCEL_CHANNEL(1, STK8312_REG_YOUT, Y),
+	STK8312_ACCEL_CHANNEL(2, STK8312_REG_ZOUT, Z),
+	IIO_CHAN_SOFT_TIMESTAMP(3),
 };
 };
 
 
 struct stk8312_data {
 struct stk8312_data {
 	struct i2c_client *client;
 	struct i2c_client *client;
 	struct mutex lock;
 	struct mutex lock;
-	int range;
+	u8 range;
+	u8 sample_rate_idx;
 	u8 mode;
 	u8 mode;
+	struct iio_trigger *dready_trig;
+	bool dready_trigger_on;
+	s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 64-bit timestamp */
 };
 };
 
 
 static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL);
 static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL);
 
 
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("3.125 6.25 12.5 25 50 100 200 400");
+
 static struct attribute *stk8312_attributes[] = {
 static struct attribute *stk8312_attributes[] = {
 	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
 	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	NULL,
 	NULL,
 };
 };
 
 
@@ -105,22 +144,25 @@ static int stk8312_otp_init(struct stk8312_data *data)
 		if (ret < 0)
 		if (ret < 0)
 			goto exit_err;
 			goto exit_err;
 		count--;
 		count--;
-	} while (!(ret & 0x80) && count > 0);
+	} while (!(ret & BIT(7)) && count > 0);
 
 
-	if (count == 0)
+	if (count == 0) {
+		ret = -ETIMEDOUT;
 		goto exit_err;
 		goto exit_err;
+	}
 
 
 	ret = i2c_smbus_read_byte_data(client, STK8312_REG_OTPDATA);
 	ret = i2c_smbus_read_byte_data(client, STK8312_REG_OTPDATA);
+	if (ret == 0)
+		ret = -EINVAL;
 	if (ret < 0)
 	if (ret < 0)
 		goto exit_err;
 		goto exit_err;
 
 
-	ret = i2c_smbus_write_byte_data(data->client,
-			STK8312_REG_AFECTRL, ret);
+	ret = i2c_smbus_write_byte_data(data->client, STK8312_REG_AFECTRL, ret);
 	if (ret < 0)
 	if (ret < 0)
 		goto exit_err;
 		goto exit_err;
 	msleep(150);
 	msleep(150);
 
 
-	return ret;
+	return 0;
 
 
 exit_err:
 exit_err:
 	dev_err(&client->dev, "failed to initialize sensor\n");
 	dev_err(&client->dev, "failed to initialize sensor\n");
@@ -130,31 +172,19 @@ exit_err:
 static int stk8312_set_mode(struct stk8312_data *data, u8 mode)
 static int stk8312_set_mode(struct stk8312_data *data, u8 mode)
 {
 {
 	int ret;
 	int ret;
-	u8 masked_reg;
 	struct i2c_client *client = data->client;
 	struct i2c_client *client = data->client;
 
 
-	if (mode > 1)
-		return -EINVAL;
-	else if (mode == data->mode)
+	if (mode == data->mode)
 		return 0;
 		return 0;
 
 
-	ret = i2c_smbus_read_byte_data(client, STK8312_REG_MODE);
-	if (ret < 0) {
-		dev_err(&client->dev, "failed to change sensor mode\n");
-		return ret;
-	}
-	masked_reg = ret & (~STK8312_MODE_MASK);
-	masked_reg |= mode;
-
-	ret = i2c_smbus_write_byte_data(client,
-			STK8312_REG_MODE, masked_reg);
+	ret = i2c_smbus_write_byte_data(client, STK8312_REG_MODE, mode);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&client->dev, "failed to change sensor mode\n");
 		dev_err(&client->dev, "failed to change sensor mode\n");
 		return ret;
 		return ret;
 	}
 	}
 
 
 	data->mode = mode;
 	data->mode = mode;
-	if (mode == STK8312_MODE_ACTIVE) {
+	if (mode & STK8312_MODE_ACTIVE) {
 		/* Need to run OTP sequence before entering active mode */
 		/* Need to run OTP sequence before entering active mode */
 		usleep_range(1000, 5000);
 		usleep_range(1000, 5000);
 		ret = stk8312_otp_init(data);
 		ret = stk8312_otp_init(data);
@@ -163,6 +193,92 @@ static int stk8312_set_mode(struct stk8312_data *data, u8 mode)
 	return ret;
 	return ret;
 }
 }
 
 
+static int stk8312_set_interrupts(struct stk8312_data *data, u8 int_mask)
+{
+	int ret;
+	u8 mode;
+	struct i2c_client *client = data->client;
+
+	mode = data->mode;
+	/* We need to go in standby mode to modify registers */
+	ret = stk8312_set_mode(data, STK8312_MODE_STANDBY);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_smbus_write_byte_data(client, STK8312_REG_INTSU, int_mask);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to set interrupts\n");
+		stk8312_set_mode(data, mode);
+		return ret;
+	}
+
+	return stk8312_set_mode(data, mode);
+}
+
+static int stk8312_data_rdy_trigger_set_state(struct iio_trigger *trig,
+					      bool state)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct stk8312_data *data = iio_priv(indio_dev);
+	int ret;
+
+	if (state)
+		ret = stk8312_set_interrupts(data, STK8312_DREADY_BIT);
+	else
+		ret = stk8312_set_interrupts(data, 0x00);
+
+	if (ret < 0) {
+		dev_err(&data->client->dev, "failed to set trigger state\n");
+		return ret;
+	}
+
+	data->dready_trigger_on = state;
+
+	return 0;
+}
+
+static const struct iio_trigger_ops stk8312_trigger_ops = {
+	.set_trigger_state = stk8312_data_rdy_trigger_set_state,
+	.owner = THIS_MODULE,
+};
+
+static int stk8312_set_sample_rate(struct stk8312_data *data, u8 rate)
+{
+	int ret;
+	u8 masked_reg;
+	u8 mode;
+	struct i2c_client *client = data->client;
+
+	if (rate == data->sample_rate_idx)
+		return 0;
+
+	mode = data->mode;
+	/* We need to go in standby mode to modify registers */
+	ret = stk8312_set_mode(data, STK8312_MODE_STANDBY);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_smbus_read_byte_data(client, STK8312_REG_SR);
+	if (ret < 0)
+		goto err_activate;
+
+	masked_reg = (ret & (~STK8312_SR_MASK)) | rate;
+
+	ret = i2c_smbus_write_byte_data(client, STK8312_REG_SR, masked_reg);
+	if (ret < 0)
+		goto err_activate;
+
+	data->sample_rate_idx = rate;
+
+	return stk8312_set_mode(data, mode);
+
+err_activate:
+	dev_err(&client->dev, "failed to set sampling rate\n");
+	stk8312_set_mode(data, mode);
+
+	return ret;
+}
+
 static int stk8312_set_range(struct stk8312_data *data, u8 range)
 static int stk8312_set_range(struct stk8312_data *data, u8 range)
 {
 {
 	int ret;
 	int ret;
@@ -182,21 +298,25 @@ static int stk8312_set_range(struct stk8312_data *data, u8 range)
 		return ret;
 		return ret;
 
 
 	ret = i2c_smbus_read_byte_data(client, STK8312_REG_STH);
 	ret = i2c_smbus_read_byte_data(client, STK8312_REG_STH);
-	if (ret < 0) {
-		dev_err(&client->dev, "failed to change sensor range\n");
-		return ret;
-	}
+	if (ret < 0)
+		goto err_activate;
 
 
 	masked_reg = ret & (~STK8312_RNG_MASK);
 	masked_reg = ret & (~STK8312_RNG_MASK);
 	masked_reg |= range << STK8312_RNG_SHIFT;
 	masked_reg |= range << STK8312_RNG_SHIFT;
 
 
 	ret = i2c_smbus_write_byte_data(client, STK8312_REG_STH, masked_reg);
 	ret = i2c_smbus_write_byte_data(client, STK8312_REG_STH, masked_reg);
 	if (ret < 0)
 	if (ret < 0)
-		dev_err(&client->dev, "failed to change sensor range\n");
-	else
-		data->range = range;
+		goto err_activate;
+
+	data->range = range;
 
 
 	return stk8312_set_mode(data, mode);
 	return stk8312_set_mode(data, mode);
+
+err_activate:
+	dev_err(&client->dev, "failed to change sensor range\n");
+	stk8312_set_mode(data, mode);
+
+	return ret;
 }
 }
 
 
 static int stk8312_read_accel(struct stk8312_data *data, u8 address)
 static int stk8312_read_accel(struct stk8312_data *data, u8 address)
@@ -208,12 +328,10 @@ static int stk8312_read_accel(struct stk8312_data *data, u8 address)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	ret = i2c_smbus_read_byte_data(client, address);
 	ret = i2c_smbus_read_byte_data(client, address);
-	if (ret < 0) {
+	if (ret < 0)
 		dev_err(&client->dev, "register read failed\n");
 		dev_err(&client->dev, "register read failed\n");
-		return ret;
-	}
 
 
-	return sign_extend32(ret, 7);
+	return ret;
 }
 }
 
 
 static int stk8312_read_raw(struct iio_dev *indio_dev,
 static int stk8312_read_raw(struct iio_dev *indio_dev,
@@ -221,20 +339,40 @@ static int stk8312_read_raw(struct iio_dev *indio_dev,
 			    int *val, int *val2, long mask)
 			    int *val, int *val2, long mask)
 {
 {
 	struct stk8312_data *data = iio_priv(indio_dev);
 	struct stk8312_data *data = iio_priv(indio_dev);
-
-	if (chan->type != IIO_ACCEL)
-		return -EINVAL;
+	int ret;
 
 
 	switch (mask) {
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
 	case IIO_CHAN_INFO_RAW:
+		if (iio_buffer_enabled(indio_dev))
+			return -EBUSY;
 		mutex_lock(&data->lock);
 		mutex_lock(&data->lock);
-		*val = stk8312_read_accel(data, chan->address);
+		ret = stk8312_set_mode(data, data->mode | STK8312_MODE_ACTIVE);
+		if (ret < 0) {
+			mutex_unlock(&data->lock);
+			return ret;
+		}
+		ret = stk8312_read_accel(data, chan->address);
+		if (ret < 0) {
+			stk8312_set_mode(data,
+					 data->mode & (~STK8312_MODE_ACTIVE));
+			mutex_unlock(&data->lock);
+			return ret;
+		}
+		*val = sign_extend32(ret, 7);
+		ret = stk8312_set_mode(data,
+				       data->mode & (~STK8312_MODE_ACTIVE));
 		mutex_unlock(&data->lock);
 		mutex_unlock(&data->lock);
+		if (ret < 0)
+			return ret;
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_SCALE:
 		*val = stk8312_scale_table[data->range - 1][0];
 		*val = stk8312_scale_table[data->range - 1][0];
 		*val2 = stk8312_scale_table[data->range - 1][1];
 		*val2 = stk8312_scale_table[data->range - 1][1];
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = stk8312_samp_freq_table[data->sample_rate_idx].val;
+		*val2 = stk8312_samp_freq_table[data->sample_rate_idx].val2;
+		return IIO_VAL_INT_PLUS_MICRO;
 	}
 	}
 
 
 	return -EINVAL;
 	return -EINVAL;
@@ -264,6 +402,20 @@ static int stk8312_write_raw(struct iio_dev *indio_dev,
 		ret = stk8312_set_range(data, index);
 		ret = stk8312_set_range(data, index);
 		mutex_unlock(&data->lock);
 		mutex_unlock(&data->lock);
 
 
+		return ret;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		for (i = 0; i < ARRAY_SIZE(stk8312_samp_freq_table); i++)
+			if (val == stk8312_samp_freq_table[i].val &&
+			    val2 == stk8312_samp_freq_table[i].val2) {
+				index = i;
+				break;
+			}
+		if (index < 0)
+			return -EINVAL;
+		mutex_lock(&data->lock);
+		ret = stk8312_set_sample_rate(data, index);
+		mutex_unlock(&data->lock);
+
 		return ret;
 		return ret;
 	}
 	}
 
 
@@ -277,6 +429,105 @@ static const struct iio_info stk8312_info = {
 	.attrs			= &stk8312_attribute_group,
 	.attrs			= &stk8312_attribute_group,
 };
 };
 
 
+static irqreturn_t stk8312_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct stk8312_data *data = iio_priv(indio_dev);
+	int bit, ret, i = 0;
+
+	mutex_lock(&data->lock);
+	/*
+	 * Do a bulk read if all channels are requested,
+	 * from 0x00 (XOUT) to 0x02 (ZOUT)
+	 */
+	if (*(indio_dev->active_scan_mask) == STK8312_ALL_CHANNEL_MASK) {
+		ret = i2c_smbus_read_i2c_block_data(data->client,
+						    STK8312_REG_XOUT,
+						    STK8312_ALL_CHANNEL_SIZE,
+						    data->buffer);
+		if (ret < STK8312_ALL_CHANNEL_SIZE) {
+			dev_err(&data->client->dev, "register read failed\n");
+			mutex_unlock(&data->lock);
+			goto err;
+		}
+	} else {
+		for_each_set_bit(bit, indio_dev->active_scan_mask,
+				 indio_dev->masklength) {
+			ret = stk8312_read_accel(data, bit);
+			if (ret < 0) {
+				mutex_unlock(&data->lock);
+				goto err;
+			}
+			data->buffer[i++] = ret;
+		}
+	}
+	mutex_unlock(&data->lock);
+
+	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+					   pf->timestamp);
+err:
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t stk8312_data_rdy_trig_poll(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct stk8312_data *data = iio_priv(indio_dev);
+
+	if (data->dready_trigger_on)
+		iio_trigger_poll(data->dready_trig);
+
+	return IRQ_HANDLED;
+}
+
+static int stk8312_buffer_preenable(struct iio_dev *indio_dev)
+{
+	struct stk8312_data *data = iio_priv(indio_dev);
+
+	return stk8312_set_mode(data, data->mode | STK8312_MODE_ACTIVE);
+}
+
+static int stk8312_buffer_postdisable(struct iio_dev *indio_dev)
+{
+	struct stk8312_data *data = iio_priv(indio_dev);
+
+	return stk8312_set_mode(data, data->mode & (~STK8312_MODE_ACTIVE));
+}
+
+static const struct iio_buffer_setup_ops stk8312_buffer_setup_ops = {
+	.preenable   = stk8312_buffer_preenable,
+	.postenable  = iio_triggered_buffer_postenable,
+	.predisable  = iio_triggered_buffer_predisable,
+	.postdisable = stk8312_buffer_postdisable,
+};
+
+static int stk8312_gpio_probe(struct i2c_client *client)
+{
+	struct device *dev;
+	struct gpio_desc *gpio;
+	int ret;
+
+	if (!client)
+		return -EINVAL;
+
+	dev = &client->dev;
+
+	/* data ready gpio interrupt pin */
+	gpio = devm_gpiod_get_index(dev, STK8312_GPIO, 0, GPIOD_IN);
+	if (IS_ERR(gpio)) {
+		dev_err(dev, "acpi gpio get index failed\n");
+		return PTR_ERR(gpio);
+	}
+
+	ret = gpiod_to_irq(gpio);
+	dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
+
+	return ret;
+}
+
 static int stk8312_probe(struct i2c_client *client,
 static int stk8312_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 			 const struct i2c_device_id *id)
 {
 {
@@ -308,30 +559,91 @@ static int stk8312_probe(struct i2c_client *client,
 		dev_err(&client->dev, "failed to reset sensor\n");
 		dev_err(&client->dev, "failed to reset sensor\n");
 		return ret;
 		return ret;
 	}
 	}
-	ret = stk8312_set_range(data, 1);
+	data->sample_rate_idx = STK8312_SR_400HZ_IDX;
+	ret = stk8312_set_range(data, STK8312_RNG_6G);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
-	ret = stk8312_set_mode(data, STK8312_MODE_ACTIVE);
+	ret = stk8312_set_mode(data,
+			       STK8312_MODE_INT_AH_PP | STK8312_MODE_ACTIVE);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
+	if (client->irq < 0)
+		client->irq = stk8312_gpio_probe(client);
+
+	if (client->irq >= 0) {
+		ret = devm_request_threaded_irq(&client->dev, client->irq,
+						stk8312_data_rdy_trig_poll,
+						NULL,
+						IRQF_TRIGGER_RISING |
+						IRQF_ONESHOT,
+						STK8312_IRQ_NAME,
+						indio_dev);
+		if (ret < 0) {
+			dev_err(&client->dev, "request irq %d failed\n",
+				client->irq);
+			goto err_power_off;
+		}
+
+		data->dready_trig = devm_iio_trigger_alloc(&client->dev,
+							   "%s-dev%d",
+							   indio_dev->name,
+							   indio_dev->id);
+		if (!data->dready_trig) {
+			ret = -ENOMEM;
+			goto err_power_off;
+		}
+
+		data->dready_trig->dev.parent = &client->dev;
+		data->dready_trig->ops = &stk8312_trigger_ops;
+		iio_trigger_set_drvdata(data->dready_trig, indio_dev);
+		ret = iio_trigger_register(data->dready_trig);
+		if (ret) {
+			dev_err(&client->dev, "iio trigger register failed\n");
+			goto err_power_off;
+		}
+	}
+
+	ret = iio_triggered_buffer_setup(indio_dev,
+					 iio_pollfunc_store_time,
+					 stk8312_trigger_handler,
+					 &stk8312_buffer_setup_ops);
+	if (ret < 0) {
+		dev_err(&client->dev, "iio triggered buffer setup failed\n");
+		goto err_trigger_unregister;
+	}
+
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&client->dev, "device_register failed\n");
 		dev_err(&client->dev, "device_register failed\n");
-		stk8312_set_mode(data, STK8312_MODE_STANDBY);
+		goto err_buffer_cleanup;
 	}
 	}
 
 
+	return 0;
+
+err_buffer_cleanup:
+	iio_triggered_buffer_cleanup(indio_dev);
+err_trigger_unregister:
+	if (data->dready_trig)
+		iio_trigger_unregister(data->dready_trig);
+err_power_off:
+	stk8312_set_mode(data, STK8312_MODE_STANDBY);
 	return ret;
 	return ret;
 }
 }
 
 
 static int stk8312_remove(struct i2c_client *client)
 static int stk8312_remove(struct i2c_client *client)
 {
 {
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct stk8312_data *data = iio_priv(indio_dev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+
+	if (data->dready_trig)
+		iio_trigger_unregister(data->dready_trig);
 
 
-	return stk8312_set_mode(iio_priv(indio_dev), STK8312_MODE_STANDBY);
+	return stk8312_set_mode(data, STK8312_MODE_STANDBY);
 }
 }
 
 
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_PM_SLEEP
@@ -341,7 +653,7 @@ static int stk8312_suspend(struct device *dev)
 
 
 	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
 	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
 
 
-	return stk8312_set_mode(data, STK8312_MODE_STANDBY);
+	return stk8312_set_mode(data, data->mode & (~STK8312_MODE_ACTIVE));
 }
 }
 
 
 static int stk8312_resume(struct device *dev)
 static int stk8312_resume(struct device *dev)
@@ -350,7 +662,7 @@ static int stk8312_resume(struct device *dev)
 
 
 	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
 	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
 
 
-	return stk8312_set_mode(data, STK8312_MODE_ACTIVE);
+	return stk8312_set_mode(data, data->mode | STK8312_MODE_ACTIVE);
 }
 }
 
 
 static SIMPLE_DEV_PM_OPS(stk8312_pm_ops, stk8312_suspend, stk8312_resume);
 static SIMPLE_DEV_PM_OPS(stk8312_pm_ops, stk8312_suspend, stk8312_resume);
@@ -364,6 +676,7 @@ static const struct i2c_device_id stk8312_i2c_id[] = {
 	{"STK8312", 0},
 	{"STK8312", 0},
 	{}
 	{}
 };
 };
+MODULE_DEVICE_TABLE(i2c, stk8312_i2c_id);
 
 
 static const struct acpi_device_id stk8312_acpi_id[] = {
 static const struct acpi_device_id stk8312_acpi_id[] = {
 	{"STK8312", 0},
 	{"STK8312", 0},
@@ -374,7 +687,7 @@ MODULE_DEVICE_TABLE(acpi, stk8312_acpi_id);
 
 
 static struct i2c_driver stk8312_driver = {
 static struct i2c_driver stk8312_driver = {
 	.driver = {
 	.driver = {
-		.name = "stk8312",
+		.name = STK8312_DRIVER_NAME,
 		.pm = STK8312_PM_OPS,
 		.pm = STK8312_PM_OPS,
 		.acpi_match_table = ACPI_PTR(stk8312_acpi_id),
 		.acpi_match_table = ACPI_PTR(stk8312_acpi_id),
 	},
 	},

+ 333 - 36
drivers/iio/accel/stk8ba50.c

@@ -11,26 +11,42 @@
  */
  */
 
 
 #include <linux/acpi.h>
 #include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
+#include <linux/iio/buffer.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
 
 
 #define STK8BA50_REG_XOUT			0x02
 #define STK8BA50_REG_XOUT			0x02
 #define STK8BA50_REG_YOUT			0x04
 #define STK8BA50_REG_YOUT			0x04
 #define STK8BA50_REG_ZOUT			0x06
 #define STK8BA50_REG_ZOUT			0x06
 #define STK8BA50_REG_RANGE			0x0F
 #define STK8BA50_REG_RANGE			0x0F
+#define STK8BA50_REG_BWSEL			0x10
 #define STK8BA50_REG_POWMODE			0x11
 #define STK8BA50_REG_POWMODE			0x11
 #define STK8BA50_REG_SWRST			0x14
 #define STK8BA50_REG_SWRST			0x14
+#define STK8BA50_REG_INTEN2			0x17
+#define STK8BA50_REG_INTMAP2			0x1A
 
 
 #define STK8BA50_MODE_NORMAL			0
 #define STK8BA50_MODE_NORMAL			0
 #define STK8BA50_MODE_SUSPEND			1
 #define STK8BA50_MODE_SUSPEND			1
 #define STK8BA50_MODE_POWERBIT			BIT(7)
 #define STK8BA50_MODE_POWERBIT			BIT(7)
 #define STK8BA50_DATA_SHIFT			6
 #define STK8BA50_DATA_SHIFT			6
 #define STK8BA50_RESET_CMD			0xB6
 #define STK8BA50_RESET_CMD			0xB6
+#define STK8BA50_SR_1792HZ_IDX			7
+#define STK8BA50_DREADY_INT_MASK		0x10
+#define STK8BA50_DREADY_INT_MAP			0x81
+#define STK8BA50_ALL_CHANNEL_MASK		7
+#define STK8BA50_ALL_CHANNEL_SIZE		6
 
 
 #define STK8BA50_DRIVER_NAME			"stk8ba50"
 #define STK8BA50_DRIVER_NAME			"stk8ba50"
+#define STK8BA50_GPIO				"stk8ba50_gpio"
+#define STK8BA50_IRQ_NAME			"stk8ba50_event"
 
 
 #define STK8BA50_SCALE_AVAIL			"0.0384 0.0767 0.1534 0.3069"
 #define STK8BA50_SCALE_AVAIL			"0.0384 0.0767 0.1534 0.3069"
 
 
@@ -50,35 +66,76 @@
  *
  *
  * Locally, the range is stored as a table index.
  * Locally, the range is stored as a table index.
  */
  */
-static const int stk8ba50_scale_table[][2] = {
+static const struct {
+	u8 reg_val;
+	u32 scale_val;
+} stk8ba50_scale_table[] = {
 	{3, 38400}, {5, 76700}, {8, 153400}, {12, 306900}
 	{3, 38400}, {5, 76700}, {8, 153400}, {12, 306900}
 };
 };
 
 
+/* Sample rates are stored as { <register value>, <Hz value> } */
+static const struct {
+	u8 reg_val;
+	u16 samp_freq;
+} stk8ba50_samp_freq_table[] = {
+	{0x08, 14},  {0x09, 25},  {0x0A, 56},  {0x0B, 112},
+	{0x0C, 224}, {0x0D, 448}, {0x0E, 896}, {0x0F, 1792}
+};
+
+/* Used to map scan mask bits to their corresponding channel register. */
+static const int stk8ba50_channel_table[] = {
+	STK8BA50_REG_XOUT,
+	STK8BA50_REG_YOUT,
+	STK8BA50_REG_ZOUT
+};
+
 struct stk8ba50_data {
 struct stk8ba50_data {
 	struct i2c_client *client;
 	struct i2c_client *client;
 	struct mutex lock;
 	struct mutex lock;
 	int range;
 	int range;
+	u8 sample_rate_idx;
+	struct iio_trigger *dready_trig;
+	bool dready_trigger_on;
+	/*
+	 * 3 x 16-bit channels (10-bit data, 6-bit padding) +
+	 * 1 x 16 padding +
+	 * 4 x 16 64-bit timestamp
+	 */
+	s16 buffer[8];
 };
 };
 
 
-#define STK8BA50_ACCEL_CHANNEL(reg, axis) {			\
-	.type = IIO_ACCEL,					\
-	.address = reg,						\
-	.modified = 1,						\
-	.channel2 = IIO_MOD_##axis,				\
-	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
-	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
+#define STK8BA50_ACCEL_CHANNEL(index, reg, axis) {			\
+	.type = IIO_ACCEL,						\
+	.address = reg,							\
+	.modified = 1,							\
+	.channel2 = IIO_MOD_##axis,					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),		\
+				    BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
+	.scan_index = index,						\
+	.scan_type = {							\
+		.sign = 's',						\
+		.realbits = 10,						\
+		.storagebits = 16,					\
+		.shift = STK8BA50_DATA_SHIFT,				\
+		.endianness = IIO_CPU,					\
+	},								\
 }
 }
 
 
 static const struct iio_chan_spec stk8ba50_channels[] = {
 static const struct iio_chan_spec stk8ba50_channels[] = {
-	STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_XOUT, X),
-	STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_YOUT, Y),
-	STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_ZOUT, Z),
+	STK8BA50_ACCEL_CHANNEL(0, STK8BA50_REG_XOUT, X),
+	STK8BA50_ACCEL_CHANNEL(1, STK8BA50_REG_YOUT, Y),
+	STK8BA50_ACCEL_CHANNEL(2, STK8BA50_REG_ZOUT, Z),
+	IIO_CHAN_SOFT_TIMESTAMP(3),
 };
 };
 
 
 static IIO_CONST_ATTR(in_accel_scale_available, STK8BA50_SCALE_AVAIL);
 static IIO_CONST_ATTR(in_accel_scale_available, STK8BA50_SCALE_AVAIL);
 
 
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("14 25 56 112 224 448 896 1792");
+
 static struct attribute *stk8ba50_attributes[] = {
 static struct attribute *stk8ba50_attributes[] = {
 	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
 	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	NULL,
 	NULL,
 };
 };
 
 
@@ -97,7 +154,61 @@ static int stk8ba50_read_accel(struct stk8ba50_data *data, u8 reg)
 		return ret;
 		return ret;
 	}
 	}
 
 
-	return sign_extend32(ret >> STK8BA50_DATA_SHIFT, 9);
+	return ret;
+}
+
+static int stk8ba50_data_rdy_trigger_set_state(struct iio_trigger *trig,
+					       bool state)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct stk8ba50_data *data = iio_priv(indio_dev);
+	int ret;
+
+	if (state)
+		ret = i2c_smbus_write_byte_data(data->client,
+			STK8BA50_REG_INTEN2, STK8BA50_DREADY_INT_MASK);
+	else
+		ret = i2c_smbus_write_byte_data(data->client,
+			STK8BA50_REG_INTEN2, 0x00);
+
+	if (ret < 0)
+		dev_err(&data->client->dev, "failed to set trigger state\n");
+	else
+		data->dready_trigger_on = state;
+
+	return ret;
+}
+
+static const struct iio_trigger_ops stk8ba50_trigger_ops = {
+	.set_trigger_state = stk8ba50_data_rdy_trigger_set_state,
+	.owner = THIS_MODULE,
+};
+
+static int stk8ba50_set_power(struct stk8ba50_data *data, bool mode)
+{
+	int ret;
+	u8 masked_reg;
+	struct i2c_client *client = data->client;
+
+	ret = i2c_smbus_read_byte_data(client, STK8BA50_REG_POWMODE);
+	if (ret < 0)
+		goto exit_err;
+
+	if (mode)
+		masked_reg = ret | STK8BA50_MODE_POWERBIT;
+	else
+		masked_reg = ret & (~STK8BA50_MODE_POWERBIT);
+
+	ret = i2c_smbus_write_byte_data(client, STK8BA50_REG_POWMODE,
+					masked_reg);
+	if (ret < 0)
+		goto exit_err;
+
+	return ret;
+
+exit_err:
+	dev_err(&client->dev, "failed to change sensor mode\n");
+	return ret;
 }
 }
 
 
 static int stk8ba50_read_raw(struct iio_dev *indio_dev,
 static int stk8ba50_read_raw(struct iio_dev *indio_dev,
@@ -105,17 +216,37 @@ static int stk8ba50_read_raw(struct iio_dev *indio_dev,
 			     int *val, int *val2, long mask)
 			     int *val, int *val2, long mask)
 {
 {
 	struct stk8ba50_data *data = iio_priv(indio_dev);
 	struct stk8ba50_data *data = iio_priv(indio_dev);
+	int ret;
 
 
 	switch (mask) {
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
 	case IIO_CHAN_INFO_RAW:
+		if (iio_buffer_enabled(indio_dev))
+			return -EBUSY;
 		mutex_lock(&data->lock);
 		mutex_lock(&data->lock);
-		*val = stk8ba50_read_accel(data, chan->address);
+		ret = stk8ba50_set_power(data, STK8BA50_MODE_NORMAL);
+		if (ret < 0) {
+			mutex_unlock(&data->lock);
+			return -EINVAL;
+		}
+		ret = stk8ba50_read_accel(data, chan->address);
+		if (ret < 0) {
+			stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
+			mutex_unlock(&data->lock);
+			return -EINVAL;
+		}
+		*val = sign_extend32(ret >> STK8BA50_DATA_SHIFT, 9);
+		stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
 		mutex_unlock(&data->lock);
 		mutex_unlock(&data->lock);
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_SCALE:
 		*val = 0;
 		*val = 0;
-		*val2 = stk8ba50_scale_table[data->range][1];
+		*val2 = stk8ba50_scale_table[data->range].scale_val;
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		*val = stk8ba50_samp_freq_table
+				[data->sample_rate_idx].samp_freq;
+		*val2 = 0;
+		return IIO_VAL_INT;
 	}
 	}
 
 
 	return -EINVAL;
 	return -EINVAL;
@@ -136,7 +267,7 @@ static int stk8ba50_write_raw(struct iio_dev *indio_dev,
 			return -EINVAL;
 			return -EINVAL;
 
 
 		for (i = 0; i < ARRAY_SIZE(stk8ba50_scale_table); i++)
 		for (i = 0; i < ARRAY_SIZE(stk8ba50_scale_table); i++)
-			if (val2 == stk8ba50_scale_table[i][1]) {
+			if (val2 == stk8ba50_scale_table[i].scale_val) {
 				index = i;
 				index = i;
 				break;
 				break;
 			}
 			}
@@ -145,13 +276,32 @@ static int stk8ba50_write_raw(struct iio_dev *indio_dev,
 
 
 		ret = i2c_smbus_write_byte_data(data->client,
 		ret = i2c_smbus_write_byte_data(data->client,
 				STK8BA50_REG_RANGE,
 				STK8BA50_REG_RANGE,
-				stk8ba50_scale_table[index][0]);
+				stk8ba50_scale_table[index].reg_val);
 		if (ret < 0)
 		if (ret < 0)
 			dev_err(&data->client->dev,
 			dev_err(&data->client->dev,
 					"failed to set measurement range\n");
 					"failed to set measurement range\n");
 		else
 		else
 			data->range = index;
 			data->range = index;
 
 
+		return ret;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		for (i = 0; i < ARRAY_SIZE(stk8ba50_samp_freq_table); i++)
+			if (val == stk8ba50_samp_freq_table[i].samp_freq) {
+				index = i;
+				break;
+			}
+		if (index < 0)
+			return -EINVAL;
+
+		ret = i2c_smbus_write_byte_data(data->client,
+				STK8BA50_REG_BWSEL,
+				stk8ba50_samp_freq_table[index].reg_val);
+		if (ret < 0)
+			dev_err(&data->client->dev,
+					"failed to set sampling rate\n");
+		else
+			data->sample_rate_idx = index;
+
 		return ret;
 		return ret;
 	}
 	}
 
 
@@ -165,30 +315,100 @@ static const struct iio_info stk8ba50_info = {
 	.attrs			= &stk8ba50_attribute_group,
 	.attrs			= &stk8ba50_attribute_group,
 };
 };
 
 
-static int stk8ba50_set_power(struct stk8ba50_data *data, bool mode)
+static irqreturn_t stk8ba50_trigger_handler(int irq, void *p)
 {
 {
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct stk8ba50_data *data = iio_priv(indio_dev);
+	int bit, ret, i = 0;
+
+	mutex_lock(&data->lock);
+	/*
+	 * Do a bulk read if all channels are requested,
+	 * from 0x02 (XOUT1) to 0x07 (ZOUT2)
+	 */
+	if (*(indio_dev->active_scan_mask) == STK8BA50_ALL_CHANNEL_MASK) {
+		ret = i2c_smbus_read_i2c_block_data(data->client,
+						    STK8BA50_REG_XOUT,
+						    STK8BA50_ALL_CHANNEL_SIZE,
+						    (u8 *)data->buffer);
+		if (ret < STK8BA50_ALL_CHANNEL_SIZE) {
+			dev_err(&data->client->dev, "register read failed\n");
+			goto err;
+		}
+	} else {
+		for_each_set_bit(bit, indio_dev->active_scan_mask,
+				 indio_dev->masklength) {
+			ret = stk8ba50_read_accel(data,
+						  stk8ba50_channel_table[bit]);
+			if (ret < 0)
+				goto err;
+
+			data->buffer[i++] = ret;
+		}
+	}
+	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+					   pf->timestamp);
+err:
+	mutex_unlock(&data->lock);
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t stk8ba50_data_rdy_trig_poll(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct stk8ba50_data *data = iio_priv(indio_dev);
+
+	if (data->dready_trigger_on)
+		iio_trigger_poll(data->dready_trig);
+
+	return IRQ_HANDLED;
+}
+
+static int stk8ba50_buffer_preenable(struct iio_dev *indio_dev)
+{
+	struct stk8ba50_data *data = iio_priv(indio_dev);
+
+	return stk8ba50_set_power(data, STK8BA50_MODE_NORMAL);
+}
+
+static int stk8ba50_buffer_postdisable(struct iio_dev *indio_dev)
+{
+	struct stk8ba50_data *data = iio_priv(indio_dev);
+
+	return stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
+}
+
+static const struct iio_buffer_setup_ops stk8ba50_buffer_setup_ops = {
+	.preenable   = stk8ba50_buffer_preenable,
+	.postenable  = iio_triggered_buffer_postenable,
+	.predisable  = iio_triggered_buffer_predisable,
+	.postdisable = stk8ba50_buffer_postdisable,
+};
+
+static int stk8ba50_gpio_probe(struct i2c_client *client)
+{
+	struct device *dev;
+	struct gpio_desc *gpio;
 	int ret;
 	int ret;
-	u8 masked_reg;
-	struct i2c_client *client = data->client;
 
 
-	ret = i2c_smbus_read_byte_data(client, STK8BA50_REG_POWMODE);
-	if (ret < 0)
-		goto exit_err;
+	if (!client)
+		return -EINVAL;
 
 
-	if (mode)
-		masked_reg = ret | STK8BA50_MODE_POWERBIT;
-	else
-		masked_reg = ret & (~STK8BA50_MODE_POWERBIT);
+	dev = &client->dev;
 
 
-	ret = i2c_smbus_write_byte_data(client, STK8BA50_REG_POWMODE,
-					masked_reg);
-	if (ret < 0)
-		goto exit_err;
+	/* data ready gpio interrupt pin */
+	gpio = devm_gpiod_get_index(dev, STK8BA50_GPIO, 0, GPIOD_IN);
+	if (IS_ERR(gpio)) {
+		dev_err(dev, "acpi gpio get index failed\n");
+		return PTR_ERR(gpio);
+	}
 
 
-	return ret;
+	ret = gpiod_to_irq(gpio);
+	dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
 
 
-exit_err:
-	dev_err(&client->dev, "failed to change sensor mode\n");
 	return ret;
 	return ret;
 }
 }
 
 
@@ -222,28 +442,104 @@ static int stk8ba50_probe(struct i2c_client *client,
 			STK8BA50_REG_SWRST, STK8BA50_RESET_CMD);
 			STK8BA50_REG_SWRST, STK8BA50_RESET_CMD);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&client->dev, "failed to reset sensor\n");
 		dev_err(&client->dev, "failed to reset sensor\n");
-		return ret;
+		goto err_power_off;
 	}
 	}
 
 
 	/* The default range is +/-2g */
 	/* The default range is +/-2g */
 	data->range = 0;
 	data->range = 0;
 
 
+	/* The default sampling rate is 1792 Hz (maximum) */
+	data->sample_rate_idx = STK8BA50_SR_1792HZ_IDX;
+
+	/* Set up interrupts */
+	ret = i2c_smbus_write_byte_data(client,
+			STK8BA50_REG_INTEN2, STK8BA50_DREADY_INT_MASK);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to set up interrupts\n");
+		goto err_power_off;
+	}
+	ret = i2c_smbus_write_byte_data(client,
+			STK8BA50_REG_INTMAP2, STK8BA50_DREADY_INT_MAP);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to set up interrupts\n");
+		goto err_power_off;
+	}
+
+	if (client->irq < 0)
+		client->irq = stk8ba50_gpio_probe(client);
+
+	if (client->irq >= 0) {
+		ret = devm_request_threaded_irq(&client->dev, client->irq,
+						stk8ba50_data_rdy_trig_poll,
+						NULL,
+						IRQF_TRIGGER_RISING |
+						IRQF_ONESHOT,
+						STK8BA50_IRQ_NAME,
+						indio_dev);
+		if (ret < 0) {
+			dev_err(&client->dev, "request irq %d failed\n",
+				client->irq);
+			goto err_power_off;
+		}
+
+		data->dready_trig = devm_iio_trigger_alloc(&client->dev,
+							   "%s-dev%d",
+							   indio_dev->name,
+							   indio_dev->id);
+		if (!data->dready_trig) {
+			ret = -ENOMEM;
+			goto err_power_off;
+		}
+
+		data->dready_trig->dev.parent = &client->dev;
+		data->dready_trig->ops = &stk8ba50_trigger_ops;
+		iio_trigger_set_drvdata(data->dready_trig, indio_dev);
+		ret = iio_trigger_register(data->dready_trig);
+		if (ret) {
+			dev_err(&client->dev, "iio trigger register failed\n");
+			goto err_power_off;
+		}
+	}
+
+	ret = iio_triggered_buffer_setup(indio_dev,
+					 iio_pollfunc_store_time,
+					 stk8ba50_trigger_handler,
+					 &stk8ba50_buffer_setup_ops);
+	if (ret < 0) {
+		dev_err(&client->dev, "iio triggered buffer setup failed\n");
+		goto err_trigger_unregister;
+	}
+
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&client->dev, "device_register failed\n");
 		dev_err(&client->dev, "device_register failed\n");
-		stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
+		goto err_buffer_cleanup;
 	}
 	}
 
 
 	return ret;
 	return ret;
+
+err_buffer_cleanup:
+	iio_triggered_buffer_cleanup(indio_dev);
+err_trigger_unregister:
+	if (data->dready_trig)
+		iio_trigger_unregister(data->dready_trig);
+err_power_off:
+	stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
+	return ret;
 }
 }
 
 
 static int stk8ba50_remove(struct i2c_client *client)
 static int stk8ba50_remove(struct i2c_client *client)
 {
 {
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct stk8ba50_data *data = iio_priv(indio_dev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
 
 
-	return stk8ba50_set_power(iio_priv(indio_dev), STK8BA50_MODE_SUSPEND);
+	if (data->dready_trig)
+		iio_trigger_unregister(data->dready_trig);
+
+	return stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
 }
 }
 
 
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_PM_SLEEP
@@ -276,6 +572,7 @@ static const struct i2c_device_id stk8ba50_i2c_id[] = {
 	{"stk8ba50", 0},
 	{"stk8ba50", 0},
 	{}
 	{}
 };
 };
+MODULE_DEVICE_TABLE(i2c, stk8ba50_i2c_id);
 
 
 static const struct acpi_device_id stk8ba50_acpi_id[] = {
 static const struct acpi_device_id stk8ba50_acpi_id[] = {
 	{"STK8BA50", 0},
 	{"STK8BA50", 0},

+ 40 - 12
drivers/iio/adc/Kconfig

@@ -20,6 +20,9 @@ config AD7266
 	  Say yes here to build support for Analog Devices AD7265 and AD7266
 	  Say yes here to build support for Analog Devices AD7265 and AD7266
 	  ADCs.
 	  ADCs.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called ad7266.
+
 config AD7291
 config AD7291
 	tristate "Analog Devices AD7291 ADC driver"
 	tristate "Analog Devices AD7291 ADC driver"
 	depends on I2C
 	depends on I2C
@@ -52,8 +55,6 @@ config AD7476
 	  AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
 	  AD7277, AD7278, AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468,
 	  AD7495, AD7910, AD7920, AD7920 SPI analog to digital converters (ADC).
 	  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 ad7476.
 	  module will be called ad7476.
 
 
@@ -63,8 +64,7 @@ config AD7791
 	select AD_SIGMA_DELTA
 	select AD_SIGMA_DELTA
 	help
 	help
 	  Say yes here to build support for Analog Devices AD7787, AD7788, AD7789,
 	  Say yes here to build support for Analog Devices AD7787, AD7788, AD7789,
-	  AD7790 and AD7791 SPI analog to digital converters (ADC). If unsure, say
-	  N (but it is safe to say "Y").
+	  AD7790 and AD7791 SPI analog to digital converters (ADC).
 
 
 	  To compile this driver as a module, choose M here: the module will be
 	  To compile this driver as a module, choose M here: the module will be
 	  called ad7791.
 	  called ad7791.
@@ -76,7 +76,6 @@ config AD7793
 	help
 	help
 	  Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
 	  Say yes here to build support for Analog Devices AD7785, AD7792, AD7793,
 	  AD7794 and AD7795 SPI analog to digital converters (ADC).
 	  AD7794 and AD7795 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 AD7793.
 	  module will be called AD7793.
@@ -89,7 +88,6 @@ config AD7887
 	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).
 	  AD7887 SPI analog to digital converter (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 ad7887.
 	  module will be called ad7887.
@@ -117,6 +115,9 @@ config AD799X
 	  i2c analog to digital converters (ADC). Provides direct access
 	  i2c analog to digital converters (ADC). Provides direct access
 	  via sysfs.
 	  via sysfs.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called ad799x.
+
 config AT91_ADC
 config AT91_ADC
 	tristate "Atmel AT91 ADC"
 	tristate "Atmel AT91 ADC"
 	depends on ARCH_AT91
 	depends on ARCH_AT91
@@ -127,6 +128,9 @@ config AT91_ADC
 	help
 	help
 	  Say yes here to build support for Atmel AT91 ADC.
 	  Say yes here to build support for Atmel AT91 ADC.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called at91_adc.
+
 config AXP288_ADC
 config AXP288_ADC
 	tristate "X-Powers AXP288 ADC driver"
 	tristate "X-Powers AXP288 ADC driver"
 	depends on MFD_AXP20X
 	depends on MFD_AXP20X
@@ -135,6 +139,9 @@ config AXP288_ADC
 	  device. Depending on platform configuration, this general purpose ADC can
 	  device. Depending on platform configuration, this general purpose ADC can
 	  be used for sampling sensors such as thermal resistors.
 	  be used for sampling sensors such as thermal resistors.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called axp288_adc.
+
 config BERLIN2_ADC
 config BERLIN2_ADC
 	tristate "Marvell Berlin2 ADC driver"
 	tristate "Marvell Berlin2 ADC driver"
 	depends on ARCH_BERLIN
 	depends on ARCH_BERLIN
@@ -151,6 +158,9 @@ config DA9150_GPADC
 	  This driver can also be built as a module. If chosen, the module name
 	  This driver can also be built as a module. If chosen, the module name
 	  will be da9150-gpadc.
 	  will be da9150-gpadc.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called berlin2-adc.
+
 config CC10001_ADC
 config CC10001_ADC
 	tristate "Cosmic Circuits 10001 ADC driver"
 	tristate "Cosmic Circuits 10001 ADC driver"
 	depends on HAS_IOMEM && HAVE_CLK && REGULATOR
 	depends on HAS_IOMEM && HAVE_CLK && REGULATOR
@@ -170,12 +180,18 @@ config EXYNOS_ADC
 	  of SoCs for drivers such as the touchscreen and hwmon to use to share
 	  of SoCs for drivers such as the touchscreen and hwmon to use to share
 	  this resource.
 	  this resource.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called exynos_adc.
+
 config LP8788_ADC
 config LP8788_ADC
 	tristate "LP8788 ADC driver"
 	tristate "LP8788 ADC driver"
 	depends on MFD_LP8788
 	depends on MFD_LP8788
 	help
 	help
 	  Say yes here to build support for TI LP8788 ADC.
 	  Say yes here to build support for TI LP8788 ADC.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called lp8788_adc.
+
 config MAX1027
 config MAX1027
 	tristate "Maxim max1027 ADC driver"
 	tristate "Maxim max1027 ADC driver"
 	depends on SPI
 	depends on SPI
@@ -185,6 +201,9 @@ config MAX1027
 	  Say yes here to build support for Maxim SPI ADC models
 	  Say yes here to build support for Maxim SPI ADC models
 	  max1027, max1029 and max1031.
 	  max1027, max1029 and max1031.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called max1027.
+
 config MAX1363
 config MAX1363
 	tristate "Maxim max1363 ADC driver"
 	tristate "Maxim max1363 ADC driver"
 	depends on I2C
 	depends on I2C
@@ -201,13 +220,16 @@ config MAX1363
 	  max11646, max11647) Provides direct access via sysfs and buffered
 	  max11646, max11647) Provides direct access via sysfs and buffered
 	  data via the iio dev interface.
 	  data via the iio dev interface.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called max1363.
+
 config MCP320X
 config MCP320X
 	tristate "Microchip Technology MCP3x01/02/04/08"
 	tristate "Microchip Technology MCP3x01/02/04/08"
 	depends on SPI
 	depends on SPI
 	help
 	help
 	  Say yes here to build support for Microchip Technology's
 	  Say yes here to build support for Microchip Technology's
-	  MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204 or
-	  MCP3208 analog to digital converter.
+	  MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204,
+	  MCP3208 or MCP3301 analog to digital converter.
 
 
 	  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.
@@ -309,15 +331,18 @@ config TI_AM335X_ADC
 	  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.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called ti_am335x_adc.
+
 config TWL4030_MADC
 config TWL4030_MADC
 	tristate "TWL4030 MADC (Monitoring A/D Converter)"
 	tristate "TWL4030 MADC (Monitoring A/D Converter)"
 	depends on TWL4030_CORE
 	depends on TWL4030_CORE
 	help
 	help
-	This driver provides support for Triton TWL4030-MADC. The
-	driver supports both RT and SW conversion methods.
+	  This driver provides support for Triton TWL4030-MADC. The
+	  driver supports both RT and SW conversion methods.
 
 
-	This driver can also be built as a module. If so, the module will be
-	called twl4030-madc.
+	  This driver can also be built as a module. If so, the module will be
+	  called twl4030-madc.
 
 
 config TWL6030_GPADC
 config TWL6030_GPADC
 	tristate "TWL6030 GPADC (General Purpose A/D Converter) Support"
 	tristate "TWL6030 GPADC (General Purpose A/D Converter) Support"
@@ -350,6 +375,9 @@ config VIPERBOARD_ADC
 	  Say yes here to access the ADC part of the Nano River
 	  Say yes here to access the ADC part of the Nano River
 	  Technologies Viperboard.
 	  Technologies Viperboard.
 
 
+	  To compile this driver as a module, choose M here: the module will be
+	  called viperboard_adc.
+
 config XILINX_XADC
 config XILINX_XADC
 	tristate "Xilinx XADC driver"
 	tristate "Xilinx XADC driver"
 	depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
 	depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST

+ 10 - 12
drivers/iio/adc/berlin2-adc.c

@@ -26,7 +26,7 @@
 #define BERLIN2_SM_CTRL				0x14
 #define BERLIN2_SM_CTRL				0x14
 #define  BERLIN2_SM_CTRL_SM_SOC_INT		BIT(1)
 #define  BERLIN2_SM_CTRL_SM_SOC_INT		BIT(1)
 #define  BERLIN2_SM_CTRL_SOC_SM_INT		BIT(2)
 #define  BERLIN2_SM_CTRL_SOC_SM_INT		BIT(2)
-#define  BERLIN2_SM_CTRL_ADC_SEL(x)		(BIT(x) << 5)	/* 0-15 */
+#define  BERLIN2_SM_CTRL_ADC_SEL(x)		((x) << 5)	/* 0-15 */
 #define  BERLIN2_SM_CTRL_ADC_SEL_MASK		(0xf << 5)
 #define  BERLIN2_SM_CTRL_ADC_SEL_MASK		(0xf << 5)
 #define  BERLIN2_SM_CTRL_ADC_POWER		BIT(9)
 #define  BERLIN2_SM_CTRL_ADC_POWER		BIT(9)
 #define  BERLIN2_SM_CTRL_ADC_CLKSEL_DIV2	(0x0 << 10)
 #define  BERLIN2_SM_CTRL_ADC_CLKSEL_DIV2	(0x0 << 10)
@@ -53,14 +53,14 @@
 #define  BERLIN2_SM_ADC_MASK			0x3ff
 #define  BERLIN2_SM_ADC_MASK			0x3ff
 #define BERLIN2_SM_ADC_STATUS			0x1c
 #define BERLIN2_SM_ADC_STATUS			0x1c
 #define  BERLIN2_SM_ADC_STATUS_DATA_RDY(x)	BIT(x)		/* 0-15 */
 #define  BERLIN2_SM_ADC_STATUS_DATA_RDY(x)	BIT(x)		/* 0-15 */
-#define  BERLIN2_SM_ADC_STATUS_DATA_RDY_MASK	0xf
+#define  BERLIN2_SM_ADC_STATUS_DATA_RDY_MASK	GENMASK(15, 0)
 #define  BERLIN2_SM_ADC_STATUS_INT_EN(x)	(BIT(x) << 16)	/* 0-15 */
 #define  BERLIN2_SM_ADC_STATUS_INT_EN(x)	(BIT(x) << 16)	/* 0-15 */
-#define  BERLIN2_SM_ADC_STATUS_INT_EN_MASK	(0xf << 16)
+#define  BERLIN2_SM_ADC_STATUS_INT_EN_MASK	GENMASK(31, 16)
 #define BERLIN2_SM_TSEN_STATUS			0x24
 #define BERLIN2_SM_TSEN_STATUS			0x24
 #define  BERLIN2_SM_TSEN_STATUS_DATA_RDY	BIT(0)
 #define  BERLIN2_SM_TSEN_STATUS_DATA_RDY	BIT(0)
 #define  BERLIN2_SM_TSEN_STATUS_INT_EN		BIT(1)
 #define  BERLIN2_SM_TSEN_STATUS_INT_EN		BIT(1)
 #define BERLIN2_SM_TSEN_DATA			0x28
 #define BERLIN2_SM_TSEN_DATA			0x28
-#define  BERLIN2_SM_TSEN_MASK			0xfff
+#define  BERLIN2_SM_TSEN_MASK			GENMASK(9, 0)
 #define BERLIN2_SM_TSEN_CTRL			0x74
 #define BERLIN2_SM_TSEN_CTRL			0x74
 #define  BERLIN2_SM_TSEN_CTRL_START		BIT(8)
 #define  BERLIN2_SM_TSEN_CTRL_START		BIT(8)
 #define  BERLIN2_SM_TSEN_CTRL_SETTLING_4	(0x0 << 21)	/* 4 us */
 #define  BERLIN2_SM_TSEN_CTRL_SETTLING_4	(0x0 << 21)	/* 4 us */
@@ -86,7 +86,7 @@ struct berlin2_adc_priv {
 			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
 			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
 		}
 		}
 
 
-static struct iio_chan_spec berlin2_adc_channels[] = {
+static const struct iio_chan_spec berlin2_adc_channels[] = {
 	BERLIN2_ADC_CHANNEL(0, IIO_VOLTAGE),	/* external input */
 	BERLIN2_ADC_CHANNEL(0, IIO_VOLTAGE),	/* external input */
 	BERLIN2_ADC_CHANNEL(1, IIO_VOLTAGE),	/* external input */
 	BERLIN2_ADC_CHANNEL(1, IIO_VOLTAGE),	/* external input */
 	BERLIN2_ADC_CHANNEL(2, IIO_VOLTAGE),	/* external input */
 	BERLIN2_ADC_CHANNEL(2, IIO_VOLTAGE),	/* external input */
@@ -103,7 +103,6 @@ static struct iio_chan_spec berlin2_adc_channels[] = {
 	BERLIN2_ADC_CHANNEL(7, IIO_VOLTAGE),	/* reserved */
 	BERLIN2_ADC_CHANNEL(7, IIO_VOLTAGE),	/* reserved */
 	IIO_CHAN_SOFT_TIMESTAMP(8),		/* timestamp */
 	IIO_CHAN_SOFT_TIMESTAMP(8),		/* timestamp */
 };
 };
-#define BERLIN2_N_CHANNELS	ARRAY_SIZE(berlin2_adc_channels)
 
 
 static int berlin2_adc_read(struct iio_dev *indio_dev, int channel)
 static int berlin2_adc_read(struct iio_dev *indio_dev, int channel)
 {
 {
@@ -221,7 +220,7 @@ static int berlin2_adc_read_raw(struct iio_dev *indio_dev,
 			return temp;
 			return temp;
 
 
 		if (temp > 2047)
 		if (temp > 2047)
-			temp = -(4096 - temp);
+			temp -= 4096;
 
 
 		/* Convert to milli Celsius */
 		/* Convert to milli Celsius */
 		*val = ((temp * 100000) / 264 - 270000);
 		*val = ((temp * 100000) / 264 - 270000);
@@ -286,8 +285,7 @@ static int berlin2_adc_probe(struct platform_device *pdev)
 	int irq, tsen_irq;
 	int irq, tsen_irq;
 	int ret;
 	int ret;
 
 
-	indio_dev = devm_iio_device_alloc(&pdev->dev,
-					  sizeof(struct berlin2_adc_priv));
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
 	if (!indio_dev)
 	if (!indio_dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -301,11 +299,11 @@ static int berlin2_adc_probe(struct platform_device *pdev)
 
 
 	irq = platform_get_irq_byname(pdev, "adc");
 	irq = platform_get_irq_byname(pdev, "adc");
 	if (irq < 0)
 	if (irq < 0)
-		return -ENODEV;
+		return irq;
 
 
 	tsen_irq = platform_get_irq_byname(pdev, "tsen");
 	tsen_irq = platform_get_irq_byname(pdev, "tsen");
 	if (tsen_irq < 0)
 	if (tsen_irq < 0)
-		return -ENODEV;
+		return tsen_irq;
 
 
 	ret = devm_request_irq(&pdev->dev, irq, berlin2_adc_irq, 0,
 	ret = devm_request_irq(&pdev->dev, irq, berlin2_adc_irq, 0,
 			pdev->dev.driver->name, indio_dev);
 			pdev->dev.driver->name, indio_dev);
@@ -325,8 +323,8 @@ static int berlin2_adc_probe(struct platform_device *pdev)
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->info = &berlin2_adc_info;
 	indio_dev->info = &berlin2_adc_info;
 
 
-	indio_dev->num_channels = BERLIN2_N_CHANNELS;
 	indio_dev->channels = berlin2_adc_channels;
 	indio_dev->channels = berlin2_adc_channels;
+	indio_dev->num_channels = ARRAY_SIZE(berlin2_adc_channels);
 
 
 	/* Power up the ADC */
 	/* Power up the ADC */
 	regmap_update_bits(priv->regmap, BERLIN2_SM_CTRL,
 	regmap_update_bits(priv->regmap, BERLIN2_SM_CTRL,

+ 21 - 5
drivers/iio/adc/cc10001_adc.c

@@ -62,6 +62,7 @@ struct cc10001_adc_device {
 	struct regulator *reg;
 	struct regulator *reg;
 	u16 *buf;
 	u16 *buf;
 
 
+	bool shared;
 	struct mutex lock;
 	struct mutex lock;
 	unsigned int start_delay_ns;
 	unsigned int start_delay_ns;
 	unsigned int eoc_delay_ns;
 	unsigned int eoc_delay_ns;
@@ -153,7 +154,8 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
 
 
 	mutex_lock(&adc_dev->lock);
 	mutex_lock(&adc_dev->lock);
 
 
-	cc10001_adc_power_up(adc_dev);
+	if (!adc_dev->shared)
+		cc10001_adc_power_up(adc_dev);
 
 
 	/* Calculate delay step for eoc and sampled data */
 	/* Calculate delay step for eoc and sampled data */
 	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
 	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
@@ -177,7 +179,8 @@ static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
 	}
 	}
 
 
 done:
 done:
-	cc10001_adc_power_down(adc_dev);
+	if (!adc_dev->shared)
+		cc10001_adc_power_down(adc_dev);
 
 
 	mutex_unlock(&adc_dev->lock);
 	mutex_unlock(&adc_dev->lock);
 
 
@@ -196,7 +199,8 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
 	unsigned int delay_ns;
 	unsigned int delay_ns;
 	u16 val;
 	u16 val;
 
 
-	cc10001_adc_power_up(adc_dev);
+	if (!adc_dev->shared)
+		cc10001_adc_power_up(adc_dev);
 
 
 	/* Calculate delay step for eoc and sampled data */
 	/* Calculate delay step for eoc and sampled data */
 	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
 	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
@@ -205,7 +209,8 @@ static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
 
 
 	val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
 	val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
 
 
-	cc10001_adc_power_down(adc_dev);
+	if (!adc_dev->shared)
+		cc10001_adc_power_down(adc_dev);
 
 
 	return val;
 	return val;
 }
 }
@@ -322,8 +327,10 @@ static int cc10001_adc_probe(struct platform_device *pdev)
 	adc_dev = iio_priv(indio_dev);
 	adc_dev = iio_priv(indio_dev);
 
 
 	channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
 	channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
-	if (!of_property_read_u32(node, "adc-reserved-channels", &ret))
+	if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) {
+		adc_dev->shared = true;
 		channel_map &= ~ret;
 		channel_map &= ~ret;
+	}
 
 
 	adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
 	adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
 	if (IS_ERR(adc_dev->reg))
 	if (IS_ERR(adc_dev->reg))
@@ -368,6 +375,14 @@ static int cc10001_adc_probe(struct platform_device *pdev)
 	adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
 	adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
 	adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
 	adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
 
 
+	/*
+	 * There is only one register to power-up/power-down the AUX ADC.
+	 * If the ADC is shared among multiple CPUs, always power it up here.
+	 * If the ADC is used only by the MIPS, power-up/power-down at runtime.
+	 */
+	if (adc_dev->shared)
+		cc10001_adc_power_up(adc_dev);
+
 	/* Setup the ADC channels available on the device */
 	/* Setup the ADC channels available on the device */
 	ret = cc10001_adc_channel_init(indio_dev, channel_map);
 	ret = cc10001_adc_channel_init(indio_dev, channel_map);
 	if (ret < 0)
 	if (ret < 0)
@@ -402,6 +417,7 @@ static int cc10001_adc_remove(struct platform_device *pdev)
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
 	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
 
 
+	cc10001_adc_power_down(adc_dev);
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	iio_triggered_buffer_cleanup(indio_dev);
 	clk_disable_unprepare(adc_dev->adc_clk);
 	clk_disable_unprepare(adc_dev->adc_clk);

+ 15 - 1
drivers/iio/adc/mcp320x.c

@@ -25,6 +25,7 @@
  * http://ww1.microchip.com/downloads/en/DeviceDoc/21290D.pdf  mcp3201
  * http://ww1.microchip.com/downloads/en/DeviceDoc/21290D.pdf  mcp3201
  * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf  mcp3202
  * http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf  mcp3202
  * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf  mcp3204/08
  * http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf  mcp3204/08
+ * http://ww1.microchip.com/downloads/en/DeviceDoc/21700E.pdf  mcp3301
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU General Public License version 2 as
@@ -47,6 +48,7 @@ enum {
 	mcp3202,
 	mcp3202,
 	mcp3204,
 	mcp3204,
 	mcp3208,
 	mcp3208,
+	mcp3301,
 };
 };
 
 
 struct mcp320x_chip_info {
 struct mcp320x_chip_info {
@@ -76,6 +78,7 @@ static int mcp320x_channel_to_tx_data(int device_index,
 	switch (device_index) {
 	switch (device_index) {
 	case mcp3001:
 	case mcp3001:
 	case mcp3201:
 	case mcp3201:
+	case mcp3301:
 		return 0;
 		return 0;
 	case mcp3002:
 	case mcp3002:
 	case mcp3202:
 	case mcp3202:
@@ -102,7 +105,7 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
 	adc->tx_buf = mcp320x_channel_to_tx_data(device_index,
 	adc->tx_buf = mcp320x_channel_to_tx_data(device_index,
 						channel, differential);
 						channel, differential);
 
 
-	if (device_index != mcp3001 && device_index != mcp3201) {
+	if (device_index != mcp3001 && device_index != mcp3201 && device_index != mcp3301) {
 		ret = spi_sync(adc->spi, &adc->msg);
 		ret = spi_sync(adc->spi, &adc->msg);
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			return ret;
@@ -125,6 +128,8 @@ static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
 	case mcp3204:
 	case mcp3204:
 	case mcp3208:
 	case mcp3208:
 		return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4);
 		return (adc->rx_buf[0] << 4 | adc->rx_buf[1] >> 4);
+	case mcp3301:
+		return sign_extend32((adc->rx_buf[0] & 0x1f) << 8 | adc->rx_buf[1], 12);
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -274,6 +279,11 @@ static const struct mcp320x_chip_info mcp320x_chip_infos[] = {
 		.num_channels = ARRAY_SIZE(mcp3208_channels),
 		.num_channels = ARRAY_SIZE(mcp3208_channels),
 		.resolution = 12
 		.resolution = 12
 	},
 	},
+	[mcp3301] = {
+		.channels = mcp3201_channels,
+		.num_channels = ARRAY_SIZE(mcp3201_channels),
+		.resolution = 13
+	},
 };
 };
 
 
 static int mcp320x_probe(struct spi_device *spi)
 static int mcp320x_probe(struct spi_device *spi)
@@ -368,6 +378,9 @@ static const struct of_device_id mcp320x_dt_ids[] = {
 	}, {
 	}, {
 		.compatible = "mcp3208",
 		.compatible = "mcp3208",
 		.data = &mcp320x_chip_infos[mcp3208],
 		.data = &mcp320x_chip_infos[mcp3208],
+	}, {
+		.compatible = "mcp3301",
+		.data = &mcp320x_chip_infos[mcp3301],
 	}, {
 	}, {
 	}
 	}
 };
 };
@@ -383,6 +396,7 @@ static const struct spi_device_id mcp320x_id[] = {
 	{ "mcp3202", mcp3202 },
 	{ "mcp3202", mcp3202 },
 	{ "mcp3204", mcp3204 },
 	{ "mcp3204", mcp3204 },
 	{ "mcp3208", mcp3208 },
 	{ "mcp3208", mcp3208 },
+	{ "mcp3301", mcp3301 },
 	{ }
 	{ }
 };
 };
 MODULE_DEVICE_TABLE(spi, mcp320x_id);
 MODULE_DEVICE_TABLE(spi, mcp320x_id);

+ 0 - 1
drivers/iio/adc/mcp3422.c

@@ -404,7 +404,6 @@ MODULE_DEVICE_TABLE(of, mcp3422_of_match);
 static struct i2c_driver mcp3422_driver = {
 static struct i2c_driver mcp3422_driver = {
 	.driver = {
 	.driver = {
 		.name = "mcp3422",
 		.name = "mcp3422",
-		.owner = THIS_MODULE,
 		.of_match_table = of_match_ptr(mcp3422_of_match),
 		.of_match_table = of_match_ptr(mcp3422_of_match),
 	},
 	},
 	.probe = mcp3422_probe,
 	.probe = mcp3422_probe,

+ 0 - 1
drivers/iio/adc/ti-adc081c.c

@@ -140,7 +140,6 @@ MODULE_DEVICE_TABLE(of, adc081c_of_match);
 static struct i2c_driver adc081c_driver = {
 static struct i2c_driver adc081c_driver = {
 	.driver = {
 	.driver = {
 		.name = "adc081c",
 		.name = "adc081c",
-		.owner = THIS_MODULE,
 		.of_match_table = of_match_ptr(adc081c_of_match),
 		.of_match_table = of_match_ptr(adc081c_of_match),
 	},
 	},
 	.probe = adc081c_probe,
 	.probe = adc081c_probe,

+ 75 - 4
drivers/iio/adc/vf610_adc.c

@@ -68,6 +68,9 @@
 #define VF610_ADC_CLK_DIV8		0x60
 #define VF610_ADC_CLK_DIV8		0x60
 #define VF610_ADC_CLK_MASK		0x60
 #define VF610_ADC_CLK_MASK		0x60
 #define VF610_ADC_ADLSMP_LONG		0x10
 #define VF610_ADC_ADLSMP_LONG		0x10
+#define VF610_ADC_ADSTS_SHORT   0x100
+#define VF610_ADC_ADSTS_NORMAL  0x200
+#define VF610_ADC_ADSTS_LONG    0x300
 #define VF610_ADC_ADSTS_MASK		0x300
 #define VF610_ADC_ADSTS_MASK		0x300
 #define VF610_ADC_ADLPC_EN		0x80
 #define VF610_ADC_ADLPC_EN		0x80
 #define VF610_ADC_ADHSC_EN		0x400
 #define VF610_ADC_ADHSC_EN		0x400
@@ -98,6 +101,8 @@
 #define VF610_ADC_CALF			0x2
 #define VF610_ADC_CALF			0x2
 #define VF610_ADC_TIMEOUT		msecs_to_jiffies(100)
 #define VF610_ADC_TIMEOUT		msecs_to_jiffies(100)
 
 
+#define DEFAULT_SAMPLE_TIME		1000
+
 enum clk_sel {
 enum clk_sel {
 	VF610_ADCIOC_BUSCLK_SET,
 	VF610_ADCIOC_BUSCLK_SET,
 	VF610_ADCIOC_ALTCLK_SET,
 	VF610_ADCIOC_ALTCLK_SET,
@@ -124,6 +129,17 @@ enum conversion_mode_sel {
 	VF610_ADC_CONV_LOW_POWER,
 	VF610_ADC_CONV_LOW_POWER,
 };
 };
 
 
+enum lst_adder_sel {
+	VF610_ADCK_CYCLES_3,
+	VF610_ADCK_CYCLES_5,
+	VF610_ADCK_CYCLES_7,
+	VF610_ADCK_CYCLES_9,
+	VF610_ADCK_CYCLES_13,
+	VF610_ADCK_CYCLES_17,
+	VF610_ADCK_CYCLES_21,
+	VF610_ADCK_CYCLES_25,
+};
+
 struct vf610_adc_feature {
 struct vf610_adc_feature {
 	enum clk_sel	clk_sel;
 	enum clk_sel	clk_sel;
 	enum vol_ref	vol_ref;
 	enum vol_ref	vol_ref;
@@ -132,6 +148,8 @@ struct vf610_adc_feature {
 	int	clk_div;
 	int	clk_div;
 	int     sample_rate;
 	int     sample_rate;
 	int	res_mode;
 	int	res_mode;
+	u32 lst_adder_index;
+	u32 default_sample_time;
 
 
 	bool	calibration;
 	bool	calibration;
 	bool	ovwren;
 	bool	ovwren;
@@ -155,11 +173,13 @@ struct vf610_adc {
 };
 };
 
 
 static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
 static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
+static const u32 vf610_lst_adder[] = { 3, 5, 7, 9, 13, 17, 21, 25 };
 
 
 static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
 static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
 {
 {
 	struct vf610_adc_feature *adc_feature = &info->adc_feature;
 	struct vf610_adc_feature *adc_feature = &info->adc_feature;
 	unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk);
 	unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk);
+	u32 adck_period, lst_addr_min;
 	int divisor, i;
 	int divisor, i;
 
 
 	adck_rate = info->max_adck_rate[adc_feature->conv_mode];
 	adck_rate = info->max_adck_rate[adc_feature->conv_mode];
@@ -173,6 +193,19 @@ static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
 		adc_feature->clk_div = 8;
 		adc_feature->clk_div = 8;
 	}
 	}
 
 
+	/*
+	 * Determine the long sample time adder value to be used based
+	 * on the default minimum sample time provided.
+	 */
+	adck_period = NSEC_PER_SEC / adck_rate;
+	lst_addr_min = adc_feature->default_sample_time / adck_period;
+	for (i = 0; i < ARRAY_SIZE(vf610_lst_adder); i++) {
+		if (vf610_lst_adder[i] > lst_addr_min) {
+			adc_feature->lst_adder_index = i;
+			break;
+		}
+	}
+
 	/*
 	/*
 	 * Calculate ADC sample frequencies
 	 * Calculate ADC sample frequencies
 	 * Sample time unit is ADCK cycles. ADCK clk source is ipg clock,
 	 * Sample time unit is ADCK cycles. ADCK clk source is ipg clock,
@@ -182,12 +215,13 @@ static inline void vf610_adc_calculate_rates(struct vf610_adc *info)
 	 * SFCAdder: fixed to 6 ADCK cycles
 	 * SFCAdder: fixed to 6 ADCK cycles
 	 * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
 	 * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.
 	 * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
 	 * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode
-	 * LSTAdder(Long Sample Time): fixed to 3 ADCK cycles
+	 * LSTAdder(Long Sample Time): 3, 5, 7, 9, 13, 17, 21, 25 ADCK cycles
 	 */
 	 */
 	adck_rate = ipg_rate / info->adc_feature.clk_div;
 	adck_rate = ipg_rate / info->adc_feature.clk_div;
 	for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++)
 	for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++)
 		info->sample_freq_avail[i] =
 		info->sample_freq_avail[i] =
-			adck_rate / (6 + vf610_hw_avgs[i] * (25 + 3));
+			adck_rate / (6 + vf610_hw_avgs[i] *
+			 (25 + vf610_lst_adder[adc_feature->lst_adder_index]));
 }
 }
 
 
 static inline void vf610_adc_cfg_init(struct vf610_adc *info)
 static inline void vf610_adc_cfg_init(struct vf610_adc *info)
@@ -347,8 +381,40 @@ static void vf610_adc_sample_set(struct vf610_adc *info)
 		break;
 		break;
 	}
 	}
 
 
-	/* Use the short sample mode */
-	cfg_data &= ~(VF610_ADC_ADLSMP_LONG | VF610_ADC_ADSTS_MASK);
+	/*
+	 * Set ADLSMP and ADSTS based on the Long Sample Time Adder value
+	 * determined.
+	 */
+	switch (adc_feature->lst_adder_index) {
+	case VF610_ADCK_CYCLES_3:
+		break;
+	case VF610_ADCK_CYCLES_5:
+		cfg_data |= VF610_ADC_ADSTS_SHORT;
+		break;
+	case VF610_ADCK_CYCLES_7:
+		cfg_data |= VF610_ADC_ADSTS_NORMAL;
+		break;
+	case VF610_ADCK_CYCLES_9:
+		cfg_data |= VF610_ADC_ADSTS_LONG;
+		break;
+	case VF610_ADCK_CYCLES_13:
+		cfg_data |= VF610_ADC_ADLSMP_LONG;
+		break;
+	case VF610_ADCK_CYCLES_17:
+		cfg_data |= VF610_ADC_ADLSMP_LONG;
+		cfg_data |= VF610_ADC_ADSTS_SHORT;
+		break;
+	case VF610_ADCK_CYCLES_21:
+		cfg_data |= VF610_ADC_ADLSMP_LONG;
+		cfg_data |= VF610_ADC_ADSTS_NORMAL;
+		break;
+	case VF610_ADCK_CYCLES_25:
+		cfg_data |= VF610_ADC_ADLSMP_LONG;
+		cfg_data |= VF610_ADC_ADSTS_NORMAL;
+		break;
+	default:
+		dev_err(info->dev, "error in sample time select\n");
+	}
 
 
 	/* update hardware average selection */
 	/* update hardware average selection */
 	cfg_data &= ~VF610_ADC_AVGS_MASK;
 	cfg_data &= ~VF610_ADC_AVGS_MASK;
@@ -713,6 +779,11 @@ static int vf610_adc_probe(struct platform_device *pdev)
 	of_property_read_u32_array(pdev->dev.of_node, "fsl,adck-max-frequency",
 	of_property_read_u32_array(pdev->dev.of_node, "fsl,adck-max-frequency",
 			info->max_adck_rate, 3);
 			info->max_adck_rate, 3);
 
 
+	ret = of_property_read_u32(pdev->dev.of_node, "min-sample-time",
+			&info->adc_feature.default_sample_time);
+	if (ret)
+		info->adc_feature.default_sample_time = DEFAULT_SAMPLE_TIME;
+
 	platform_set_drvdata(pdev, indio_dev);
 	platform_set_drvdata(pdev, indio_dev);
 
 
 	init_completion(&info->completion);
 	init_completion(&info->completion);

+ 0 - 1
drivers/iio/common/ssp_sensors/ssp_dev.c

@@ -700,7 +700,6 @@ static struct spi_driver ssp_driver = {
 	.remove = ssp_remove,
 	.remove = ssp_remove,
 	.driver = {
 	.driver = {
 		.pm = &ssp_pm_ops,
 		.pm = &ssp_pm_ops,
-		.bus = &spi_bus_type,
 		.owner = THIS_MODULE,
 		.owner = THIS_MODULE,
 		.of_match_table = of_match_ptr(ssp_of_match),
 		.of_match_table = of_match_ptr(ssp_of_match),
 		.name = "sensorhub"
 		.name = "sensorhub"

+ 26 - 26
drivers/iio/common/st_sensors/st_sensors_core.c

@@ -126,6 +126,9 @@ static int st_sensors_set_fullscale(struct iio_dev *indio_dev, 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);
 
 
+	if (sdata->sensor_settings->fs.addr == 0)
+		return 0;
+
 	err = st_sensors_match_fs(sdata->sensor_settings, fs, &i);
 	err = st_sensors_match_fs(sdata->sensor_settings, fs, &i);
 	if (err < 0)
 	if (err < 0)
 		goto st_accel_set_fullscale_error;
 		goto st_accel_set_fullscale_error;
@@ -479,46 +482,43 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev,
 			int num_sensors_list,
 			int num_sensors_list,
 			const struct st_sensor_settings *sensor_settings)
 			const struct st_sensor_settings *sensor_settings)
 {
 {
-	u8 wai;
 	int i, n, err;
 	int i, n, err;
+	u8 wai;
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
 
 
-	err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
-					ST_SENSORS_DEFAULT_WAI_ADDRESS, &wai);
-	if (err < 0) {
-		dev_err(&indio_dev->dev, "failed to read Who-Am-I register.\n");
-		goto read_wai_error;
-	}
-
 	for (i = 0; i < num_sensors_list; i++) {
 	for (i = 0; i < num_sensors_list; i++) {
-		if (sensor_settings[i].wai == wai)
+		for (n = 0; n < ST_SENSORS_MAX_4WAI; n++) {
+			if (strcmp(indio_dev->name,
+				sensor_settings[i].sensors_supported[n]) == 0) {
+				break;
+			}
+		}
+		if (n < ST_SENSORS_MAX_4WAI)
 			break;
 			break;
 	}
 	}
-	if (i == num_sensors_list)
-		goto device_not_supported;
+	if (i == num_sensors_list) {
+		dev_err(&indio_dev->dev, "device name %s not recognized.\n",
+							indio_dev->name);
+		return -ENODEV;
+	}
 
 
-	for (n = 0; n < ARRAY_SIZE(sensor_settings[i].sensors_supported); n++) {
-		if (strcmp(indio_dev->name,
-				&sensor_settings[i].sensors_supported[n][0]) == 0)
-			break;
+	err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
+					sensor_settings[i].wai_addr, &wai);
+	if (err < 0) {
+		dev_err(&indio_dev->dev, "failed to read Who-Am-I register.\n");
+		return err;
 	}
 	}
-	if (n == ARRAY_SIZE(sensor_settings[i].sensors_supported)) {
-		dev_err(&indio_dev->dev, "device name \"%s\" and WhoAmI (0x%02x) mismatch",
-			indio_dev->name, wai);
-		goto sensor_name_mismatch;
+
+	if (sensor_settings[i].wai != wai) {
+		dev_err(&indio_dev->dev, "%s: WhoAmI mismatch (0x%x).\n",
+						indio_dev->name, wai);
+		return -EINVAL;
 	}
 	}
 
 
 	sdata->sensor_settings =
 	sdata->sensor_settings =
 			(struct st_sensor_settings *)&sensor_settings[i];
 			(struct st_sensor_settings *)&sensor_settings[i];
 
 
 	return i;
 	return i;
-
-device_not_supported:
-	dev_err(&indio_dev->dev, "device not supported: WhoAmI (0x%x).\n", wai);
-sensor_name_mismatch:
-	err = -ENODEV;
-read_wai_error:
-	return err;
 }
 }
 EXPORT_SYMBOL(st_sensors_check_device_support);
 EXPORT_SYMBOL(st_sensors_check_device_support);
 
 

+ 0 - 1
drivers/iio/dac/ad5064.c

@@ -630,7 +630,6 @@ MODULE_DEVICE_TABLE(i2c, ad5064_i2c_ids);
 static struct i2c_driver ad5064_i2c_driver = {
 static struct i2c_driver ad5064_i2c_driver = {
 	.driver = {
 	.driver = {
 		   .name = "ad5064",
 		   .name = "ad5064",
-		   .owner = THIS_MODULE,
 	},
 	},
 	.probe = ad5064_i2c_probe,
 	.probe = ad5064_i2c_probe,
 	.remove = ad5064_i2c_remove,
 	.remove = ad5064_i2c_remove,

+ 0 - 1
drivers/iio/dac/ad5380.c

@@ -593,7 +593,6 @@ MODULE_DEVICE_TABLE(i2c, ad5380_i2c_ids);
 static struct i2c_driver ad5380_i2c_driver = {
 static struct i2c_driver ad5380_i2c_driver = {
 	.driver = {
 	.driver = {
 		   .name = "ad5380",
 		   .name = "ad5380",
-		   .owner = THIS_MODULE,
 	},
 	},
 	.probe = ad5380_i2c_probe,
 	.probe = ad5380_i2c_probe,
 	.remove = ad5380_i2c_remove,
 	.remove = ad5380_i2c_remove,

+ 0 - 1
drivers/iio/dac/ad5446.c

@@ -569,7 +569,6 @@ MODULE_DEVICE_TABLE(i2c, ad5446_i2c_ids);
 static struct i2c_driver ad5446_i2c_driver = {
 static struct i2c_driver ad5446_i2c_driver = {
 	.driver = {
 	.driver = {
 		   .name = "ad5446",
 		   .name = "ad5446",
-		   .owner = THIS_MODULE,
 	},
 	},
 	.probe = ad5446_i2c_probe,
 	.probe = ad5446_i2c_probe,
 	.remove = ad5446_i2c_remove,
 	.remove = ad5446_i2c_remove,

+ 0 - 1
drivers/iio/dac/max5821.c

@@ -392,7 +392,6 @@ static struct i2c_driver max5821_driver = {
 	.driver = {
 	.driver = {
 		.name	= "max5821",
 		.name	= "max5821",
 		.pm     = MAX5821_PM_OPS,
 		.pm     = MAX5821_PM_OPS,
-		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= max5821_probe,
 	.probe		= max5821_probe,
 	.remove		= max5821_remove,
 	.remove		= max5821_remove,

+ 0 - 1
drivers/iio/frequency/adf4350.c

@@ -72,7 +72,6 @@ static int adf4350_sync_config(struct adf4350_state *st)
 	for (i = ADF4350_REG5; i >= ADF4350_REG0; i--) {
 	for (i = ADF4350_REG5; i >= ADF4350_REG0; i--) {
 		if ((st->regs_hw[i] != st->regs[i]) ||
 		if ((st->regs_hw[i] != st->regs[i]) ||
 			((i == ADF4350_REG0) && doublebuf)) {
 			((i == ADF4350_REG0) && doublebuf)) {
-
 			switch (i) {
 			switch (i) {
 			case ADF4350_REG1:
 			case ADF4350_REG1:
 			case ADF4350_REG4:
 			case ADF4350_REG4:

+ 2 - 1
drivers/iio/gyro/Kconfig

@@ -53,7 +53,8 @@ config ADXRS450
 config BMG160
 config BMG160
 	tristate "BOSCH BMG160 Gyro Sensor"
 	tristate "BOSCH BMG160 Gyro Sensor"
 	depends on I2C
 	depends on I2C
-	select IIO_TRIGGERED_BUFFER if IIO_BUFFER
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	help
 	  Say yes here to build support for Bosch BMG160 Tri-axis Gyro Sensor
 	  Say yes here to build support for Bosch BMG160 Tri-axis Gyro Sensor
 	  driver. This driver also supports BMI055 gyroscope.
 	  driver. This driver also supports BMI055 gyroscope.

+ 6 - 0
drivers/iio/gyro/adis16136.c

@@ -473,6 +473,7 @@ enum adis16136_id {
 	ID_ADIS16133,
 	ID_ADIS16133,
 	ID_ADIS16135,
 	ID_ADIS16135,
 	ID_ADIS16136,
 	ID_ADIS16136,
+	ID_ADIS16137,
 };
 };
 
 
 static const struct adis16136_chip_info adis16136_chip_info[] = {
 static const struct adis16136_chip_info adis16136_chip_info[] = {
@@ -488,6 +489,10 @@ static const struct adis16136_chip_info adis16136_chip_info[] = {
 		.precision = IIO_DEGREE_TO_RAD(450),
 		.precision = IIO_DEGREE_TO_RAD(450),
 		.fullscale = 24623,
 		.fullscale = 24623,
 	},
 	},
+	[ID_ADIS16137] = {
+		.precision = IIO_DEGREE_TO_RAD(1000),
+		.fullscale = 24609,
+	},
 };
 };
 
 
 static int adis16136_probe(struct spi_device *spi)
 static int adis16136_probe(struct spi_device *spi)
@@ -557,6 +562,7 @@ static const struct spi_device_id adis16136_ids[] = {
 	{ "adis16133", ID_ADIS16133 },
 	{ "adis16133", ID_ADIS16133 },
 	{ "adis16135", ID_ADIS16135 },
 	{ "adis16135", ID_ADIS16135 },
 	{ "adis16136", ID_ADIS16136 },
 	{ "adis16136", ID_ADIS16136 },
+	{ "adis16137", ID_ADIS16137 },
 	{ }
 	{ }
 };
 };
 MODULE_DEVICE_TABLE(spi, adis16136_ids);
 MODULE_DEVICE_TABLE(spi, adis16136_ids);

+ 98 - 39
drivers/iio/gyro/adis16260.c

@@ -101,19 +101,24 @@
 #define ADIS16260_SCAN_TEMP	3
 #define ADIS16260_SCAN_TEMP	3
 #define ADIS16260_SCAN_ANGL	4
 #define ADIS16260_SCAN_ANGL	4
 
 
-/* Power down the device */
-static int adis16260_stop_device(struct iio_dev *indio_dev)
-{
-	struct adis *adis = iio_priv(indio_dev);
-	int ret;
-	u16 val = ADIS16260_SLP_CNT_POWER_OFF;
+struct adis16260_chip_info {
+	unsigned int gyro_max_val;
+	unsigned int gyro_max_scale;
+	const struct iio_chan_spec *channels;
+	unsigned int num_channels;
+};
 
 
-	ret = adis_write_reg_16(adis, ADIS16260_SLP_CNT, val);
-	if (ret)
-		dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
+struct adis16260 {
+	const struct adis16260_chip_info *info;
 
 
-	return ret;
-}
+	struct adis adis;
+};
+
+enum adis16260_type {
+	ADIS16251,
+	ADIS16260,
+	ADIS16266,
+};
 
 
 static const struct iio_chan_spec adis16260_channels[] = {
 static const struct iio_chan_spec adis16260_channels[] = {
 	ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO,
 	ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO,
@@ -131,6 +136,55 @@ static const struct iio_chan_spec adis16260_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(5),
 	IIO_CHAN_SOFT_TIMESTAMP(5),
 };
 };
 
 
+static const struct iio_chan_spec adis16266_channels[] = {
+	ADIS_GYRO_CHAN(X, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO,
+		BIT(IIO_CHAN_INFO_CALIBBIAS) |
+		BIT(IIO_CHAN_INFO_CALIBSCALE),
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 14),
+	ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 12),
+	ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 12),
+	ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC,
+		BIT(IIO_CHAN_INFO_SAMP_FREQ), 12),
+	IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static const struct adis16260_chip_info adis16260_chip_info_table[] = {
+	[ADIS16251] = {
+		.gyro_max_scale = 80,
+		.gyro_max_val = IIO_RAD_TO_DEGREE(4368),
+		.channels = adis16260_channels,
+		.num_channels = ARRAY_SIZE(adis16260_channels),
+	},
+	[ADIS16260] = {
+		.gyro_max_scale = 320,
+		.gyro_max_val = IIO_RAD_TO_DEGREE(4368),
+		.channels = adis16260_channels,
+		.num_channels = ARRAY_SIZE(adis16260_channels),
+	},
+	[ADIS16266] = {
+		.gyro_max_scale = 14000,
+		.gyro_max_val = IIO_RAD_TO_DEGREE(3357),
+		.channels = adis16266_channels,
+		.num_channels = ARRAY_SIZE(adis16266_channels),
+	},
+};
+
+/* Power down the device */
+static int adis16260_stop_device(struct iio_dev *indio_dev)
+{
+	struct adis16260 *adis16260 = iio_priv(indio_dev);
+	int ret;
+	u16 val = ADIS16260_SLP_CNT_POWER_OFF;
+
+	ret = adis_write_reg_16(&adis16260->adis, ADIS16260_SLP_CNT, val);
+	if (ret)
+		dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
+
+	return ret;
+}
+
 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 },
 };
 };
@@ -140,7 +194,9 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
 			      int *val, int *val2,
 			      int *val, int *val2,
 			      long mask)
 			      long mask)
 {
 {
-	struct adis *adis = iio_priv(indio_dev);
+	struct adis16260 *adis16260 = iio_priv(indio_dev);
+	const struct adis16260_chip_info *info = adis16260->info;
+	struct adis *adis = &adis16260->adis;
 	int ret;
 	int ret;
 	u8 addr;
 	u8 addr;
 	s16 val16;
 	s16 val16;
@@ -152,15 +208,9 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		switch (chan->type) {
 		case IIO_ANGL_VEL:
 		case IIO_ANGL_VEL:
-			*val = 0;
-			if (spi_get_device_id(adis->spi)->driver_data) {
-				/* 0.01832 degree / sec */
-				*val2 = IIO_DEGREE_TO_RAD(18320);
-			} else {
-				/* 0.07326 degree / sec */
-				*val2 = IIO_DEGREE_TO_RAD(73260);
-			}
-			return IIO_VAL_INT_PLUS_MICRO;
+			*val = info->gyro_max_scale;
+			*val2 = info->gyro_max_val;
+			return IIO_VAL_FRACTIONAL;
 		case IIO_INCLI:
 		case IIO_INCLI:
 			*val = 0;
 			*val = 0;
 			*val2 = IIO_DEGREE_TO_RAD(36630);
 			*val2 = IIO_DEGREE_TO_RAD(36630);
@@ -224,7 +274,8 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
 			       int val2,
 			       int val2,
 			       long mask)
 			       long mask)
 {
 {
-	struct adis *adis = iio_priv(indio_dev);
+	struct adis16260 *adis16260 = iio_priv(indio_dev);
+	struct adis *adis = &adis16260->adis;
 	int ret;
 	int ret;
 	u8 addr;
 	u8 addr;
 	u8 t;
 	u8 t;
@@ -305,35 +356,42 @@ static const struct adis_data adis16260_data = {
 
 
 static int adis16260_probe(struct spi_device *spi)
 static int adis16260_probe(struct spi_device *spi)
 {
 {
+	const struct spi_device_id *id;
+	struct adis16260 *adis16260;
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
-	struct adis *adis;
 	int ret;
 	int ret;
 
 
+	id = spi_get_device_id(spi);
+	if (!id)
+		return -ENODEV;
+
 	/* setup the industrialio driver allocated elements */
 	/* setup the industrialio driver allocated elements */
-	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis));
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis16260));
 	if (!indio_dev)
 	if (!indio_dev)
 		return -ENOMEM;
 		return -ENOMEM;
-	adis = iio_priv(indio_dev);
+	adis16260 = 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;
+	adis16260->info = &adis16260_chip_info_table[id->driver_data];
+
+	indio_dev->name = id->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->channels = adis16260_channels;
-	indio_dev->num_channels = ARRAY_SIZE(adis16260_channels);
+	indio_dev->channels = adis16260->info->channels;
+	indio_dev->num_channels = adis16260->info->num_channels;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
 
-	ret = adis_init(adis, indio_dev, spi, &adis16260_data);
+	ret = adis_init(&adis16260->adis, indio_dev, spi, &adis16260_data);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
-	ret = adis_setup_buffer_and_trigger(adis, indio_dev, NULL);
+	ret = adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
 	/* Get the device into a sane initial state */
 	/* Get the device into a sane initial state */
-	ret = adis_initial_startup(adis);
+	ret = adis_initial_startup(&adis16260->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);
@@ -343,18 +401,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(adis, indio_dev);
+	adis_cleanup_buffer_and_trigger(&adis16260->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 adis *adis = iio_priv(indio_dev);
+	struct adis16260 *adis16260 = 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(adis, indio_dev);
+	adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -364,11 +422,12 @@ static int adis16260_remove(struct spi_device *spi)
  * support for the on chip filtering.
  * support for the on chip filtering.
  */
  */
 static const struct spi_device_id adis16260_id[] = {
 static const struct spi_device_id adis16260_id[] = {
-	{"adis16260", 0},
-	{"adis16265", 0},
-	{"adis16250", 0},
-	{"adis16255", 0},
-	{"adis16251", 1},
+	{"adis16260", ADIS16260},
+	{"adis16265", ADIS16260},
+	{"adis16266", ADIS16266},
+	{"adis16250", ADIS16260},
+	{"adis16255", ADIS16260},
+	{"adis16251", ADIS16251},
 	{}
 	{}
 };
 };
 MODULE_DEVICE_TABLE(spi, adis16260_id);
 MODULE_DEVICE_TABLE(spi, adis16260_id);

+ 0 - 1
drivers/iio/gyro/itg3200_core.c

@@ -379,7 +379,6 @@ MODULE_DEVICE_TABLE(i2c, itg3200_id);
 
 
 static struct i2c_driver itg3200_driver = {
 static struct i2c_driver itg3200_driver = {
 	.driver = {
 	.driver = {
-		.owner  = THIS_MODULE,
 		.name	= "itg3200",
 		.name	= "itg3200",
 		.pm	= &itg3200_pm_ops,
 		.pm	= &itg3200_pm_ops,
 	},
 	},

+ 3 - 0
drivers/iio/gyro/st_gyro_core.c

@@ -131,6 +131,7 @@ static const struct iio_chan_spec st_gyro_16bit_channels[] = {
 static const struct st_sensor_settings st_gyro_sensors_settings[] = {
 static const struct st_sensor_settings st_gyro_sensors_settings[] = {
 	{
 	{
 		.wai = ST_GYRO_1_WAI_EXP,
 		.wai = ST_GYRO_1_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = L3G4200D_GYRO_DEV_NAME,
 			[0] = L3G4200D_GYRO_DEV_NAME,
 			[1] = LSM330DL_GYRO_DEV_NAME,
 			[1] = LSM330DL_GYRO_DEV_NAME,
@@ -190,6 +191,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_GYRO_2_WAI_EXP,
 		.wai = ST_GYRO_2_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = L3GD20_GYRO_DEV_NAME,
 			[0] = L3GD20_GYRO_DEV_NAME,
 			[1] = LSM330D_GYRO_DEV_NAME,
 			[1] = LSM330D_GYRO_DEV_NAME,
@@ -252,6 +254,7 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_GYRO_3_WAI_EXP,
 		.wai = ST_GYRO_3_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = L3GD20_GYRO_DEV_NAME,
 			[0] = L3GD20_GYRO_DEV_NAME,
 		},
 		},

+ 0 - 1
drivers/iio/gyro/st_gyro_i2c.c

@@ -99,7 +99,6 @@ MODULE_DEVICE_TABLE(i2c, st_gyro_id_table);
 
 
 static struct i2c_driver st_gyro_driver = {
 static struct i2c_driver st_gyro_driver = {
 	.driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name = "st-gyro-i2c",
 		.name = "st-gyro-i2c",
 		.of_match_table = of_match_ptr(st_gyro_of_match),
 		.of_match_table = of_match_ptr(st_gyro_of_match),
 	},
 	},

+ 35 - 30
drivers/iio/humidity/dht11.c

@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
+#include <linux/timekeeping.h>
 
 
 #include <linux/iio/iio.h>
 #include <linux/iio/iio.h>
 
 
@@ -46,7 +47,8 @@
  * Note that when reading the sensor actually 84 edges are detected, but
  * Note that when reading the sensor actually 84 edges are detected, but
  * since the last edge is not significant, we only store 83:
  * since the last edge is not significant, we only store 83:
  */
  */
-#define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1)
+#define DHT11_EDGES_PER_READ (2 * DHT11_BITS_PER_READ + \
+			      DHT11_EDGES_PREAMBLE + 1)
 
 
 /* Data transmission timing (nano seconds) */
 /* Data transmission timing (nano seconds) */
 #define DHT11_START_TRANSMISSION	18  /* ms */
 #define DHT11_START_TRANSMISSION	18  /* ms */
@@ -62,6 +64,7 @@ struct dht11 {
 	int				irq;
 	int				irq;
 
 
 	struct completion		completion;
 	struct completion		completion;
+	/* The iio sysfs interface doesn't prevent concurrent reads: */
 	struct mutex			lock;
 	struct mutex			lock;
 
 
 	s64				timestamp;
 	s64				timestamp;
@@ -87,32 +90,20 @@ static unsigned char dht11_decode_byte(int *timing, int threshold)
 	return ret;
 	return ret;
 }
 }
 
 
-static int dht11_decode(struct dht11 *dht11, int offset)
+static int dht11_decode(struct dht11 *dht11, int offset, int timeres)
 {
 {
-	int i, t, timing[DHT11_BITS_PER_READ], threshold,
-		timeres = DHT11_SENSOR_RESPONSE;
+	int i, t, timing[DHT11_BITS_PER_READ], threshold;
 	unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum;
 	unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum;
 
 
-	/* Calculate timestamp resolution */
-	for (i = 1; i < dht11->num_edges; ++i) {
-		t = dht11->edges[i].ts - dht11->edges[i-1].ts;
-		if (t > 0 && t < timeres)
-			timeres = t;
-	}
-	if (2*timeres > DHT11_DATA_BIT_HIGH) {
-		pr_err("dht11: timeresolution %d too bad for decoding\n",
-			timeres);
-		return -EIO;
-	}
 	threshold = DHT11_DATA_BIT_HIGH / timeres;
 	threshold = DHT11_DATA_BIT_HIGH / timeres;
-	if (DHT11_DATA_BIT_LOW/timeres + 1 >= threshold)
+	if (DHT11_DATA_BIT_LOW / timeres + 1 >= threshold)
 		pr_err("dht11: WARNING: decoding ambiguous\n");
 		pr_err("dht11: WARNING: decoding ambiguous\n");
 
 
 	/* scale down with timeres and check validity */
 	/* scale down with timeres and check validity */
 	for (i = 0; i < DHT11_BITS_PER_READ; ++i) {
 	for (i = 0; i < DHT11_BITS_PER_READ; ++i) {
-		t = dht11->edges[offset + 2*i + 2].ts -
-			dht11->edges[offset + 2*i + 1].ts;
-		if (!dht11->edges[offset + 2*i + 1].value)
+		t = dht11->edges[offset + 2 * i + 2].ts -
+			dht11->edges[offset + 2 * i + 1].ts;
+		if (!dht11->edges[offset + 2 * i + 1].value)
 			return -EIO;  /* lost synchronisation */
 			return -EIO;  /* lost synchronisation */
 		timing[i] = t / timeres;
 		timing[i] = t / timeres;
 	}
 	}
@@ -126,7 +117,7 @@ static int dht11_decode(struct dht11 *dht11, int offset)
 	if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum)
 	if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum)
 		return -EIO;
 		return -EIO;
 
 
-	dht11->timestamp = iio_get_time_ns();
+	dht11->timestamp = ktime_get_real_ns();
 	if (hum_int < 20) {  /* DHT22 */
 	if (hum_int < 20) {  /* DHT22 */
 		dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) *
 		dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) *
 					((temp_int & 0x80) ? -100 : 100);
 					((temp_int & 0x80) ? -100 : 100);
@@ -154,7 +145,7 @@ static irqreturn_t dht11_handle_irq(int irq, void *data)
 
 
 	/* TODO: Consider making the handler safe for IRQ sharing */
 	/* TODO: Consider making the handler safe for IRQ sharing */
 	if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) {
 	if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) {
-		dht11->edges[dht11->num_edges].ts = iio_get_time_ns();
+		dht11->edges[dht11->num_edges].ts = ktime_get_real_ns();
 		dht11->edges[dht11->num_edges++].value =
 		dht11->edges[dht11->num_edges++].value =
 						gpio_get_value(dht11->gpio);
 						gpio_get_value(dht11->gpio);
 
 
@@ -166,14 +157,26 @@ static irqreturn_t dht11_handle_irq(int irq, void *data)
 }
 }
 
 
 static int dht11_read_raw(struct iio_dev *iio_dev,
 static int dht11_read_raw(struct iio_dev *iio_dev,
-			const struct iio_chan_spec *chan,
+			  const struct iio_chan_spec *chan,
 			int *val, int *val2, long m)
 			int *val, int *val2, long m)
 {
 {
 	struct dht11 *dht11 = iio_priv(iio_dev);
 	struct dht11 *dht11 = iio_priv(iio_dev);
-	int ret;
+	int ret, timeres;
 
 
 	mutex_lock(&dht11->lock);
 	mutex_lock(&dht11->lock);
-	if (dht11->timestamp + DHT11_DATA_VALID_TIME < iio_get_time_ns()) {
+	if (dht11->timestamp + DHT11_DATA_VALID_TIME < ktime_get_real_ns()) {
+		timeres = ktime_get_resolution_ns();
+		if (DHT11_DATA_BIT_HIGH < 2 * timeres) {
+			dev_err(dht11->dev, "timeresolution %dns too low\n",
+				timeres);
+			/* In theory a better clock could become available
+			 * at some point ... and there is no error code
+			 * that really fits better.
+			 */
+			ret = -EAGAIN;
+			goto err;
+		}
+
 		reinit_completion(&dht11->completion);
 		reinit_completion(&dht11->completion);
 
 
 		dht11->num_edges = 0;
 		dht11->num_edges = 0;
@@ -192,13 +195,13 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
 			goto err;
 			goto err;
 
 
 		ret = wait_for_completion_killable_timeout(&dht11->completion,
 		ret = wait_for_completion_killable_timeout(&dht11->completion,
-								 HZ);
+							   HZ);
 
 
 		free_irq(dht11->irq, iio_dev);
 		free_irq(dht11->irq, iio_dev);
 
 
 		if (ret == 0 && dht11->num_edges < DHT11_EDGES_PER_READ - 1) {
 		if (ret == 0 && dht11->num_edges < DHT11_EDGES_PER_READ - 1) {
 			dev_err(&iio_dev->dev,
 			dev_err(&iio_dev->dev,
-					"Only %d signal edges detected\n",
+				"Only %d signal edges detected\n",
 					dht11->num_edges);
 					dht11->num_edges);
 			ret = -ETIMEDOUT;
 			ret = -ETIMEDOUT;
 		}
 		}
@@ -206,9 +209,10 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
 			goto err;
 			goto err;
 
 
 		ret = dht11_decode(dht11,
 		ret = dht11_decode(dht11,
-				dht11->num_edges == DHT11_EDGES_PER_READ ?
+				   dht11->num_edges == DHT11_EDGES_PER_READ ?
 					DHT11_EDGES_PREAMBLE :
 					DHT11_EDGES_PREAMBLE :
-					DHT11_EDGES_PREAMBLE - 2);
+					DHT11_EDGES_PREAMBLE - 2,
+				timeres);
 		if (ret)
 		if (ret)
 			goto err;
 			goto err;
 	}
 	}
@@ -261,9 +265,10 @@ static int dht11_probe(struct platform_device *pdev)
 	dht11 = iio_priv(iio);
 	dht11 = iio_priv(iio);
 	dht11->dev = dev;
 	dht11->dev = dev;
 
 
-	dht11->gpio = ret = of_get_gpio(node, 0);
+	ret = of_get_gpio(node, 0);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
+	dht11->gpio = ret;
 	ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name);
 	ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
@@ -274,7 +279,7 @@ static int dht11_probe(struct platform_device *pdev)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	dht11->timestamp = iio_get_time_ns() - DHT11_DATA_VALID_TIME - 1;
+	dht11->timestamp = ktime_get_real_ns() - DHT11_DATA_VALID_TIME - 1;
 	dht11->num_edges = -1;
 	dht11->num_edges = -1;
 
 
 	platform_set_drvdata(pdev, iio);
 	platform_set_drvdata(pdev, iio);

+ 0 - 1
drivers/iio/humidity/si7005.c

@@ -177,7 +177,6 @@ MODULE_DEVICE_TABLE(i2c, si7005_id);
 static struct i2c_driver si7005_driver = {
 static struct i2c_driver si7005_driver = {
 	.driver = {
 	.driver = {
 		.name	= "si7005",
 		.name	= "si7005",
-		.owner	= THIS_MODULE,
 	},
 	},
 	.probe = si7005_probe,
 	.probe = si7005_probe,
 	.id_table = si7005_id,
 	.id_table = si7005_id,

+ 44 - 2
drivers/iio/imu/adis16400_core.c

@@ -139,7 +139,9 @@ enum adis16400_chip_variant {
 	ADIS16360,
 	ADIS16360,
 	ADIS16362,
 	ADIS16362,
 	ADIS16364,
 	ADIS16364,
+	ADIS16367,
 	ADIS16400,
 	ADIS16400,
+	ADIS16445,
 	ADIS16448,
 	ADIS16448,
 };
 };
 
 
@@ -622,6 +624,17 @@ static const struct iio_chan_spec adis16400_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP),
 	IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP),
 };
 };
 
 
+static const struct iio_chan_spec adis16445_channels[] = {
+	ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 16),
+	ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 16),
+	ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 16),
+	ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 16),
+	ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 16),
+	ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 16),
+	ADIS16400_TEMP_CHAN(ADIS16448_TEMP_OUT, 12),
+	IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP),
+};
+
 static const struct iio_chan_spec adis16448_channels[] = {
 static const struct iio_chan_spec adis16448_channels[] = {
 	ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 16),
 	ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 16),
 	ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 16),
 	ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 16),
@@ -696,7 +709,8 @@ static struct adis16400_chip_info adis16400_chips[] = {
 	[ADIS16300] = {
 	[ADIS16300] = {
 		.channels = adis16300_channels,
 		.channels = adis16300_channels,
 		.num_channels = ARRAY_SIZE(adis16300_channels),
 		.num_channels = ARRAY_SIZE(adis16300_channels),
-		.flags = ADIS16400_HAS_SLOW_MODE,
+		.flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE |
+				ADIS16400_HAS_SERIAL_NUMBER,
 		.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
 		.gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
 		.accel_scale_micro = 5884,
 		.accel_scale_micro = 5884,
 		.temp_scale_nano = 140000000, /* 0.14 C */
 		.temp_scale_nano = 140000000, /* 0.14 C */
@@ -763,6 +777,18 @@ static struct adis16400_chip_info adis16400_chips[] = {
 		.set_freq = adis16400_set_freq,
 		.set_freq = adis16400_set_freq,
 		.get_freq = adis16400_get_freq,
 		.get_freq = adis16400_get_freq,
 	},
 	},
+	[ADIS16367] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE |
+				ADIS16400_HAS_SERIAL_NUMBER,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(2000), /* 0.2 deg/s */
+		.accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
+		.temp_scale_nano = 136000000, /* 0.136 C */
+		.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
+		.set_freq = adis16400_set_freq,
+		.get_freq = adis16400_get_freq,
+	},
 	[ADIS16400] = {
 	[ADIS16400] = {
 		.channels = adis16400_channels,
 		.channels = adis16400_channels,
 		.num_channels = ARRAY_SIZE(adis16400_channels),
 		.num_channels = ARRAY_SIZE(adis16400_channels),
@@ -774,13 +800,26 @@ static struct adis16400_chip_info adis16400_chips[] = {
 		.set_freq = adis16400_set_freq,
 		.set_freq = adis16400_set_freq,
 		.get_freq = adis16400_get_freq,
 		.get_freq = adis16400_get_freq,
 	},
 	},
+	[ADIS16445] = {
+		.channels = adis16445_channels,
+		.num_channels = ARRAY_SIZE(adis16445_channels),
+		.flags = ADIS16400_HAS_PROD_ID |
+				ADIS16400_HAS_SERIAL_NUMBER |
+				ADIS16400_BURST_DIAG_STAT,
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(10000), /* 0.01 deg/s */
+		.accel_scale_micro = IIO_G_TO_M_S_2(250), /* 1/4000 g */
+		.temp_scale_nano = 73860000, /* 0.07386 C */
+		.temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
+		.set_freq = adis16334_set_freq,
+		.get_freq = adis16334_get_freq,
+	},
 	[ADIS16448] = {
 	[ADIS16448] = {
 		.channels = adis16448_channels,
 		.channels = adis16448_channels,
 		.num_channels = ARRAY_SIZE(adis16448_channels),
 		.num_channels = ARRAY_SIZE(adis16448_channels),
 		.flags = ADIS16400_HAS_PROD_ID |
 		.flags = ADIS16400_HAS_PROD_ID |
 				ADIS16400_HAS_SERIAL_NUMBER |
 				ADIS16400_HAS_SERIAL_NUMBER |
 				ADIS16400_BURST_DIAG_STAT,
 				ADIS16400_BURST_DIAG_STAT,
-		.gyro_scale_micro = IIO_DEGREE_TO_RAD(10000), /* 0.01 deg/s */
+		.gyro_scale_micro = IIO_DEGREE_TO_RAD(40000), /* 0.04 deg/s */
 		.accel_scale_micro = IIO_G_TO_M_S_2(833), /* 1/1200 g */
 		.accel_scale_micro = IIO_G_TO_M_S_2(833), /* 1/1200 g */
 		.temp_scale_nano = 73860000, /* 0.07386 C */
 		.temp_scale_nano = 73860000, /* 0.07386 C */
 		.temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
 		.temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
@@ -926,6 +965,7 @@ static int adis16400_remove(struct spi_device *spi)
 
 
 static const struct spi_device_id adis16400_id[] = {
 static const struct spi_device_id adis16400_id[] = {
 	{"adis16300", ADIS16300},
 	{"adis16300", ADIS16300},
+	{"adis16305", ADIS16300},
 	{"adis16334", ADIS16334},
 	{"adis16334", ADIS16334},
 	{"adis16350", ADIS16350},
 	{"adis16350", ADIS16350},
 	{"adis16354", ADIS16350},
 	{"adis16354", ADIS16350},
@@ -934,8 +974,10 @@ static const struct spi_device_id adis16400_id[] = {
 	{"adis16362", ADIS16362},
 	{"adis16362", ADIS16362},
 	{"adis16364", ADIS16364},
 	{"adis16364", ADIS16364},
 	{"adis16365", ADIS16360},
 	{"adis16365", ADIS16360},
+	{"adis16367", ADIS16367},
 	{"adis16400", ADIS16400},
 	{"adis16400", ADIS16400},
 	{"adis16405", ADIS16400},
 	{"adis16405", ADIS16400},
+	{"adis16445", ADIS16445},
 	{"adis16448", ADIS16448},
 	{"adis16448", ADIS16448},
 	{}
 	{}
 };
 };

+ 33 - 6
drivers/iio/imu/adis16480.c

@@ -110,6 +110,10 @@
 struct adis16480_chip_info {
 struct adis16480_chip_info {
 	unsigned int num_channels;
 	unsigned int num_channels;
 	const struct iio_chan_spec *channels;
 	const struct iio_chan_spec *channels;
+	unsigned int gyro_max_val;
+	unsigned int gyro_max_scale;
+	unsigned int accel_max_val;
+	unsigned int accel_max_scale;
 };
 };
 
 
 struct adis16480 {
 struct adis16480 {
@@ -497,19 +501,21 @@ static int adis16480_set_filter_freq(struct iio_dev *indio_dev,
 static int adis16480_read_raw(struct iio_dev *indio_dev,
 static int adis16480_read_raw(struct iio_dev *indio_dev,
 	const struct iio_chan_spec *chan, int *val, int *val2, long info)
 	const struct iio_chan_spec *chan, int *val, int *val2, long info)
 {
 {
+	struct adis16480 *st = iio_priv(indio_dev);
+
 	switch (info) {
 	switch (info) {
 	case IIO_CHAN_INFO_RAW:
 	case IIO_CHAN_INFO_RAW:
 		return adis_single_conversion(indio_dev, chan, 0, val);
 		return adis_single_conversion(indio_dev, chan, 0, val);
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_SCALE:
 		switch (chan->type) {
 		switch (chan->type) {
 		case IIO_ANGL_VEL:
 		case IIO_ANGL_VEL:
-			*val = 0;
-			*val2 = IIO_DEGREE_TO_RAD(20000); /* 0.02 degree/sec */
-			return IIO_VAL_INT_PLUS_MICRO;
+			*val = st->chip_info->gyro_max_scale;
+			*val2 = st->chip_info->gyro_max_val;
+			return IIO_VAL_FRACTIONAL;
 		case IIO_ACCEL:
 		case IIO_ACCEL:
-			*val = 0;
-			*val2 = IIO_G_TO_M_S_2(800); /* 0.8 mg */
-			return IIO_VAL_INT_PLUS_MICRO;
+			*val = st->chip_info->accel_max_scale;
+			*val2 = st->chip_info->accel_max_val;
+			return IIO_VAL_FRACTIONAL;
 		case IIO_MAGN:
 		case IIO_MAGN:
 			*val = 0;
 			*val = 0;
 			*val2 = 100; /* 0.0001 gauss */
 			*val2 = 100; /* 0.0001 gauss */
@@ -674,18 +680,39 @@ static const struct adis16480_chip_info adis16480_chip_info[] = {
 	[ADIS16375] = {
 	[ADIS16375] = {
 		.channels = adis16485_channels,
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
 		.num_channels = ARRAY_SIZE(adis16485_channels),
+		/*
+		 * storing the value in rad/degree and the scale in degree
+		 * gives us the result in rad and better precession than
+		 * storing the scale directly in rad.
+		 */
+		.gyro_max_val = IIO_RAD_TO_DEGREE(22887),
+		.gyro_max_scale = 300,
+		.accel_max_val = IIO_M_S_2_TO_G(21973),
+		.accel_max_scale = 18,
 	},
 	},
 	[ADIS16480] = {
 	[ADIS16480] = {
 		.channels = adis16480_channels,
 		.channels = adis16480_channels,
 		.num_channels = ARRAY_SIZE(adis16480_channels),
 		.num_channels = ARRAY_SIZE(adis16480_channels),
+		.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
+		.gyro_max_scale = 450,
+		.accel_max_val = IIO_M_S_2_TO_G(12500),
+		.accel_max_scale = 5,
 	},
 	},
 	[ADIS16485] = {
 	[ADIS16485] = {
 		.channels = adis16485_channels,
 		.channels = adis16485_channels,
 		.num_channels = ARRAY_SIZE(adis16485_channels),
 		.num_channels = ARRAY_SIZE(adis16485_channels),
+		.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
+		.gyro_max_scale = 450,
+		.accel_max_val = IIO_M_S_2_TO_G(20000),
+		.accel_max_scale = 5,
 	},
 	},
 	[ADIS16488] = {
 	[ADIS16488] = {
 		.channels = adis16480_channels,
 		.channels = adis16480_channels,
 		.num_channels = ARRAY_SIZE(adis16480_channels),
 		.num_channels = ARRAY_SIZE(adis16480_channels),
+		.gyro_max_val = IIO_RAD_TO_DEGREE(22500),
+		.gyro_max_scale = 450,
+		.accel_max_val = IIO_M_S_2_TO_G(22500),
+		.accel_max_scale = 18,
 	},
 	},
 };
 };
 
 

+ 6 - 1
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c

@@ -690,6 +690,10 @@ static const struct iio_chan_spec inv_mpu_channels[] = {
 
 
 /* constant IIO attribute */
 /* constant IIO attribute */
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500");
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500");
+static IIO_CONST_ATTR(in_anglvel_scale_available,
+					  "0.000133090 0.000266181 0.000532362 0.001064724");
+static IIO_CONST_ATTR(in_accel_scale_available,
+					  "0.000598 0.001196 0.002392 0.004785");
 static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show,
 static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show,
 	inv_mpu6050_fifo_rate_store);
 	inv_mpu6050_fifo_rate_store);
 static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL,
 static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL,
@@ -702,6 +706,8 @@ static struct attribute *inv_attributes[] = {
 	&iio_dev_attr_in_accel_matrix.dev_attr.attr,
 	&iio_dev_attr_in_accel_matrix.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
+	&iio_const_attr_in_anglvel_scale_available.dev_attr.attr,
 	NULL,
 	NULL,
 };
 };
 
 
@@ -921,7 +927,6 @@ static struct i2c_driver inv_mpu_driver = {
 	.remove		=	inv_mpu_remove,
 	.remove		=	inv_mpu_remove,
 	.id_table	=	inv_mpu_id,
 	.id_table	=	inv_mpu_id,
 	.driver = {
 	.driver = {
-		.owner	=	THIS_MODULE,
 		.name	=	"inv-mpu6050",
 		.name	=	"inv-mpu6050",
 		.pm     =       INV_MPU6050_PMOPS,
 		.pm     =       INV_MPU6050_PMOPS,
 		.acpi_match_table = ACPI_PTR(inv_acpi_match),
 		.acpi_match_table = ACPI_PTR(inv_acpi_match),

+ 4 - 4
drivers/iio/imu/kmx61.c

@@ -1363,7 +1363,7 @@ static int kmx61_probe(struct i2c_client *client,
 	if (client->irq < 0)
 	if (client->irq < 0)
 		client->irq = kmx61_gpio_probe(client, data);
 		client->irq = kmx61_gpio_probe(client, data);
 
 
-	if (client->irq >= 0) {
+	if (client->irq > 0) {
 		ret = devm_request_threaded_irq(&client->dev, client->irq,
 		ret = devm_request_threaded_irq(&client->dev, client->irq,
 						kmx61_data_rdy_trig_poll,
 						kmx61_data_rdy_trig_poll,
 						kmx61_event_handler,
 						kmx61_event_handler,
@@ -1445,10 +1445,10 @@ err_iio_unregister_mag:
 err_iio_unregister_acc:
 err_iio_unregister_acc:
 	iio_device_unregister(data->acc_indio_dev);
 	iio_device_unregister(data->acc_indio_dev);
 err_buffer_cleanup_mag:
 err_buffer_cleanup_mag:
-	if (client->irq >= 0)
+	if (client->irq > 0)
 		iio_triggered_buffer_cleanup(data->mag_indio_dev);
 		iio_triggered_buffer_cleanup(data->mag_indio_dev);
 err_buffer_cleanup_acc:
 err_buffer_cleanup_acc:
-	if (client->irq >= 0)
+	if (client->irq > 0)
 		iio_triggered_buffer_cleanup(data->acc_indio_dev);
 		iio_triggered_buffer_cleanup(data->acc_indio_dev);
 err_trigger_unregister_motion:
 err_trigger_unregister_motion:
 	iio_trigger_unregister(data->motion_trig);
 	iio_trigger_unregister(data->motion_trig);
@@ -1472,7 +1472,7 @@ static int kmx61_remove(struct i2c_client *client)
 	iio_device_unregister(data->acc_indio_dev);
 	iio_device_unregister(data->acc_indio_dev);
 	iio_device_unregister(data->mag_indio_dev);
 	iio_device_unregister(data->mag_indio_dev);
 
 
-	if (client->irq >= 0) {
+	if (client->irq > 0) {
 		iio_triggered_buffer_cleanup(data->acc_indio_dev);
 		iio_triggered_buffer_cleanup(data->acc_indio_dev);
 		iio_triggered_buffer_cleanup(data->mag_indio_dev);
 		iio_triggered_buffer_cleanup(data->mag_indio_dev);
 		iio_trigger_unregister(data->acc_dready_trig);
 		iio_trigger_unregister(data->acc_dready_trig);

+ 24 - 11
drivers/iio/industrialio-buffer.c

@@ -71,8 +71,9 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf,
 
 
 	if (avail >= to_wait) {
 	if (avail >= to_wait) {
 		/* force a flush for non-blocking reads */
 		/* force a flush for non-blocking reads */
-		if (!to_wait && !avail && to_flush)
-			iio_buffer_flush_hwfifo(indio_dev, buf, to_flush);
+		if (!to_wait && avail < to_flush)
+			iio_buffer_flush_hwfifo(indio_dev, buf,
+						to_flush - avail);
 		return true;
 		return true;
 	}
 	}
 
 
@@ -90,9 +91,16 @@ static bool iio_buffer_ready(struct iio_dev *indio_dev, struct iio_buffer *buf,
 
 
 /**
 /**
  * iio_buffer_read_first_n_outer() - chrdev read for buffer access
  * iio_buffer_read_first_n_outer() - chrdev read for buffer access
+ * @filp:	File structure pointer for the char device
+ * @buf:	Destination buffer for iio buffer read
+ * @n:		First n bytes to read
+ * @f_ps:	Long offset provided by the user as a seek position
  *
  *
  * This function relies on all buffer implementations having an
  * This function relies on all buffer implementations having an
  * iio_buffer as their first element.
  * iio_buffer as their first element.
+ *
+ * Return: negative values corresponding to error codes or ret != 0
+ *	   for ending the reading activity
  **/
  **/
 ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 				      size_t n, loff_t *f_ps)
 				      size_t n, loff_t *f_ps)
@@ -100,8 +108,7 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 	struct iio_dev *indio_dev = filp->private_data;
 	struct iio_dev *indio_dev = filp->private_data;
 	struct iio_buffer *rb = indio_dev->buffer;
 	struct iio_buffer *rb = indio_dev->buffer;
 	size_t datum_size;
 	size_t datum_size;
-	size_t to_wait = 0;
-	size_t to_read;
+	size_t to_wait;
 	int ret;
 	int ret;
 
 
 	if (!indio_dev->info)
 	if (!indio_dev->info)
@@ -119,14 +126,14 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 	if (!datum_size)
 	if (!datum_size)
 		return 0;
 		return 0;
 
 
-	to_read = min_t(size_t, n / datum_size, rb->watermark);
-
-	if (!(filp->f_flags & O_NONBLOCK))
-		to_wait = to_read;
+	if (filp->f_flags & O_NONBLOCK)
+		to_wait = 0;
+	else
+		to_wait = min_t(size_t, n / datum_size, rb->watermark);
 
 
 	do {
 	do {
 		ret = wait_event_interruptible(rb->pollq,
 		ret = wait_event_interruptible(rb->pollq,
-			iio_buffer_ready(indio_dev, rb, to_wait, to_read));
+		      iio_buffer_ready(indio_dev, rb, to_wait, n / datum_size));
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
 
 
@@ -143,6 +150,12 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 
 
 /**
 /**
  * iio_buffer_poll() - poll the buffer to find out if it has data
  * iio_buffer_poll() - poll the buffer to find out if it has data
+ * @filp:	File structure pointer for device access
+ * @wait:	Poll table structure pointer for which the driver adds
+ *		a wait queue
+ *
+ * Return: (POLLIN | POLLRDNORM) if data is available for reading
+ *	   or 0 for other cases
  */
  */
 unsigned int iio_buffer_poll(struct file *filp,
 unsigned int iio_buffer_poll(struct file *filp,
 			     struct poll_table_struct *wait)
 			     struct poll_table_struct *wait)
@@ -151,7 +164,7 @@ unsigned int iio_buffer_poll(struct file *filp,
 	struct iio_buffer *rb = indio_dev->buffer;
 	struct iio_buffer *rb = indio_dev->buffer;
 
 
 	if (!indio_dev->info)
 	if (!indio_dev->info)
-		return -ENODEV;
+		return 0;
 
 
 	poll_wait(filp, &rb->pollq, wait);
 	poll_wait(filp, &rb->pollq, wait);
 	if (iio_buffer_ready(indio_dev, rb, rb->watermark, 0))
 	if (iio_buffer_ready(indio_dev, rb, rb->watermark, 0))
@@ -1136,7 +1149,7 @@ int iio_scan_mask_query(struct iio_dev *indio_dev,
 EXPORT_SYMBOL_GPL(iio_scan_mask_query);
 EXPORT_SYMBOL_GPL(iio_scan_mask_query);
 
 
 /**
 /**
- * struct iio_demux_table() - table describing demux memcpy ops
+ * struct iio_demux_table - table describing demux memcpy ops
  * @from:	index to copy from
  * @from:	index to copy from
  * @to:		index to copy to
  * @to:		index to copy to
  * @length:	how many bytes to copy
  * @length:	how many bytes to copy

+ 28 - 5
drivers/iio/industrialio-core.c

@@ -81,6 +81,14 @@ static const char * const iio_modifier_names[] = {
 	[IIO_MOD_X] = "x",
 	[IIO_MOD_X] = "x",
 	[IIO_MOD_Y] = "y",
 	[IIO_MOD_Y] = "y",
 	[IIO_MOD_Z] = "z",
 	[IIO_MOD_Z] = "z",
+	[IIO_MOD_X_AND_Y] = "x&y",
+	[IIO_MOD_X_AND_Z] = "x&z",
+	[IIO_MOD_Y_AND_Z] = "y&z",
+	[IIO_MOD_X_AND_Y_AND_Z] = "x&y&z",
+	[IIO_MOD_X_OR_Y] = "x|y",
+	[IIO_MOD_X_OR_Z] = "x|z",
+	[IIO_MOD_Y_OR_Z] = "y|z",
+	[IIO_MOD_X_OR_Y_OR_Z] = "x|y|z",
 	[IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)",
 	[IIO_MOD_ROOT_SUM_SQUARED_X_Y] = "sqrt(x^2+y^2)",
 	[IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
 	[IIO_MOD_SUM_SQUARED_X_Y_Z] = "x^2+y^2+z^2",
 	[IIO_MOD_LIGHT_BOTH] = "both",
 	[IIO_MOD_LIGHT_BOTH] = "both",
@@ -398,10 +406,16 @@ EXPORT_SYMBOL_GPL(iio_enum_write);
 
 
 /**
 /**
  * iio_format_value() - Formats a IIO value into its string representation
  * iio_format_value() - Formats a IIO value into its string representation
- * @buf: The buffer to which the formated value gets written
- * @type: One of the IIO_VAL_... constants. This decides how the val and val2
- *        parameters are formatted.
- * @vals: pointer to the values, exact meaning depends on the type parameter.
+ * @buf:	The buffer to which the formatted value gets written
+ * @type:	One of the IIO_VAL_... constants. This decides how the val
+ *		and val2 parameters are formatted.
+ * @size:	Number of IIO value entries contained in vals
+ * @vals:	Pointer to the values, exact meaning depends on the
+ *		type parameter.
+ *
+ * Return: 0 by default, a negative number on failure or the
+ *	   total number of characters written for a type that belongs
+ *	   to the IIO_VAL_... constant.
  */
  */
 ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals)
 ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals)
 {
 {
@@ -1088,6 +1102,11 @@ 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
+ * @inode:	Inode structure for identifying the device in the file system
+ * @filp:	File structure for iio device used to keep and later access
+ *		private data
+ *
+ * Return: 0 on success or -EBUSY if the device is already opened
  **/
  **/
 static int iio_chrdev_open(struct inode *inode, struct file *filp)
 static int iio_chrdev_open(struct inode *inode, struct file *filp)
 {
 {
@@ -1106,7 +1125,11 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp)
 
 
 /**
 /**
  * iio_chrdev_release() - chrdev file close buffer access and ioctls
  * iio_chrdev_release() - chrdev file close buffer access and ioctls
- **/
+ * @inode:	Inode structure pointer for the char device
+ * @filp:	File structure pointer for the char device
+ *
+ * Return: 0 for successful release
+ */
 static int iio_chrdev_release(struct inode *inode, struct file *filp)
 static int iio_chrdev_release(struct inode *inode, struct file *filp)
 {
 {
 	struct iio_dev *indio_dev = container_of(inode->i_cdev,
 	struct iio_dev *indio_dev = container_of(inode->i_cdev,

+ 7 - 1
drivers/iio/industrialio-event.c

@@ -32,6 +32,7 @@
  * @dev_attr_list:	list of event interface sysfs attribute
  * @dev_attr_list:	list of event interface sysfs attribute
  * @flags:		file operations related flags including busy flag.
  * @flags:		file operations related flags including busy flag.
  * @group:		event interface sysfs attribute group
  * @group:		event interface sysfs attribute group
+ * @read_lock:		lock to protect kfifo read operations
  */
  */
 struct iio_event_interface {
 struct iio_event_interface {
 	wait_queue_head_t	wait;
 	wait_queue_head_t	wait;
@@ -75,6 +76,11 @@ EXPORT_SYMBOL(iio_push_event);
 
 
 /**
 /**
  * iio_event_poll() - poll the event queue to find out if it has data
  * iio_event_poll() - poll the event queue to find out if it has data
+ * @filep:	File structure pointer to identify the device
+ * @wait:	Poll table pointer to add the wait queue on
+ *
+ * Return: (POLLIN | POLLRDNORM) if data is available for reading
+ *	   or a negative error code on failure
  */
  */
 static unsigned int iio_event_poll(struct file *filep,
 static unsigned int iio_event_poll(struct file *filep,
 			     struct poll_table_struct *wait)
 			     struct poll_table_struct *wait)
@@ -84,7 +90,7 @@ static unsigned int iio_event_poll(struct file *filep,
 	unsigned int events = 0;
 	unsigned int events = 0;
 
 
 	if (!indio_dev->info)
 	if (!indio_dev->info)
-		return -ENODEV;
+		return events;
 
 
 	poll_wait(filep, &ev_int->wait, wait);
 	poll_wait(filep, &ev_int->wait, wait);
 
 

+ 24 - 3
drivers/iio/industrialio-trigger.c

@@ -40,7 +40,14 @@ static DEFINE_MUTEX(iio_trigger_list_lock);
 
 
 /**
 /**
  * iio_trigger_read_name() - retrieve useful identifying name
  * iio_trigger_read_name() - retrieve useful identifying name
- **/
+ * @dev:	device associated with the iio_trigger
+ * @attr:	pointer to the device_attribute structure that is
+ *		being processed
+ * @buf:	buffer to print the name into
+ *
+ * Return: a negative number on failure or the number of written
+ *	   characters on success.
+ */
 static ssize_t iio_trigger_read_name(struct device *dev,
 static ssize_t iio_trigger_read_name(struct device *dev,
 				     struct device_attribute *attr,
 				     struct device_attribute *attr,
 				     char *buf)
 				     char *buf)
@@ -288,10 +295,17 @@ EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc);
 
 
 /**
 /**
  * iio_trigger_read_current() - trigger consumer sysfs query current trigger
  * iio_trigger_read_current() - trigger consumer sysfs query current trigger
+ * @dev:	device associated with an industrial I/O device
+ * @attr:	pointer to the device_attribute structure that
+ *		is being processed
+ * @buf:	buffer where the current trigger name will be printed into
  *
  *
  * For trigger consumers the current_trigger interface allows the trigger
  * For trigger consumers the current_trigger interface allows the trigger
  * used by the device to be queried.
  * used by the device to be queried.
- **/
+ *
+ * Return: a negative number on failure, the number of characters written
+ *	   on success or 0 if no trigger is available
+ */
 static ssize_t iio_trigger_read_current(struct device *dev,
 static ssize_t iio_trigger_read_current(struct device *dev,
 					struct device_attribute *attr,
 					struct device_attribute *attr,
 					char *buf)
 					char *buf)
@@ -305,11 +319,18 @@ static ssize_t iio_trigger_read_current(struct device *dev,
 
 
 /**
 /**
  * iio_trigger_write_current() - trigger consumer sysfs set current trigger
  * iio_trigger_write_current() - trigger consumer sysfs set current trigger
+ * @dev:	device associated with an industrial I/O device
+ * @attr:	device attribute that is being processed
+ * @buf:	string buffer that holds the name of the trigger
+ * @len:	length of the trigger name held by buf
  *
  *
  * For trigger consumers the current_trigger interface allows the trigger
  * For trigger consumers the current_trigger interface allows the trigger
  * used for this device to be specified at run time based on the trigger's
  * used for this device to be specified at run time based on the trigger's
  * name.
  * name.
- **/
+ *
+ * Return: negative error code on failure or length of the buffer
+ *	   on success
+ */
 static ssize_t iio_trigger_write_current(struct device *dev,
 static ssize_t iio_trigger_write_current(struct device *dev,
 					 struct device_attribute *attr,
 					 struct device_attribute *attr,
 					 const char *buf,
 					 const char *buf,

+ 6 - 6
drivers/iio/industrialio-triggered-buffer.c

@@ -24,8 +24,8 @@ static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
 /**
 /**
  * iio_triggered_buffer_setup() - Setup triggered buffer and pollfunc
  * iio_triggered_buffer_setup() - Setup triggered buffer and pollfunc
  * @indio_dev:		IIO device structure
  * @indio_dev:		IIO device structure
- * @pollfunc_bh:	Function which will be used as pollfunc bottom half
- * @pollfunc_th:	Function which will be used as pollfunc top half
+ * @h:			Function which will be used as pollfunc top half
+ * @thread:		Function which will be used as pollfunc bottom half
  * @setup_ops:		Buffer setup functions to use for this device.
  * @setup_ops:		Buffer setup functions to use for this device.
  *			If NULL the default setup functions for triggered
  *			If NULL the default setup functions for triggered
  *			buffers will be used.
  *			buffers will be used.
@@ -42,8 +42,8 @@ static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
  * iio_triggered_buffer_cleanup().
  * iio_triggered_buffer_cleanup().
  */
  */
 int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
 int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
-	irqreturn_t (*pollfunc_bh)(int irq, void *p),
-	irqreturn_t (*pollfunc_th)(int irq, void *p),
+	irqreturn_t (*h)(int irq, void *p),
+	irqreturn_t (*thread)(int irq, void *p),
 	const struct iio_buffer_setup_ops *setup_ops)
 	const struct iio_buffer_setup_ops *setup_ops)
 {
 {
 	struct iio_buffer *buffer;
 	struct iio_buffer *buffer;
@@ -57,8 +57,8 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
 
 
 	iio_device_attach_buffer(indio_dev, buffer);
 	iio_device_attach_buffer(indio_dev, buffer);
 
 
-	indio_dev->pollfunc = iio_alloc_pollfunc(pollfunc_bh,
-						 pollfunc_th,
+	indio_dev->pollfunc = iio_alloc_pollfunc(h,
+						 thread,
 						 IRQF_ONESHOT,
 						 IRQF_ONESHOT,
 						 indio_dev,
 						 indio_dev,
 						 "%s_consumer%d",
 						 "%s_consumer%d",

+ 33 - 1
drivers/iio/light/Kconfig

@@ -86,7 +86,7 @@ config CM3323
 	depends on I2C
 	depends on I2C
 	tristate "Capella CM3323 color light sensor"
 	tristate "Capella CM3323 color light sensor"
 	help
 	help
-	 Say Y here if you want to build a driver for Capela CM3323
+	 Say Y here if you want to build a driver for Capella CM3323
 	 color sensor.
 	 color sensor.
 
 
 	 To compile this driver as a module, choose M here: the module will
 	 To compile this driver as a module, choose M here: the module will
@@ -168,6 +168,17 @@ config JSA1212
 	 To compile this driver as a module, choose M here:
 	 To compile this driver as a module, choose M here:
 	 the module will be called jsa1212.
 	 the module will be called jsa1212.
 
 
+config RPR0521
+	tristate "ROHM RPR0521 ALS and proximity sensor driver"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	 Say Y here if you want to build support for ROHM's RPR0521
+	 ambient light and proximity sensor device.
+
+	 To compile this driver as a module, choose M here:
+	 the module will be called rpr0521.
+
 config SENSORS_LM3533
 config SENSORS_LM3533
 	tristate "LM3533 ambient light sensor"
 	tristate "LM3533 ambient light sensor"
 	depends on MFD_LM3533
 	depends on MFD_LM3533
@@ -199,6 +210,27 @@ config LTR501
 	 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 ltr501.
          will be called ltr501.
 
 
+config OPT3001
+	tristate "Texas Instruments OPT3001 Light Sensor"
+	depends on I2C
+	help
+	  If you say Y or M here, you get support for Texas Instruments
+	  OPT3001 Ambient Light Sensor.
+
+	  If built as a dynamically linked module, it will be called
+	  opt3001.
+
+config PA12203001
+        tristate "TXC PA12203001 light and proximity sensor"
+        depends on I2C
+        select REGMAP_I2C
+        help
+         If you say yes here you get support for the TXC PA12203001
+         ambient light and proximity sensor.
+
+         This driver can also be built as a module.  If so, the module
+         will be called pa12203001.
+
 config STK3310
 config STK3310
 	tristate "STK3310 ALS and proximity sensor"
 	tristate "STK3310 ALS and proximity sensor"
 	depends on I2C
 	depends on I2C

+ 3 - 0
drivers/iio/light/Makefile

@@ -19,6 +19,9 @@ obj-$(CONFIG_ISL29125)		+= isl29125.o
 obj-$(CONFIG_JSA1212)		+= jsa1212.o
 obj-$(CONFIG_JSA1212)		+= jsa1212.o
 obj-$(CONFIG_SENSORS_LM3533)	+= lm3533-als.o
 obj-$(CONFIG_SENSORS_LM3533)	+= lm3533-als.o
 obj-$(CONFIG_LTR501)		+= ltr501.o
 obj-$(CONFIG_LTR501)		+= ltr501.o
+obj-$(CONFIG_OPT3001)		+= opt3001.o
+obj-$(CONFIG_PA12203001)	+= pa12203001.o
+obj-$(CONFIG_RPR0521)		+= rpr0521.o
 obj-$(CONFIG_SENSORS_TSL2563)	+= tsl2563.o
 obj-$(CONFIG_SENSORS_TSL2563)	+= tsl2563.o
 obj-$(CONFIG_STK3310)          += stk3310.o
 obj-$(CONFIG_STK3310)          += stk3310.o
 obj-$(CONFIG_TCS3414)		+= tcs3414.o
 obj-$(CONFIG_TCS3414)		+= tcs3414.o

+ 9 - 9
drivers/iio/light/acpi-als.c

@@ -65,20 +65,20 @@ static const struct iio_chan_spec acpi_als_channels[] = {
  * to acpi_als_channels[], the evt_buffer below will grow
  * to acpi_als_channels[], the evt_buffer below will grow
  * automatically.
  * automatically.
  */
  */
-#define EVT_NR_SOURCES		ARRAY_SIZE(acpi_als_channels)
-#define EVT_BUFFER_SIZE		\
-	(sizeof(s64) + (EVT_NR_SOURCES * sizeof(s32)))
+#define ACPI_ALS_EVT_NR_SOURCES		ARRAY_SIZE(acpi_als_channels)
+#define ACPI_ALS_EVT_BUFFER_SIZE		\
+	(sizeof(s64) + (ACPI_ALS_EVT_NR_SOURCES * sizeof(s32)))
 
 
 struct acpi_als {
 struct acpi_als {
 	struct acpi_device	*device;
 	struct acpi_device	*device;
 	struct mutex		lock;
 	struct mutex		lock;
 
 
-	s32			evt_buffer[EVT_BUFFER_SIZE];
+	s32			evt_buffer[ACPI_ALS_EVT_BUFFER_SIZE];
 };
 };
 
 
 /*
 /*
  * All types of properties the ACPI0008 block can report. The ALI, ALC, ALT
  * All types of properties the ACPI0008 block can report. The ALI, ALC, ALT
- * and ALP can all be handled by als_read_value() below, while the ALR is
+ * and ALP can all be handled by acpi_als_read_value() below, while the ALR is
  * special.
  * special.
  *
  *
  * The _ALR property returns tables that can be used to fine-tune the values
  * The _ALR property returns tables that can be used to fine-tune the values
@@ -93,7 +93,7 @@ struct acpi_als {
 #define ACPI_ALS_POLLING	"_ALP"
 #define ACPI_ALS_POLLING	"_ALP"
 #define ACPI_ALS_TABLES		"_ALR"
 #define ACPI_ALS_TABLES		"_ALR"
 
 
-static int als_read_value(struct acpi_als *als, char *prop, s32 *val)
+static int acpi_als_read_value(struct acpi_als *als, char *prop, s32 *val)
 {
 {
 	unsigned long long temp_val;
 	unsigned long long temp_val;
 	acpi_status status;
 	acpi_status status;
@@ -122,11 +122,11 @@ static void acpi_als_notify(struct acpi_device *device, u32 event)
 
 
 	mutex_lock(&als->lock);
 	mutex_lock(&als->lock);
 
 
-	memset(buffer, 0, EVT_BUFFER_SIZE);
+	memset(buffer, 0, ACPI_ALS_EVT_BUFFER_SIZE);
 
 
 	switch (event) {
 	switch (event) {
 	case ACPI_ALS_NOTIFY_ILLUMINANCE:
 	case ACPI_ALS_NOTIFY_ILLUMINANCE:
-		ret = als_read_value(als, ACPI_ALS_ILLUMINANCE, &val);
+		ret = acpi_als_read_value(als, ACPI_ALS_ILLUMINANCE, &val);
 		if (ret < 0)
 		if (ret < 0)
 			goto out;
 			goto out;
 		*buffer++ = val;
 		*buffer++ = val;
@@ -159,7 +159,7 @@ static int acpi_als_read_raw(struct iio_dev *indio_dev,
 	if (chan->type != IIO_LIGHT)
 	if (chan->type != IIO_LIGHT)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	ret = als_read_value(als, ACPI_ALS_ILLUMINANCE, &temp_val);
+	ret = acpi_als_read_value(als, ACPI_ALS_ILLUMINANCE, &temp_val);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 

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

@@ -515,7 +515,6 @@ MODULE_DEVICE_TABLE(i2c, apds9300_id);
 static struct i2c_driver apds9300_driver = {
 static struct i2c_driver apds9300_driver = {
 	.driver = {
 	.driver = {
 		.name	= APDS9300_DRV_NAME,
 		.name	= APDS9300_DRV_NAME,
-		.owner	= THIS_MODULE,
 		.pm	= APDS9300_PM_OPS,
 		.pm	= APDS9300_PM_OPS,
 	},
 	},
 	.probe		= apds9300_probe,
 	.probe		= apds9300_probe,

+ 0 - 1
drivers/iio/light/bh1750.c

@@ -319,7 +319,6 @@ MODULE_DEVICE_TABLE(i2c, bh1750_id);
 static struct i2c_driver bh1750_driver = {
 static struct i2c_driver bh1750_driver = {
 	.driver = {
 	.driver = {
 		.name = "bh1750",
 		.name = "bh1750",
-		.owner = THIS_MODULE,
 		.pm = BH1750_PM_OPS,
 		.pm = BH1750_PM_OPS,
 	},
 	},
 	.probe = bh1750_probe,
 	.probe = bh1750_probe,

+ 1 - 1
drivers/iio/light/cm32181.c

@@ -353,12 +353,12 @@ static const struct of_device_id cm32181_of_match[] = {
 	{ .compatible = "capella,cm32181" },
 	{ .compatible = "capella,cm32181" },
 	{ }
 	{ }
 };
 };
+MODULE_DEVICE_TABLE(of, cm32181_of_match);
 
 
 static struct i2c_driver cm32181_driver = {
 static struct i2c_driver cm32181_driver = {
 	.driver = {
 	.driver = {
 		.name	= "cm32181",
 		.name	= "cm32181",
 		.of_match_table = of_match_ptr(cm32181_of_match),
 		.of_match_table = of_match_ptr(cm32181_of_match),
-		.owner	= THIS_MODULE,
 	},
 	},
 	.id_table       = cm32181_id,
 	.id_table       = cm32181_id,
 	.probe		= cm32181_probe,
 	.probe		= cm32181_probe,

+ 1 - 1
drivers/iio/light/cm3232.c

@@ -417,11 +417,11 @@ static const struct of_device_id cm3232_of_match[] = {
 	{.compatible = "capella,cm3232"},
 	{.compatible = "capella,cm3232"},
 	{}
 	{}
 };
 };
+MODULE_DEVICE_TABLE(of, cm3232_of_match);
 
 
 static struct i2c_driver cm3232_driver = {
 static struct i2c_driver cm3232_driver = {
 	.driver = {
 	.driver = {
 		.name	= "cm3232",
 		.name	= "cm3232",
-		.owner	= THIS_MODULE,
 		.of_match_table = of_match_ptr(cm3232_of_match),
 		.of_match_table = of_match_ptr(cm3232_of_match),
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_PM_SLEEP
 		.pm	= &cm3232_pm_ops,
 		.pm	= &cm3232_pm_ops,

+ 12 - 7
drivers/iio/light/cm3323.c

@@ -29,7 +29,7 @@
 
 
 #define CM3323_CONF_SD_BIT	BIT(0) /* sensor disable */
 #define CM3323_CONF_SD_BIT	BIT(0) /* sensor disable */
 #define CM3323_CONF_AF_BIT	BIT(1) /* auto/manual force mode */
 #define CM3323_CONF_AF_BIT	BIT(1) /* auto/manual force mode */
-#define CM3323_CONF_IT_MASK	(BIT(4) | BIT(5) | BIT(6))
+#define CM3323_CONF_IT_MASK	GENMASK(6, 4)
 #define CM3323_CONF_IT_SHIFT	4
 #define CM3323_CONF_IT_SHIFT	4
 
 
 #define CM3323_INT_TIME_AVAILABLE "0.04 0.08 0.16 0.32 0.64 1.28"
 #define CM3323_INT_TIME_AVAILABLE "0.04 0.08 0.16 0.32 0.64 1.28"
@@ -133,9 +133,11 @@ static int cm3323_set_it_bits(struct cm3323_data *data, int val, int val2)
 				return ret;
 				return ret;
 
 
 			data->reg_conf = reg_conf;
 			data->reg_conf = reg_conf;
+
 			return 0;
 			return 0;
 		}
 		}
 	}
 	}
+
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
@@ -148,6 +150,7 @@ static int cm3323_get_it_bits(struct cm3323_data *data)
 
 
 	if (bits >= ARRAY_SIZE(cm3323_int_time))
 	if (bits >= ARRAY_SIZE(cm3323_int_time))
 		return -EINVAL;
 		return -EINVAL;
+
 	return bits;
 	return bits;
 }
 }
 
 
@@ -155,7 +158,7 @@ static int cm3323_read_raw(struct iio_dev *indio_dev,
 			   struct iio_chan_spec const *chan, int *val,
 			   struct iio_chan_spec const *chan, int *val,
 			   int *val2, long mask)
 			   int *val2, long mask)
 {
 {
-	int i, ret;
+	int ret;
 	struct cm3323_data *data = iio_priv(indio_dev);
 	struct cm3323_data *data = iio_priv(indio_dev);
 
 
 	switch (mask) {
 	switch (mask) {
@@ -172,14 +175,14 @@ static int cm3323_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 	case IIO_CHAN_INFO_INT_TIME:
 		mutex_lock(&data->mutex);
 		mutex_lock(&data->mutex);
-		i = cm3323_get_it_bits(data);
-		if (i < 0) {
+		ret = cm3323_get_it_bits(data);
+		if (ret < 0) {
 			mutex_unlock(&data->mutex);
 			mutex_unlock(&data->mutex);
-			return -EINVAL;
+			return ret;
 		}
 		}
 
 
-		*val = cm3323_int_time[i].val;
-		*val2 = cm3323_int_time[i].val2;
+		*val = cm3323_int_time[ret].val;
+		*val2 = cm3323_int_time[ret].val2;
 		mutex_unlock(&data->mutex);
 		mutex_unlock(&data->mutex);
 
 
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
@@ -243,11 +246,13 @@ static int cm3323_probe(struct i2c_client *client,
 		dev_err(&client->dev, "cm3323 chip init failed\n");
 		dev_err(&client->dev, "cm3323 chip init failed\n");
 		return ret;
 		return ret;
 	}
 	}
+
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&client->dev, "failed to register iio dev\n");
 		dev_err(&client->dev, "failed to register iio dev\n");
 		goto err_init;
 		goto err_init;
 	}
 	}
+
 	return 0;
 	return 0;
 err_init:
 err_init:
 	cm3323_disable(indio_dev);
 	cm3323_disable(indio_dev);

+ 1 - 1
drivers/iio/light/cm36651.c

@@ -731,12 +731,12 @@ static const struct of_device_id cm36651_of_match[] = {
 	{ .compatible = "capella,cm36651" },
 	{ .compatible = "capella,cm36651" },
 	{ }
 	{ }
 };
 };
+MODULE_DEVICE_TABLE(of, cm36651_of_match);
 
 
 static struct i2c_driver cm36651_driver = {
 static struct i2c_driver cm36651_driver = {
 	.driver = {
 	.driver = {
 		.name	= "cm36651",
 		.name	= "cm36651",
 		.of_match_table = cm36651_of_match,
 		.of_match_table = cm36651_of_match,
-		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= cm36651_probe,
 	.probe		= cm36651_probe,
 	.remove		= cm36651_remove,
 	.remove		= cm36651_remove,

+ 1 - 1
drivers/iio/light/gp2ap020a00f.c

@@ -1634,13 +1634,13 @@ static const struct of_device_id gp2ap020a00f_of_match[] = {
 	{ .compatible = "sharp,gp2ap020a00f" },
 	{ .compatible = "sharp,gp2ap020a00f" },
 	{ }
 	{ }
 };
 };
+MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match);
 #endif
 #endif
 
 
 static struct i2c_driver gp2ap020a00f_driver = {
 static struct i2c_driver gp2ap020a00f_driver = {
 	.driver = {
 	.driver = {
 		.name	= GP2A_I2C_NAME,
 		.name	= GP2A_I2C_NAME,
 		.of_match_table = of_match_ptr(gp2ap020a00f_of_match),
 		.of_match_table = of_match_ptr(gp2ap020a00f_of_match),
-		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= gp2ap020a00f_probe,
 	.probe		= gp2ap020a00f_probe,
 	.remove		= gp2ap020a00f_remove,
 	.remove		= gp2ap020a00f_remove,

+ 1 - 2
drivers/iio/light/hid-sensor-prox.c

@@ -284,8 +284,7 @@ static int hid_prox_probe(struct platform_device *pdev)
 		goto error_free_dev_mem;
 		goto error_free_dev_mem;
 	}
 	}
 
 
-	indio_dev->num_channels =
-				ARRAY_SIZE(prox_channels);
+	indio_dev->num_channels = ARRAY_SIZE(prox_channels);
 	indio_dev->dev.parent = &pdev->dev;
 	indio_dev->dev.parent = &pdev->dev;
 	indio_dev->info = &prox_info;
 	indio_dev->info = &prox_info;
 	indio_dev->name = name;
 	indio_dev->name = name;

+ 12 - 1
drivers/iio/light/isl29125.c

@@ -197,9 +197,21 @@ done:
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
+static IIO_CONST_ATTR(scale_available, "0.005722 0.152590");
+
+static struct attribute *isl29125_attributes[] = {
+	&iio_const_attr_scale_available.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group isl29125_attribute_group = {
+	.attrs = isl29125_attributes,
+};
+
 static const struct iio_info isl29125_info = {
 static const struct iio_info isl29125_info = {
 	.read_raw = isl29125_read_raw,
 	.read_raw = isl29125_read_raw,
 	.write_raw = isl29125_write_raw,
 	.write_raw = isl29125_write_raw,
+	.attrs = &isl29125_attribute_group,
 	.driver_module = THIS_MODULE,
 	.driver_module = THIS_MODULE,
 };
 };
 
 
@@ -334,7 +346,6 @@ static struct i2c_driver isl29125_driver = {
 	.driver = {
 	.driver = {
 		.name	= ISL29125_DRV_NAME,
 		.name	= ISL29125_DRV_NAME,
 		.pm	= &isl29125_pm_ops,
 		.pm	= &isl29125_pm_ops,
-		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= isl29125_probe,
 	.probe		= isl29125_probe,
 	.remove		= isl29125_remove,
 	.remove		= isl29125_remove,

+ 0 - 1
drivers/iio/light/jsa1212.c

@@ -457,7 +457,6 @@ static struct i2c_driver jsa1212_driver = {
 	.driver = {
 	.driver = {
 		.name	= JSA1212_DRIVER_NAME,
 		.name	= JSA1212_DRIVER_NAME,
 		.pm	= JSA1212_PM_OPS,
 		.pm	= JSA1212_PM_OPS,
-		.owner	= THIS_MODULE,
 		.acpi_match_table = ACPI_PTR(jsa1212_acpi_match),
 		.acpi_match_table = ACPI_PTR(jsa1212_acpi_match),
 	},
 	},
 	.probe		= jsa1212_probe,
 	.probe		= jsa1212_probe,

+ 0 - 1
drivers/iio/light/ltr501.c

@@ -1551,7 +1551,6 @@ static struct i2c_driver ltr501_driver = {
 		.name   = LTR501_DRV_NAME,
 		.name   = LTR501_DRV_NAME,
 		.pm	= &ltr501_pm_ops,
 		.pm	= &ltr501_pm_ops,
 		.acpi_match_table = ACPI_PTR(ltr_acpi_match),
 		.acpi_match_table = ACPI_PTR(ltr_acpi_match),
-		.owner  = THIS_MODULE,
 	},
 	},
 	.probe  = ltr501_probe,
 	.probe  = ltr501_probe,
 	.remove	= ltr501_remove,
 	.remove	= ltr501_remove,

+ 804 - 0
drivers/iio/light/opt3001.c

@@ -0,0 +1,804 @@
+/**
+ * opt3001.c - Texas Instruments OPT3001 Light Sensor
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Andreas Dannenberg <dannenberg@ti.com>
+ * Based on previous work from: Felipe Balbi <balbi@ti.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 of the License
+ * 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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <linux/iio/events.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define OPT3001_RESULT		0x00
+#define OPT3001_CONFIGURATION	0x01
+#define OPT3001_LOW_LIMIT	0x02
+#define OPT3001_HIGH_LIMIT	0x03
+#define OPT3001_MANUFACTURER_ID	0x7e
+#define OPT3001_DEVICE_ID	0x7f
+
+#define OPT3001_CONFIGURATION_RN_MASK	(0xf << 12)
+#define OPT3001_CONFIGURATION_RN_AUTO	(0xc << 12)
+
+#define OPT3001_CONFIGURATION_CT	BIT(11)
+
+#define OPT3001_CONFIGURATION_M_MASK	(3 << 9)
+#define OPT3001_CONFIGURATION_M_SHUTDOWN (0 << 9)
+#define OPT3001_CONFIGURATION_M_SINGLE	(1 << 9)
+#define OPT3001_CONFIGURATION_M_CONTINUOUS (2 << 9) /* also 3 << 9 */
+
+#define OPT3001_CONFIGURATION_OVF	BIT(8)
+#define OPT3001_CONFIGURATION_CRF	BIT(7)
+#define OPT3001_CONFIGURATION_FH	BIT(6)
+#define OPT3001_CONFIGURATION_FL	BIT(5)
+#define OPT3001_CONFIGURATION_L		BIT(4)
+#define OPT3001_CONFIGURATION_POL	BIT(3)
+#define OPT3001_CONFIGURATION_ME	BIT(2)
+
+#define OPT3001_CONFIGURATION_FC_MASK	(3 << 0)
+
+/* The end-of-conversion enable is located in the low-limit register */
+#define OPT3001_LOW_LIMIT_EOC_ENABLE	0xc000
+
+#define OPT3001_REG_EXPONENT(n)		((n) >> 12)
+#define OPT3001_REG_MANTISSA(n)		((n) & 0xfff)
+
+/*
+ * Time to wait for conversion result to be ready. The device datasheet
+ * worst-case max value is 880ms. Add some slack to be on the safe side.
+ */
+#define OPT3001_RESULT_READY_TIMEOUT	msecs_to_jiffies(1000)
+
+struct opt3001 {
+	struct i2c_client	*client;
+	struct device		*dev;
+
+	struct mutex		lock;
+	u16			ok_to_ignore_lock:1;
+	u16			result_ready:1;
+	wait_queue_head_t	result_ready_queue;
+	u16			result;
+
+	u32			int_time;
+	u32			mode;
+
+	u16			high_thresh_mantissa;
+	u16			low_thresh_mantissa;
+
+	u8			high_thresh_exp;
+	u8			low_thresh_exp;
+};
+
+struct opt3001_scale {
+	int	val;
+	int	val2;
+};
+
+static const struct opt3001_scale opt3001_scales[] = {
+	{
+		.val = 40,
+		.val2 = 950000,
+	},
+	{
+		.val = 81,
+		.val2 = 900000,
+	},
+	{
+		.val = 163,
+		.val2 = 800000,
+	},
+	{
+		.val = 327,
+		.val2 = 600000,
+	},
+	{
+		.val = 655,
+		.val2 = 200000,
+	},
+	{
+		.val = 1310,
+		.val2 = 400000,
+	},
+	{
+		.val = 2620,
+		.val2 = 800000,
+	},
+	{
+		.val = 5241,
+		.val2 = 600000,
+	},
+	{
+		.val = 10483,
+		.val2 = 200000,
+	},
+	{
+		.val = 20966,
+		.val2 = 400000,
+	},
+	{
+		.val = 83865,
+		.val2 = 600000,
+	},
+};
+
+static int opt3001_find_scale(const struct opt3001 *opt, int val,
+		int val2, u8 *exponent)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(opt3001_scales); i++) {
+		const struct opt3001_scale *scale = &opt3001_scales[i];
+
+		/*
+		 * Combine the integer and micro parts for comparison
+		 * purposes. Use milli lux precision to avoid 32-bit integer
+		 * overflows.
+		 */
+		if ((val * 1000 + val2 / 1000) <=
+				(scale->val * 1000 + scale->val2 / 1000)) {
+			*exponent = i;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static void opt3001_to_iio_ret(struct opt3001 *opt, u8 exponent,
+		u16 mantissa, int *val, int *val2)
+{
+	int lux;
+
+	lux = 10 * (mantissa << exponent);
+	*val = lux / 1000;
+	*val2 = (lux - (*val * 1000)) * 1000;
+}
+
+static void opt3001_set_mode(struct opt3001 *opt, u16 *reg, u16 mode)
+{
+	*reg &= ~OPT3001_CONFIGURATION_M_MASK;
+	*reg |= mode;
+	opt->mode = mode;
+}
+
+static IIO_CONST_ATTR_INT_TIME_AVAIL("0.1 0.8");
+
+static struct attribute *opt3001_attributes[] = {
+	&iio_const_attr_integration_time_available.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group opt3001_attribute_group = {
+	.attrs = opt3001_attributes,
+};
+
+static const struct iio_event_spec opt3001_event_spec[] = {
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_RISING,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
+			BIT(IIO_EV_INFO_ENABLE),
+	},
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_FALLING,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
+			BIT(IIO_EV_INFO_ENABLE),
+	},
+};
+
+static const struct iio_chan_spec opt3001_channels[] = {
+	{
+		.type = IIO_LIGHT,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
+				BIT(IIO_CHAN_INFO_INT_TIME),
+		.event_spec = opt3001_event_spec,
+		.num_event_specs = ARRAY_SIZE(opt3001_event_spec),
+	},
+	IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+static int opt3001_get_lux(struct opt3001 *opt, int *val, int *val2)
+{
+	int ret;
+	u16 mantissa;
+	u16 reg;
+	u8 exponent;
+	u16 value;
+
+	/*
+	 * Enable the end-of-conversion interrupt mechanism. Note that doing
+	 * so will overwrite the low-level limit value however we will restore
+	 * this value later on.
+	 */
+	ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_LOW_LIMIT,
+			OPT3001_LOW_LIMIT_EOC_ENABLE);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to write register %02x\n",
+				OPT3001_LOW_LIMIT);
+		return ret;
+	}
+
+	/* Reset data-ready indicator flag (will be set in the IRQ routine) */
+	opt->result_ready = false;
+
+	/* Allow IRQ to access the device despite lock being set */
+	opt->ok_to_ignore_lock = true;
+
+	/* Configure for single-conversion mode and start a new conversion */
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_CONFIGURATION);
+		goto err;
+	}
+
+	reg = ret;
+	opt3001_set_mode(opt, &reg, OPT3001_CONFIGURATION_M_SINGLE);
+
+	ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION,
+			reg);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to write register %02x\n",
+				OPT3001_CONFIGURATION);
+		goto err;
+	}
+
+	/* Wait for the IRQ to indicate the conversion is complete */
+	ret = wait_event_timeout(opt->result_ready_queue, opt->result_ready,
+			OPT3001_RESULT_READY_TIMEOUT);
+
+err:
+	/* Disallow IRQ to access the device while lock is active */
+	opt->ok_to_ignore_lock = false;
+
+	if (ret == 0)
+		return -ETIMEDOUT;
+	else if (ret < 0)
+		return ret;
+
+	/*
+	 * Disable the end-of-conversion interrupt mechanism by restoring the
+	 * low-level limit value (clearing OPT3001_LOW_LIMIT_EOC_ENABLE). Note
+	 * that selectively clearing those enable bits would affect the actual
+	 * limit value due to bit-overlap and therefore can't be done.
+	 */
+	value = (opt->low_thresh_exp << 12) | opt->low_thresh_mantissa;
+	ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_LOW_LIMIT,
+			value);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to write register %02x\n",
+				OPT3001_LOW_LIMIT);
+		return ret;
+	}
+
+	exponent = OPT3001_REG_EXPONENT(opt->result);
+	mantissa = OPT3001_REG_MANTISSA(opt->result);
+
+	opt3001_to_iio_ret(opt, exponent, mantissa, val, val2);
+
+	return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int opt3001_get_int_time(struct opt3001 *opt, int *val, int *val2)
+{
+	*val = 0;
+	*val2 = opt->int_time;
+
+	return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int opt3001_set_int_time(struct opt3001 *opt, int time)
+{
+	int ret;
+	u16 reg;
+
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_CONFIGURATION);
+		return ret;
+	}
+
+	reg = ret;
+
+	switch (time) {
+	case 100000:
+		reg &= ~OPT3001_CONFIGURATION_CT;
+		opt->int_time = 100000;
+		break;
+	case 800000:
+		reg |= OPT3001_CONFIGURATION_CT;
+		opt->int_time = 800000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION,
+			reg);
+}
+
+static int opt3001_read_raw(struct iio_dev *iio,
+		struct iio_chan_spec const *chan, int *val, int *val2,
+		long mask)
+{
+	struct opt3001 *opt = iio_priv(iio);
+	int ret;
+
+	if (opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS)
+		return -EBUSY;
+
+	if (chan->type != IIO_LIGHT)
+		return -EINVAL;
+
+	mutex_lock(&opt->lock);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_PROCESSED:
+		ret = opt3001_get_lux(opt, val, val2);
+		break;
+	case IIO_CHAN_INFO_INT_TIME:
+		ret = opt3001_get_int_time(opt, val, val2);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	mutex_unlock(&opt->lock);
+
+	return ret;
+}
+
+static int opt3001_write_raw(struct iio_dev *iio,
+		struct iio_chan_spec const *chan, int val, int val2,
+		long mask)
+{
+	struct opt3001 *opt = iio_priv(iio);
+	int ret;
+
+	if (opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS)
+		return -EBUSY;
+
+	if (chan->type != IIO_LIGHT)
+		return -EINVAL;
+
+	if (mask != IIO_CHAN_INFO_INT_TIME)
+		return -EINVAL;
+
+	if (val != 0)
+		return -EINVAL;
+
+	mutex_lock(&opt->lock);
+	ret = opt3001_set_int_time(opt, val2);
+	mutex_unlock(&opt->lock);
+
+	return ret;
+}
+
+static int opt3001_read_event_value(struct iio_dev *iio,
+		const struct iio_chan_spec *chan, enum iio_event_type type,
+		enum iio_event_direction dir, enum iio_event_info info,
+		int *val, int *val2)
+{
+	struct opt3001 *opt = iio_priv(iio);
+	int ret = IIO_VAL_INT_PLUS_MICRO;
+
+	mutex_lock(&opt->lock);
+
+	switch (dir) {
+	case IIO_EV_DIR_RISING:
+		opt3001_to_iio_ret(opt, opt->high_thresh_exp,
+				opt->high_thresh_mantissa, val, val2);
+		break;
+	case IIO_EV_DIR_FALLING:
+		opt3001_to_iio_ret(opt, opt->low_thresh_exp,
+				opt->low_thresh_mantissa, val, val2);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	mutex_unlock(&opt->lock);
+
+	return ret;
+}
+
+static int opt3001_write_event_value(struct iio_dev *iio,
+		const struct iio_chan_spec *chan, enum iio_event_type type,
+		enum iio_event_direction dir, enum iio_event_info info,
+		int val, int val2)
+{
+	struct opt3001 *opt = iio_priv(iio);
+	int ret;
+
+	u16 mantissa;
+	u16 value;
+	u16 reg;
+
+	u8 exponent;
+
+	if (val < 0)
+		return -EINVAL;
+
+	mutex_lock(&opt->lock);
+
+	ret = opt3001_find_scale(opt, val, val2, &exponent);
+	if (ret < 0) {
+		dev_err(opt->dev, "can't find scale for %d.%06u\n", val, val2);
+		goto err;
+	}
+
+	mantissa = (((val * 1000) + (val2 / 1000)) / 10) >> exponent;
+	value = (exponent << 12) | mantissa;
+
+	switch (dir) {
+	case IIO_EV_DIR_RISING:
+		reg = OPT3001_HIGH_LIMIT;
+		opt->high_thresh_mantissa = mantissa;
+		opt->high_thresh_exp = exponent;
+		break;
+	case IIO_EV_DIR_FALLING:
+		reg = OPT3001_LOW_LIMIT;
+		opt->low_thresh_mantissa = mantissa;
+		opt->low_thresh_exp = exponent;
+		break;
+	default:
+		ret = -EINVAL;
+		goto err;
+	}
+
+	ret = i2c_smbus_write_word_swapped(opt->client, reg, value);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to write register %02x\n", reg);
+		goto err;
+	}
+
+err:
+	mutex_unlock(&opt->lock);
+
+	return ret;
+}
+
+static int opt3001_read_event_config(struct iio_dev *iio,
+		const struct iio_chan_spec *chan, enum iio_event_type type,
+		enum iio_event_direction dir)
+{
+	struct opt3001 *opt = iio_priv(iio);
+
+	return opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS;
+}
+
+static int opt3001_write_event_config(struct iio_dev *iio,
+		const struct iio_chan_spec *chan, enum iio_event_type type,
+		enum iio_event_direction dir, int state)
+{
+	struct opt3001 *opt = iio_priv(iio);
+	int ret;
+	u16 mode;
+	u16 reg;
+
+	if (state && opt->mode == OPT3001_CONFIGURATION_M_CONTINUOUS)
+		return 0;
+
+	if (!state && opt->mode == OPT3001_CONFIGURATION_M_SHUTDOWN)
+		return 0;
+
+	mutex_lock(&opt->lock);
+
+	mode = state ? OPT3001_CONFIGURATION_M_CONTINUOUS
+		: OPT3001_CONFIGURATION_M_SHUTDOWN;
+
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_CONFIGURATION);
+		goto err;
+	}
+
+	reg = ret;
+	opt3001_set_mode(opt, &reg, mode);
+
+	ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION,
+			reg);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to write register %02x\n",
+				OPT3001_CONFIGURATION);
+		goto err;
+	}
+
+err:
+	mutex_unlock(&opt->lock);
+
+	return ret;
+}
+
+static const struct iio_info opt3001_info = {
+	.driver_module = THIS_MODULE,
+	.attrs = &opt3001_attribute_group,
+	.read_raw = opt3001_read_raw,
+	.write_raw = opt3001_write_raw,
+	.read_event_value = opt3001_read_event_value,
+	.write_event_value = opt3001_write_event_value,
+	.read_event_config = opt3001_read_event_config,
+	.write_event_config = opt3001_write_event_config,
+};
+
+static int opt3001_read_id(struct opt3001 *opt)
+{
+	char manufacturer[2];
+	u16 device_id;
+	int ret;
+
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_MANUFACTURER_ID);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_MANUFACTURER_ID);
+		return ret;
+	}
+
+	manufacturer[0] = ret >> 8;
+	manufacturer[1] = ret & 0xff;
+
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_DEVICE_ID);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_DEVICE_ID);
+		return ret;
+	}
+
+	device_id = ret;
+
+	dev_info(opt->dev, "Found %c%c OPT%04x\n", manufacturer[0],
+			manufacturer[1], device_id);
+
+	return 0;
+}
+
+static int opt3001_configure(struct opt3001 *opt)
+{
+	int ret;
+	u16 reg;
+
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_CONFIGURATION);
+		return ret;
+	}
+
+	reg = ret;
+
+	/* Enable automatic full-scale setting mode */
+	reg &= ~OPT3001_CONFIGURATION_RN_MASK;
+	reg |= OPT3001_CONFIGURATION_RN_AUTO;
+
+	/* Reflect status of the device's integration time setting */
+	if (reg & OPT3001_CONFIGURATION_CT)
+		opt->int_time = 800000;
+	else
+		opt->int_time = 100000;
+
+	/* Ensure device is in shutdown initially */
+	opt3001_set_mode(opt, &reg, OPT3001_CONFIGURATION_M_SHUTDOWN);
+
+	/* Configure for latched window-style comparison operation */
+	reg |= OPT3001_CONFIGURATION_L;
+	reg &= ~OPT3001_CONFIGURATION_POL;
+	reg &= ~OPT3001_CONFIGURATION_ME;
+	reg &= ~OPT3001_CONFIGURATION_FC_MASK;
+
+	ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION,
+			reg);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to write register %02x\n",
+				OPT3001_CONFIGURATION);
+		return ret;
+	}
+
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_LOW_LIMIT);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_LOW_LIMIT);
+		return ret;
+	}
+
+	opt->low_thresh_mantissa = OPT3001_REG_MANTISSA(ret);
+	opt->low_thresh_exp = OPT3001_REG_EXPONENT(ret);
+
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_HIGH_LIMIT);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_HIGH_LIMIT);
+		return ret;
+	}
+
+	opt->high_thresh_mantissa = OPT3001_REG_MANTISSA(ret);
+	opt->high_thresh_exp = OPT3001_REG_EXPONENT(ret);
+
+	return 0;
+}
+
+static irqreturn_t opt3001_irq(int irq, void *_iio)
+{
+	struct iio_dev *iio = _iio;
+	struct opt3001 *opt = iio_priv(iio);
+	int ret;
+
+	if (!opt->ok_to_ignore_lock)
+		mutex_lock(&opt->lock);
+
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_CONFIGURATION);
+		goto out;
+	}
+
+	if ((ret & OPT3001_CONFIGURATION_M_MASK) ==
+			OPT3001_CONFIGURATION_M_CONTINUOUS) {
+		if (ret & OPT3001_CONFIGURATION_FH)
+			iio_push_event(iio,
+					IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
+							IIO_EV_TYPE_THRESH,
+							IIO_EV_DIR_RISING),
+					iio_get_time_ns());
+		if (ret & OPT3001_CONFIGURATION_FL)
+			iio_push_event(iio,
+					IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
+							IIO_EV_TYPE_THRESH,
+							IIO_EV_DIR_FALLING),
+					iio_get_time_ns());
+	} else if (ret & OPT3001_CONFIGURATION_CRF) {
+		ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_RESULT);
+		if (ret < 0) {
+			dev_err(opt->dev, "failed to read register %02x\n",
+					OPT3001_RESULT);
+			goto out;
+		}
+		opt->result = ret;
+		opt->result_ready = true;
+		wake_up(&opt->result_ready_queue);
+	}
+
+out:
+	if (!opt->ok_to_ignore_lock)
+		mutex_unlock(&opt->lock);
+
+	return IRQ_HANDLED;
+}
+
+static int opt3001_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+
+	struct iio_dev *iio;
+	struct opt3001 *opt;
+	int irq = client->irq;
+	int ret;
+
+	iio = devm_iio_device_alloc(dev, sizeof(*opt));
+	if (!iio)
+		return -ENOMEM;
+
+	opt = iio_priv(iio);
+	opt->client = client;
+	opt->dev = dev;
+
+	mutex_init(&opt->lock);
+	init_waitqueue_head(&opt->result_ready_queue);
+	i2c_set_clientdata(client, iio);
+
+	ret = opt3001_read_id(opt);
+	if (ret)
+		return ret;
+
+	ret = opt3001_configure(opt);
+	if (ret)
+		return ret;
+
+	iio->name = client->name;
+	iio->channels = opt3001_channels;
+	iio->num_channels = ARRAY_SIZE(opt3001_channels);
+	iio->dev.parent = dev;
+	iio->modes = INDIO_DIRECT_MODE;
+	iio->info = &opt3001_info;
+
+	ret = devm_iio_device_register(dev, iio);
+	if (ret) {
+		dev_err(dev, "failed to register IIO device\n");
+		return ret;
+	}
+
+	ret = request_threaded_irq(irq, NULL, opt3001_irq,
+			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+			"opt3001", iio);
+	if (ret) {
+		dev_err(dev, "failed to request IRQ #%d\n", irq);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int opt3001_remove(struct i2c_client *client)
+{
+	struct iio_dev *iio = i2c_get_clientdata(client);
+	struct opt3001 *opt = iio_priv(iio);
+	int ret;
+	u16 reg;
+
+	free_irq(client->irq, iio);
+
+	ret = i2c_smbus_read_word_swapped(opt->client, OPT3001_CONFIGURATION);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to read register %02x\n",
+				OPT3001_CONFIGURATION);
+		return ret;
+	}
+
+	reg = ret;
+	opt3001_set_mode(opt, &reg, OPT3001_CONFIGURATION_M_SHUTDOWN);
+
+	ret = i2c_smbus_write_word_swapped(opt->client, OPT3001_CONFIGURATION,
+			reg);
+	if (ret < 0) {
+		dev_err(opt->dev, "failed to write register %02x\n",
+				OPT3001_CONFIGURATION);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct i2c_device_id opt3001_id[] = {
+	{ "opt3001", 0 },
+	{ } /* Terminating Entry */
+};
+MODULE_DEVICE_TABLE(i2c, opt3001_id);
+
+static const struct of_device_id opt3001_of_match[] = {
+	{ .compatible = "ti,opt3001" },
+	{ }
+};
+
+static struct i2c_driver opt3001_driver = {
+	.probe = opt3001_probe,
+	.remove = opt3001_remove,
+	.id_table = opt3001_id,
+
+	.driver = {
+		.name = "opt3001",
+		.of_match_table = of_match_ptr(opt3001_of_match),
+		.owner = THIS_MODULE,
+	},
+};
+
+module_i2c_driver(opt3001_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>");
+MODULE_DESCRIPTION("Texas Instruments OPT3001 Light Sensor Driver");

+ 483 - 0
drivers/iio/light/pa12203001.c

@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Driver for TXC PA12203001 Proximity and Ambient Light Sensor.
+ *
+ * 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.
+ * To do: Interrupt support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/mutex.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#define PA12203001_DRIVER_NAME	"pa12203001"
+
+#define PA12203001_REG_CFG0		0x00
+#define PA12203001_REG_CFG1		0x01
+#define PA12203001_REG_CFG2		0x02
+#define PA12203001_REG_CFG3		0x03
+
+#define PA12203001_REG_ADL		0x0b
+#define PA12203001_REG_PDH		0x0e
+
+#define PA12203001_REG_POFS		0x10
+#define PA12203001_REG_PSET		0x11
+
+#define PA12203001_ALS_EN_MASK		BIT(0)
+#define PA12203001_PX_EN_MASK		BIT(1)
+#define PA12203001_PX_NORMAL_MODE_MASK		GENMASK(7, 6)
+#define PA12203001_AFSR_MASK		GENMASK(5, 4)
+#define PA12203001_AFSR_SHIFT		4
+
+#define PA12203001_PSCAN			0x03
+
+/* als range 31000, ps, als disabled */
+#define PA12203001_REG_CFG0_DEFAULT		0x30
+
+/* led current: 100 mA */
+#define PA12203001_REG_CFG1_DEFAULT		0x20
+
+/* ps mode: normal, interrupts not active */
+#define PA12203001_REG_CFG2_DEFAULT		0xcc
+
+#define PA12203001_REG_CFG3_DEFAULT		0x00
+
+#define PA12203001_SLEEP_DELAY_MS		3000
+
+#define PA12203001_CHIP_ENABLE		0xff
+#define PA12203001_CHIP_DISABLE		0x00
+
+/* available scales: corresponding to [500, 4000, 7000, 31000]  lux */
+static const int pa12203001_scales[] = { 7629, 61036, 106813, 473029};
+
+struct pa12203001_data {
+	struct i2c_client *client;
+
+	/* protect device states */
+	struct mutex lock;
+
+	bool als_enabled;
+	bool px_enabled;
+	bool als_needs_enable;
+	bool px_needs_enable;
+
+	struct regmap *map;
+};
+
+static const struct {
+	u8 reg;
+	u8 val;
+} regvals[] = {
+	{PA12203001_REG_CFG0, PA12203001_REG_CFG0_DEFAULT},
+	{PA12203001_REG_CFG1, PA12203001_REG_CFG1_DEFAULT},
+	{PA12203001_REG_CFG2, PA12203001_REG_CFG2_DEFAULT},
+	{PA12203001_REG_CFG3, PA12203001_REG_CFG3_DEFAULT},
+	{PA12203001_REG_PSET, PA12203001_PSCAN},
+};
+
+static IIO_CONST_ATTR(in_illuminance_scale_available,
+		      "0.007629 0.061036 0.106813 0.473029");
+
+static struct attribute *pa12203001_attrs[] = {
+	&iio_const_attr_in_illuminance_scale_available.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group pa12203001_attr_group = {
+	.attrs = pa12203001_attrs,
+};
+
+static const struct iio_chan_spec pa12203001_channels[] = {
+	{
+		.type = IIO_LIGHT,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				      BIT(IIO_CHAN_INFO_SCALE),
+	},
+	{
+		.type = IIO_PROXIMITY,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+	}
+};
+
+static const struct regmap_range pa12203001_volatile_regs_ranges[] = {
+	regmap_reg_range(PA12203001_REG_ADL, PA12203001_REG_ADL + 1),
+	regmap_reg_range(PA12203001_REG_PDH, PA12203001_REG_PDH),
+};
+
+static const struct regmap_access_table pa12203001_volatile_regs = {
+	.yes_ranges = pa12203001_volatile_regs_ranges,
+	.n_yes_ranges = ARRAY_SIZE(pa12203001_volatile_regs_ranges),
+};
+
+static const struct regmap_config pa12203001_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = PA12203001_REG_PSET,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_table = &pa12203001_volatile_regs,
+};
+
+static inline int pa12203001_als_enable(struct pa12203001_data *data, u8 enable)
+{
+	int ret;
+
+	ret = regmap_update_bits(data->map, PA12203001_REG_CFG0,
+				 PA12203001_ALS_EN_MASK, enable);
+	if (ret < 0)
+		return ret;
+
+	data->als_enabled = !!enable;
+
+	return 0;
+}
+
+static inline int pa12203001_px_enable(struct pa12203001_data *data, u8 enable)
+{
+	int ret;
+
+	ret = regmap_update_bits(data->map, PA12203001_REG_CFG0,
+				 PA12203001_PX_EN_MASK, enable);
+	if (ret < 0)
+		return ret;
+
+	data->px_enabled = !!enable;
+
+	return 0;
+}
+
+static int pa12203001_set_power_state(struct pa12203001_data *data, bool on,
+				      u8 mask)
+{
+#ifdef CONFIG_PM
+	int ret;
+
+	if (on && (mask & PA12203001_ALS_EN_MASK)) {
+		mutex_lock(&data->lock);
+		if (data->px_enabled) {
+			ret = pa12203001_als_enable(data,
+						    PA12203001_ALS_EN_MASK);
+			if (ret < 0)
+				goto err;
+		} else {
+			data->als_needs_enable = true;
+		}
+		mutex_unlock(&data->lock);
+	}
+
+	if (on && (mask & PA12203001_PX_EN_MASK)) {
+		mutex_lock(&data->lock);
+		if (data->als_enabled) {
+			ret = pa12203001_px_enable(data, PA12203001_PX_EN_MASK);
+			if (ret < 0)
+				goto err;
+		} else {
+			data->px_needs_enable = true;
+		}
+		mutex_unlock(&data->lock);
+	}
+
+	if (on) {
+		ret = pm_runtime_get_sync(&data->client->dev);
+		if (ret < 0)
+			pm_runtime_put_noidle(&data->client->dev);
+
+	} else {
+		pm_runtime_mark_last_busy(&data->client->dev);
+		ret = pm_runtime_put_autosuspend(&data->client->dev);
+	}
+
+	return ret;
+
+err:
+	mutex_unlock(&data->lock);
+	return ret;
+
+#endif
+	return 0;
+}
+
+static int pa12203001_read_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan, int *val,
+			       int *val2, long mask)
+{
+	struct pa12203001_data *data = iio_priv(indio_dev);
+	int ret;
+	u8 dev_mask;
+	unsigned int reg_byte;
+	__le16 reg_word;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		switch (chan->type) {
+		case IIO_LIGHT:
+			dev_mask = PA12203001_ALS_EN_MASK;
+			ret = pa12203001_set_power_state(data, true, dev_mask);
+			if (ret < 0)
+				return ret;
+			/*
+			 * ALS ADC value is stored in registers
+			 * PA12203001_REG_ADL and in PA12203001_REG_ADL + 1.
+			 */
+			ret = regmap_bulk_read(data->map, PA12203001_REG_ADL,
+					       &reg_word, 2);
+			if (ret < 0)
+				goto reg_err;
+
+			*val = le16_to_cpu(reg_word);
+			ret = pa12203001_set_power_state(data, false, dev_mask);
+			if (ret < 0)
+				return ret;
+			break;
+		case IIO_PROXIMITY:
+			dev_mask = PA12203001_PX_EN_MASK;
+			ret = pa12203001_set_power_state(data, true, dev_mask);
+			if (ret < 0)
+				return ret;
+			ret = regmap_read(data->map, PA12203001_REG_PDH,
+					  &reg_byte);
+			if (ret < 0)
+				goto reg_err;
+
+			*val = reg_byte;
+			ret = pa12203001_set_power_state(data, false, dev_mask);
+			if (ret < 0)
+				return ret;
+			break;
+		default:
+			return -EINVAL;
+		}
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		ret = regmap_read(data->map, PA12203001_REG_CFG0, &reg_byte);
+		if (ret < 0)
+			return ret;
+		*val = 0;
+		reg_byte = (reg_byte & PA12203001_AFSR_MASK);
+		*val2 = pa12203001_scales[reg_byte >> 4];
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+
+reg_err:
+	pa12203001_set_power_state(data, false, dev_mask);
+	return ret;
+}
+
+static int pa12203001_write_raw(struct iio_dev *indio_dev,
+				struct iio_chan_spec const *chan, int val,
+				int val2, long mask)
+{
+	struct pa12203001_data *data = iio_priv(indio_dev);
+	int i, ret, new_val;
+	unsigned int reg_byte;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		ret = regmap_read(data->map, PA12203001_REG_CFG0, &reg_byte);
+		if (val != 0 || ret < 0)
+			return -EINVAL;
+		for (i = 0; i < ARRAY_SIZE(pa12203001_scales); i++) {
+			if (val2 == pa12203001_scales[i]) {
+				new_val = i << PA12203001_AFSR_SHIFT;
+				return regmap_update_bits(data->map,
+							  PA12203001_REG_CFG0,
+							  PA12203001_AFSR_MASK,
+							  new_val);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static const struct iio_info pa12203001_info = {
+	.driver_module	= THIS_MODULE,
+	.read_raw = pa12203001_read_raw,
+	.write_raw = pa12203001_write_raw,
+	.attrs = &pa12203001_attr_group,
+};
+
+static int pa12203001_init(struct iio_dev *indio_dev)
+{
+	struct pa12203001_data *data = iio_priv(indio_dev);
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(regvals); i++) {
+		ret = regmap_write(data->map, regvals[i].reg, regvals[i].val);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int pa12203001_power_chip(struct iio_dev *indio_dev, u8 state)
+{
+	struct pa12203001_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->lock);
+	ret = pa12203001_als_enable(data, state);
+	if (ret < 0)
+		goto out;
+
+	ret = pa12203001_px_enable(data, state);
+
+out:
+	mutex_unlock(&data->lock);
+	return ret;
+}
+
+static int pa12203001_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	struct pa12203001_data *data;
+	struct iio_dev *indio_dev;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&client->dev,
+					  sizeof(struct pa12203001_data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+
+	data->map = devm_regmap_init_i2c(client, &pa12203001_regmap_config);
+	if (IS_ERR(data->map))
+		return PTR_ERR(data->map);
+
+	mutex_init(&data->lock);
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->info = &pa12203001_info;
+	indio_dev->name = PA12203001_DRIVER_NAME;
+	indio_dev->channels = pa12203001_channels;
+	indio_dev->num_channels = ARRAY_SIZE(pa12203001_channels);
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = pa12203001_init(indio_dev);
+	if (ret < 0)
+		return ret;
+
+	ret = pa12203001_power_chip(indio_dev, PA12203001_CHIP_ENABLE);
+	if (ret < 0)
+		return ret;
+
+	ret = pm_runtime_set_active(&client->dev);
+	if (ret < 0) {
+		pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE);
+		return ret;
+	}
+
+	pm_runtime_enable(&client->dev);
+	pm_runtime_set_autosuspend_delay(&client->dev,
+					 PA12203001_SLEEP_DELAY_MS);
+	pm_runtime_use_autosuspend(&client->dev);
+
+	return iio_device_register(indio_dev);
+}
+
+static int pa12203001_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+	iio_device_unregister(indio_dev);
+
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
+
+	return pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE);
+}
+
+#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM)
+static int pa12203001_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+
+	return pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE);
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int pa12203001_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+
+	return pa12203001_power_chip(indio_dev, PA12203001_CHIP_ENABLE);
+}
+#endif
+
+#ifdef CONFIG_PM
+static int pa12203001_runtime_resume(struct device *dev)
+{
+	struct pa12203001_data *data;
+
+	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+
+	mutex_lock(&data->lock);
+	if (data->als_needs_enable) {
+		pa12203001_als_enable(data, PA12203001_ALS_EN_MASK);
+		data->als_needs_enable = false;
+	}
+	if (data->px_needs_enable) {
+		pa12203001_px_enable(data, PA12203001_PX_EN_MASK);
+		data->px_needs_enable = false;
+	}
+	mutex_unlock(&data->lock);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops pa12203001_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pa12203001_suspend, pa12203001_resume)
+	SET_RUNTIME_PM_OPS(pa12203001_suspend, pa12203001_runtime_resume, NULL)
+};
+
+static const struct acpi_device_id pa12203001_acpi_match[] = {
+	{ "TXCPA122", 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(acpi, pa12203001_acpi_match);
+
+static const struct i2c_device_id pa12203001_id[] = {
+		{"txcpa122", 0},
+		{}
+};
+
+MODULE_DEVICE_TABLE(i2c, pa12203001_id);
+
+static struct i2c_driver pa12203001_driver = {
+	.driver = {
+		.name = PA12203001_DRIVER_NAME,
+		.pm = &pa12203001_pm_ops,
+		.acpi_match_table = ACPI_PTR(pa12203001_acpi_match),
+	},
+	.probe = pa12203001_probe,
+	.remove = pa12203001_remove,
+	.id_table = pa12203001_id,
+
+};
+module_i2c_driver(pa12203001_driver);
+
+MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
+MODULE_DESCRIPTION("Driver for TXC PA12203001 Proximity and Light Sensor");
+MODULE_LICENSE("GPL v2");

+ 615 - 0
drivers/iio/light/rpr0521.c

@@ -0,0 +1,615 @@
+/*
+ * RPR-0521 ROHM Ambient Light and Proximity Sensor
+ *
+ * Copyright (c) 2015, Intel Corporation.
+ *
+ * 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.
+ *
+ * IIO driver for RPR-0521RS (7-bit I2C slave address 0x38).
+ *
+ * TODO: illuminance channel, PM support, buffer
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/acpi.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/pm_runtime.h>
+
+#define RPR0521_REG_SYSTEM_CTRL		0x40
+#define RPR0521_REG_MODE_CTRL		0x41
+#define RPR0521_REG_ALS_CTRL		0x42
+#define RPR0521_REG_PXS_CTRL		0x43
+#define RPR0521_REG_PXS_DATA		0x44 /* 16-bit, little endian */
+#define RPR0521_REG_ALS_DATA0		0x46 /* 16-bit, little endian */
+#define RPR0521_REG_ALS_DATA1		0x48 /* 16-bit, little endian */
+#define RPR0521_REG_ID			0x92
+
+#define RPR0521_MODE_ALS_MASK		BIT(7)
+#define RPR0521_MODE_PXS_MASK		BIT(6)
+#define RPR0521_MODE_MEAS_TIME_MASK	GENMASK(3, 0)
+#define RPR0521_ALS_DATA0_GAIN_MASK	GENMASK(5, 4)
+#define RPR0521_ALS_DATA0_GAIN_SHIFT	4
+#define RPR0521_ALS_DATA1_GAIN_MASK	GENMASK(3, 2)
+#define RPR0521_ALS_DATA1_GAIN_SHIFT	2
+#define RPR0521_PXS_GAIN_MASK		GENMASK(5, 4)
+#define RPR0521_PXS_GAIN_SHIFT		4
+
+#define RPR0521_MODE_ALS_ENABLE		BIT(7)
+#define RPR0521_MODE_ALS_DISABLE	0x00
+#define RPR0521_MODE_PXS_ENABLE		BIT(6)
+#define RPR0521_MODE_PXS_DISABLE	0x00
+
+#define RPR0521_MANUFACT_ID		0xE0
+#define RPR0521_DEFAULT_MEAS_TIME	0x06 /* ALS - 100ms, PXS - 100ms */
+
+#define RPR0521_DRV_NAME		"RPR0521"
+#define RPR0521_REGMAP_NAME		"rpr0521_regmap"
+
+#define RPR0521_SLEEP_DELAY_MS	2000
+
+#define RPR0521_ALS_SCALE_AVAIL "0.007812 0.015625 0.5 1"
+#define RPR0521_PXS_SCALE_AVAIL "0.125 0.5 1"
+
+struct rpr0521_gain {
+	int scale;
+	int uscale;
+};
+
+static const struct rpr0521_gain rpr0521_als_gain[4] = {
+	{1, 0},		/* x1 */
+	{0, 500000},	/* x2 */
+	{0, 15625},	/* x64 */
+	{0, 7812},	/* x128 */
+};
+
+static const struct rpr0521_gain rpr0521_pxs_gain[3] = {
+	{1, 0},		/* x1 */
+	{0, 500000},	/* x2 */
+	{0, 125000},	/* x4 */
+};
+
+enum rpr0521_channel {
+	RPR0521_CHAN_ALS_DATA0,
+	RPR0521_CHAN_ALS_DATA1,
+	RPR0521_CHAN_PXS,
+};
+
+struct rpr0521_reg_desc {
+	u8 address;
+	u8 device_mask;
+};
+
+static const struct rpr0521_reg_desc rpr0521_data_reg[] = {
+	[RPR0521_CHAN_ALS_DATA0] = {
+		.address	= RPR0521_REG_ALS_DATA0,
+		.device_mask	= RPR0521_MODE_ALS_MASK,
+	},
+	[RPR0521_CHAN_ALS_DATA1] = {
+		.address	= RPR0521_REG_ALS_DATA1,
+		.device_mask	= RPR0521_MODE_ALS_MASK,
+	},
+	[RPR0521_CHAN_PXS]	= {
+		.address	= RPR0521_REG_PXS_DATA,
+		.device_mask	= RPR0521_MODE_PXS_MASK,
+	},
+};
+
+static const struct rpr0521_gain_info {
+	u8 reg;
+	u8 mask;
+	u8 shift;
+	const struct rpr0521_gain *gain;
+	int size;
+} rpr0521_gain[] = {
+	[RPR0521_CHAN_ALS_DATA0] = {
+		.reg	= RPR0521_REG_ALS_CTRL,
+		.mask	= RPR0521_ALS_DATA0_GAIN_MASK,
+		.shift	= RPR0521_ALS_DATA0_GAIN_SHIFT,
+		.gain	= rpr0521_als_gain,
+		.size	= ARRAY_SIZE(rpr0521_als_gain),
+	},
+	[RPR0521_CHAN_ALS_DATA1] = {
+		.reg	= RPR0521_REG_ALS_CTRL,
+		.mask	= RPR0521_ALS_DATA1_GAIN_MASK,
+		.shift	= RPR0521_ALS_DATA1_GAIN_SHIFT,
+		.gain	= rpr0521_als_gain,
+		.size	= ARRAY_SIZE(rpr0521_als_gain),
+	},
+	[RPR0521_CHAN_PXS] = {
+		.reg	= RPR0521_REG_PXS_CTRL,
+		.mask	= RPR0521_PXS_GAIN_MASK,
+		.shift	= RPR0521_PXS_GAIN_SHIFT,
+		.gain	= rpr0521_pxs_gain,
+		.size	= ARRAY_SIZE(rpr0521_pxs_gain),
+	},
+};
+
+struct rpr0521_data {
+	struct i2c_client *client;
+
+	/* protect device params updates (e.g state, gain) */
+	struct mutex lock;
+
+	/* device active status */
+	bool als_dev_en;
+	bool pxs_dev_en;
+
+	/* optimize runtime pm ops - enable device only if needed */
+	bool als_ps_need_en;
+	bool pxs_ps_need_en;
+
+	struct regmap *regmap;
+};
+
+static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
+static IIO_CONST_ATTR(in_proximity_scale_available, RPR0521_PXS_SCALE_AVAIL);
+
+static struct attribute *rpr0521_attributes[] = {
+	&iio_const_attr_in_intensity_scale_available.dev_attr.attr,
+	&iio_const_attr_in_proximity_scale_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group rpr0521_attribute_group = {
+	.attrs = rpr0521_attributes,
+};
+
+static const struct iio_chan_spec rpr0521_channels[] = {
+	{
+		.type = IIO_INTENSITY,
+		.modified = 1,
+		.address = RPR0521_CHAN_ALS_DATA0,
+		.channel2 = IIO_MOD_LIGHT_BOTH,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE),
+	},
+	{
+		.type = IIO_INTENSITY,
+		.modified = 1,
+		.address = RPR0521_CHAN_ALS_DATA1,
+		.channel2 = IIO_MOD_LIGHT_IR,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE),
+	},
+	{
+		.type = IIO_PROXIMITY,
+		.address = RPR0521_CHAN_PXS,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE),
+	}
+};
+
+static int rpr0521_als_enable(struct rpr0521_data *data, u8 status)
+{
+	int ret;
+
+	ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+				 RPR0521_MODE_ALS_MASK,
+				 status);
+	if (ret < 0)
+		return ret;
+
+	data->als_dev_en = true;
+
+	return 0;
+}
+
+static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status)
+{
+	int ret;
+
+	ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+				 RPR0521_MODE_PXS_MASK,
+				 status);
+	if (ret < 0)
+		return ret;
+
+	data->pxs_dev_en = true;
+
+	return 0;
+}
+
+/**
+ * rpr0521_set_power_state - handles runtime PM state and sensors enabled status
+ *
+ * @data: rpr0521 device private data
+ * @on: state to be set for devices in @device_mask
+ * @device_mask: bitmask specifying for which device we need to update @on state
+ *
+ * We rely on rpr0521_runtime_resume to enable our @device_mask devices, but
+ * if (for example) PXS was enabled (pxs_dev_en = true) by a previous call to
+ * rpr0521_runtime_resume and we want to enable ALS we MUST set ALS enable
+ * bit of RPR0521_REG_MODE_CTRL here because rpr0521_runtime_resume will not
+ * be called twice.
+ */
+static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
+				   u8 device_mask)
+{
+#ifdef CONFIG_PM
+	int ret;
+	u8 update_mask = 0;
+
+	if (device_mask & RPR0521_MODE_ALS_MASK) {
+		if (on && !data->als_ps_need_en && data->pxs_dev_en)
+			update_mask |= RPR0521_MODE_ALS_MASK;
+		else
+			data->als_ps_need_en = on;
+	}
+
+	if (device_mask & RPR0521_MODE_PXS_MASK) {
+		if (on && !data->pxs_ps_need_en && data->als_dev_en)
+			update_mask |= RPR0521_MODE_PXS_MASK;
+		else
+			data->pxs_ps_need_en = on;
+	}
+
+	if (update_mask) {
+		ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+					 update_mask, update_mask);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (on) {
+		ret = pm_runtime_get_sync(&data->client->dev);
+	} else {
+		pm_runtime_mark_last_busy(&data->client->dev);
+		ret = pm_runtime_put_autosuspend(&data->client->dev);
+	}
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"Failed: rpr0521_set_power_state for %d, ret %d\n",
+			on, ret);
+		if (on)
+			pm_runtime_put_noidle(&data->client->dev);
+
+		return ret;
+	}
+#endif
+	return 0;
+}
+
+static int rpr0521_get_gain(struct rpr0521_data *data, int chan,
+			    int *val, int *val2)
+{
+	int ret, reg, idx;
+
+	ret = regmap_read(data->regmap, rpr0521_gain[chan].reg, &reg);
+	if (ret < 0)
+		return ret;
+
+	idx = (rpr0521_gain[chan].mask & reg) >> rpr0521_gain[chan].shift;
+	*val = rpr0521_gain[chan].gain[idx].scale;
+	*val2 = rpr0521_gain[chan].gain[idx].uscale;
+
+	return 0;
+}
+
+static int rpr0521_set_gain(struct rpr0521_data *data, int chan,
+			    int val, int val2)
+{
+	int i, idx = -EINVAL;
+
+	/* get gain index */
+	for (i = 0; i < rpr0521_gain[chan].size; i++)
+		if (val == rpr0521_gain[chan].gain[i].scale &&
+		    val2 == rpr0521_gain[chan].gain[i].uscale) {
+			idx = i;
+			break;
+		}
+
+	if (idx < 0)
+		return idx;
+
+	return regmap_update_bits(data->regmap, rpr0521_gain[chan].reg,
+				  rpr0521_gain[chan].mask,
+				  idx << rpr0521_gain[chan].shift);
+}
+
+static int rpr0521_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan, int *val,
+			    int *val2, long mask)
+{
+	struct rpr0521_data *data = iio_priv(indio_dev);
+	int ret;
+	u8 device_mask;
+	__le16 raw_data;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		if (chan->type != IIO_INTENSITY && chan->type != IIO_PROXIMITY)
+			return -EINVAL;
+
+		device_mask = rpr0521_data_reg[chan->address].device_mask;
+
+		mutex_lock(&data->lock);
+		ret = rpr0521_set_power_state(data, true, device_mask);
+		if (ret < 0) {
+			mutex_unlock(&data->lock);
+			return ret;
+		}
+
+		ret = regmap_bulk_read(data->regmap,
+				       rpr0521_data_reg[chan->address].address,
+				       &raw_data, 2);
+		if (ret < 0) {
+			rpr0521_set_power_state(data, false, device_mask);
+			mutex_unlock(&data->lock);
+			return ret;
+		}
+
+		ret = rpr0521_set_power_state(data, false, device_mask);
+		mutex_unlock(&data->lock);
+		if (ret < 0)
+			return ret;
+
+		*val = le16_to_cpu(raw_data);
+
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		mutex_lock(&data->lock);
+		ret = rpr0521_get_gain(data, chan->address, val, val2);
+		mutex_unlock(&data->lock);
+		if (ret < 0)
+			return ret;
+
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int rpr0521_write_raw(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan, int val,
+			     int val2, long mask)
+{
+	struct rpr0521_data *data = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SCALE:
+		mutex_lock(&data->lock);
+		ret = rpr0521_set_gain(data, chan->address, val, val2);
+		mutex_unlock(&data->lock);
+
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct iio_info rpr0521_info = {
+	.driver_module	= THIS_MODULE,
+	.read_raw	= rpr0521_read_raw,
+	.write_raw	= rpr0521_write_raw,
+	.attrs		= &rpr0521_attribute_group,
+};
+
+static int rpr0521_init(struct rpr0521_data *data)
+{
+	int ret;
+	int id;
+
+	ret = regmap_read(data->regmap, RPR0521_REG_ID, &id);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Failed to read REG_ID register\n");
+		return ret;
+	}
+
+	if (id != RPR0521_MANUFACT_ID) {
+		dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n",
+			id, RPR0521_MANUFACT_ID);
+		return -ENODEV;
+	}
+
+	/* set default measurement time - 100 ms for both ALS and PS */
+	ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+				 RPR0521_MODE_MEAS_TIME_MASK,
+				 RPR0521_DEFAULT_MEAS_TIME);
+	if (ret) {
+		pr_err("regmap_update_bits returned %d\n", ret);
+		return ret;
+	}
+
+	ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
+	if (ret < 0)
+		return ret;
+	ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int rpr0521_poweroff(struct rpr0521_data *data)
+{
+	int ret;
+
+	ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
+				 RPR0521_MODE_ALS_MASK |
+				 RPR0521_MODE_PXS_MASK,
+				 RPR0521_MODE_ALS_DISABLE |
+				 RPR0521_MODE_PXS_DISABLE);
+	if (ret < 0)
+		return ret;
+
+	data->als_dev_en = false;
+	data->pxs_dev_en = false;
+
+	return 0;
+}
+
+static bool rpr0521_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case RPR0521_REG_MODE_CTRL:
+	case RPR0521_REG_ALS_CTRL:
+	case RPR0521_REG_PXS_CTRL:
+		return false;
+	default:
+		return true;
+	}
+}
+
+static const struct regmap_config rpr0521_regmap_config = {
+	.name		= RPR0521_REGMAP_NAME,
+
+	.reg_bits	= 8,
+	.val_bits	= 8,
+
+	.max_register	= RPR0521_REG_ID,
+	.cache_type	= REGCACHE_RBTREE,
+	.volatile_reg	= rpr0521_is_volatile_reg,
+};
+
+static int rpr0521_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct rpr0521_data *data;
+	struct iio_dev *indio_dev;
+	struct regmap *regmap;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	regmap = devm_regmap_init_i2c(client, &rpr0521_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "regmap_init failed!\n");
+		return PTR_ERR(regmap);
+	}
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+	data->regmap = regmap;
+
+	mutex_init(&data->lock);
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->info = &rpr0521_info;
+	indio_dev->name = RPR0521_DRV_NAME;
+	indio_dev->channels = rpr0521_channels;
+	indio_dev->num_channels = ARRAY_SIZE(rpr0521_channels);
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = rpr0521_init(data);
+	if (ret < 0) {
+		dev_err(&client->dev, "rpr0521 chip init failed\n");
+		return ret;
+	}
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		return ret;
+
+	ret = pm_runtime_set_active(&client->dev);
+	if (ret < 0)
+		goto err_iio_unregister;
+
+	pm_runtime_enable(&client->dev);
+	pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS);
+	pm_runtime_use_autosuspend(&client->dev);
+
+	return 0;
+
+err_iio_unregister:
+	iio_device_unregister(indio_dev);
+	return ret;
+}
+
+static int rpr0521_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_put_noidle(&client->dev);
+
+	iio_device_unregister(indio_dev);
+	rpr0521_poweroff(iio_priv(indio_dev));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int rpr0521_runtime_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct rpr0521_data *data = iio_priv(indio_dev);
+	int ret;
+
+	/* disable channels and sets {als,pxs}_dev_en to false */
+	mutex_lock(&data->lock);
+	ret = rpr0521_poweroff(data);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int rpr0521_runtime_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct rpr0521_data *data = iio_priv(indio_dev);
+	int ret;
+
+	if (data->als_ps_need_en) {
+		ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
+		if (ret < 0)
+			return ret;
+		data->als_ps_need_en = false;
+	}
+
+	if (data->pxs_ps_need_en) {
+		ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
+		if (ret < 0)
+			return ret;
+		data->pxs_ps_need_en = false;
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops rpr0521_pm_ops = {
+	SET_RUNTIME_PM_OPS(rpr0521_runtime_suspend,
+			   rpr0521_runtime_resume, NULL)
+};
+
+static const struct acpi_device_id rpr0521_acpi_match[] = {
+	{"RPR0521", 0},
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, rpr0521_acpi_match);
+
+static const struct i2c_device_id rpr0521_id[] = {
+	{"rpr0521", 0},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, rpr0521_id);
+
+static struct i2c_driver rpr0521_driver = {
+	.driver = {
+		.name	= RPR0521_DRV_NAME,
+		.pm	= &rpr0521_pm_ops,
+		.acpi_match_table = ACPI_PTR(rpr0521_acpi_match),
+	},
+	.probe		= rpr0521_probe,
+	.remove		= rpr0521_remove,
+	.id_table	= rpr0521_id,
+};
+
+module_i2c_driver(rpr0521_driver);
+
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
+MODULE_DESCRIPTION("RPR0521 ROHM Ambient Light and Proximity Sensor driver");
+MODULE_LICENSE("GPL v2");

+ 1 - 0
drivers/iio/light/stk3310.c

@@ -676,6 +676,7 @@ static const struct i2c_device_id stk3310_i2c_id[] = {
 	{"STK3311", 0},
 	{"STK3311", 0},
 	{}
 	{}
 };
 };
+MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id);
 
 
 static const struct acpi_device_id stk3310_acpi_id[] = {
 static const struct acpi_device_id stk3310_acpi_id[] = {
 	{"STK3310", 0},
 	{"STK3310", 0},

+ 0 - 1
drivers/iio/light/tcs3414.c

@@ -392,7 +392,6 @@ static struct i2c_driver tcs3414_driver = {
 	.driver = {
 	.driver = {
 		.name	= TCS3414_DRV_NAME,
 		.name	= TCS3414_DRV_NAME,
 		.pm	= &tcs3414_pm_ops,
 		.pm	= &tcs3414_pm_ops,
-		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= tcs3414_probe,
 	.probe		= tcs3414_probe,
 	.remove		= tcs3414_remove,
 	.remove		= tcs3414_remove,

+ 0 - 1
drivers/iio/light/tcs3472.c

@@ -366,7 +366,6 @@ static struct i2c_driver tcs3472_driver = {
 	.driver = {
 	.driver = {
 		.name	= TCS3472_DRV_NAME,
 		.name	= TCS3472_DRV_NAME,
 		.pm	= &tcs3472_pm_ops,
 		.pm	= &tcs3472_pm_ops,
-		.owner	= THIS_MODULE,
 	},
 	},
 	.probe		= tcs3472_probe,
 	.probe		= tcs3472_probe,
 	.remove		= tcs3472_remove,
 	.remove		= tcs3472_remove,

+ 0 - 1
drivers/iio/light/tsl4531.c

@@ -247,7 +247,6 @@ static struct i2c_driver tsl4531_driver = {
 	.driver = {
 	.driver = {
 		.name   = TSL4531_DRV_NAME,
 		.name   = TSL4531_DRV_NAME,
 		.pm	= TSL4531_PM_OPS,
 		.pm	= TSL4531_PM_OPS,
-		.owner  = THIS_MODULE,
 	},
 	},
 	.probe  = tsl4531_probe,
 	.probe  = tsl4531_probe,
 	.remove = tsl4531_remove,
 	.remove = tsl4531_remove,

+ 0 - 1
drivers/iio/light/vcnl4000.c

@@ -185,7 +185,6 @@ static int vcnl4000_probe(struct i2c_client *client,
 static struct i2c_driver vcnl4000_driver = {
 static struct i2c_driver vcnl4000_driver = {
 	.driver = {
 	.driver = {
 		.name   = VCNL4000_DRV_NAME,
 		.name   = VCNL4000_DRV_NAME,
-		.owner  = THIS_MODULE,
 	},
 	},
 	.probe  = vcnl4000_probe,
 	.probe  = vcnl4000_probe,
 	.id_table = vcnl4000_id,
 	.id_table = vcnl4000_id,

+ 52 - 43
drivers/iio/magnetometer/bmc150_magn.c

@@ -85,6 +85,7 @@
 #define BMC150_MAGN_REG_HIGH_THRESH		0x50
 #define BMC150_MAGN_REG_HIGH_THRESH		0x50
 #define BMC150_MAGN_REG_REP_XY			0x51
 #define BMC150_MAGN_REG_REP_XY			0x51
 #define BMC150_MAGN_REG_REP_Z			0x52
 #define BMC150_MAGN_REG_REP_Z			0x52
+#define BMC150_MAGN_REG_REP_DATAMASK		GENMASK(7, 0)
 
 
 #define BMC150_MAGN_REG_TRIM_START		0x5D
 #define BMC150_MAGN_REG_TRIM_START		0x5D
 #define BMC150_MAGN_REG_TRIM_END		0x71
 #define BMC150_MAGN_REG_TRIM_END		0x71
@@ -559,7 +560,7 @@ static int bmc150_magn_write_raw(struct iio_dev *indio_dev,
 			}
 			}
 			ret = regmap_update_bits(data->regmap,
 			ret = regmap_update_bits(data->regmap,
 						 BMC150_MAGN_REG_REP_XY,
 						 BMC150_MAGN_REG_REP_XY,
-						 0xFF,
+						 BMC150_MAGN_REG_REP_DATAMASK,
 						 BMC150_MAGN_REPXY_TO_REGVAL
 						 BMC150_MAGN_REPXY_TO_REGVAL
 						 (val));
 						 (val));
 			mutex_unlock(&data->mutex);
 			mutex_unlock(&data->mutex);
@@ -575,7 +576,7 @@ static int bmc150_magn_write_raw(struct iio_dev *indio_dev,
 			}
 			}
 			ret = regmap_update_bits(data->regmap,
 			ret = regmap_update_bits(data->regmap,
 						 BMC150_MAGN_REG_REP_Z,
 						 BMC150_MAGN_REG_REP_Z,
-						 0xFF,
+						 BMC150_MAGN_REG_REP_DATAMASK,
 						 BMC150_MAGN_REPZ_TO_REGVAL
 						 BMC150_MAGN_REPZ_TO_REGVAL
 						 (val));
 						 (val));
 			mutex_unlock(&data->mutex);
 			mutex_unlock(&data->mutex);
@@ -588,17 +589,6 @@ static int bmc150_magn_write_raw(struct iio_dev *indio_dev,
 	}
 	}
 }
 }
 
 
-static int bmc150_magn_validate_trigger(struct iio_dev *indio_dev,
-					struct iio_trigger *trig)
-{
-	struct bmc150_magn_data *data = iio_priv(indio_dev);
-
-	if (data->dready_trig != trig)
-		return -EINVAL;
-
-	return 0;
-}
-
 static ssize_t bmc150_magn_show_samp_freq_avail(struct device *dev,
 static ssize_t bmc150_magn_show_samp_freq_avail(struct device *dev,
 						struct device_attribute *attr,
 						struct device_attribute *attr,
 						char *buf)
 						char *buf)
@@ -659,11 +649,12 @@ static const struct iio_info bmc150_magn_info = {
 	.attrs = &bmc150_magn_attrs_group,
 	.attrs = &bmc150_magn_attrs_group,
 	.read_raw = bmc150_magn_read_raw,
 	.read_raw = bmc150_magn_read_raw,
 	.write_raw = bmc150_magn_write_raw,
 	.write_raw = bmc150_magn_write_raw,
-	.validate_trigger = bmc150_magn_validate_trigger,
 	.driver_module = THIS_MODULE,
 	.driver_module = THIS_MODULE,
 };
 };
 
 
-static const unsigned long bmc150_magn_scan_masks[] = {0x07, 0};
+static const unsigned long bmc150_magn_scan_masks[] = {
+					BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
+					0};
 
 
 static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p)
 static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p)
 {
 {
@@ -674,7 +665,6 @@ static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p)
 
 
 	mutex_lock(&data->mutex);
 	mutex_lock(&data->mutex);
 	ret = bmc150_magn_read_xyz(data, data->buffer);
 	ret = bmc150_magn_read_xyz(data, data->buffer);
-	mutex_unlock(&data->mutex);
 	if (ret < 0)
 	if (ret < 0)
 		goto err;
 		goto err;
 
 
@@ -682,7 +672,8 @@ static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p)
 					   pf->timestamp);
 					   pf->timestamp);
 
 
 err:
 err:
-	iio_trigger_notify_done(data->dready_trig);
+	mutex_unlock(&data->mutex);
+	iio_trigger_notify_done(indio_dev->trig);
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
@@ -793,29 +784,23 @@ static int bmc150_magn_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	if (state == data->dready_trigger_on)
 	if (state == data->dready_trigger_on)
 		goto err_unlock;
 		goto err_unlock;
 
 
-	ret = bmc150_magn_set_power_state(data, state);
-	if (ret < 0)
-		goto err_unlock;
-
 	ret = regmap_update_bits(data->regmap, BMC150_MAGN_REG_INT_DRDY,
 	ret = regmap_update_bits(data->regmap, BMC150_MAGN_REG_INT_DRDY,
 				 BMC150_MAGN_MASK_DRDY_EN,
 				 BMC150_MAGN_MASK_DRDY_EN,
 				 state << BMC150_MAGN_SHIFT_DRDY_EN);
 				 state << BMC150_MAGN_SHIFT_DRDY_EN);
 	if (ret < 0)
 	if (ret < 0)
-		goto err_poweroff;
+		goto err_unlock;
 
 
 	data->dready_trigger_on = state;
 	data->dready_trigger_on = state;
 
 
 	if (state) {
 	if (state) {
 		ret = bmc150_magn_reset_intr(data);
 		ret = bmc150_magn_reset_intr(data);
 		if (ret < 0)
 		if (ret < 0)
-			goto err_poweroff;
+			goto err_unlock;
 	}
 	}
 	mutex_unlock(&data->mutex);
 	mutex_unlock(&data->mutex);
 
 
 	return 0;
 	return 0;
 
 
-err_poweroff:
-	bmc150_magn_set_power_state(data, false);
 err_unlock:
 err_unlock:
 	mutex_unlock(&data->mutex);
 	mutex_unlock(&data->mutex);
 	return ret;
 	return ret;
@@ -827,6 +812,27 @@ static const struct iio_trigger_ops bmc150_magn_trigger_ops = {
 	.owner = THIS_MODULE,
 	.owner = THIS_MODULE,
 };
 };
 
 
+static int bmc150_magn_buffer_preenable(struct iio_dev *indio_dev)
+{
+	struct bmc150_magn_data *data = iio_priv(indio_dev);
+
+	return bmc150_magn_set_power_state(data, true);
+}
+
+static int bmc150_magn_buffer_postdisable(struct iio_dev *indio_dev)
+{
+	struct bmc150_magn_data *data = iio_priv(indio_dev);
+
+	return bmc150_magn_set_power_state(data, false);
+}
+
+static const struct iio_buffer_setup_ops bmc150_magn_buffer_setup_ops = {
+	.preenable = bmc150_magn_buffer_preenable,
+	.postenable = iio_triggered_buffer_postenable,
+	.predisable = iio_triggered_buffer_predisable,
+	.postdisable = bmc150_magn_buffer_postdisable,
+};
+
 static int bmc150_magn_gpio_probe(struct i2c_client *client)
 static int bmc150_magn_gpio_probe(struct i2c_client *client)
 {
 {
 	struct device *dev;
 	struct device *dev;
@@ -932,16 +938,6 @@ static int bmc150_magn_probe(struct i2c_client *client,
 			goto err_poweroff;
 			goto err_poweroff;
 		}
 		}
 
 
-		ret = iio_triggered_buffer_setup(indio_dev,
-						 &iio_pollfunc_store_time,
-						 bmc150_magn_trigger_handler,
-						 NULL);
-		if (ret < 0) {
-			dev_err(&client->dev,
-				"iio triggered buffer setup failed\n");
-			goto err_trigger_unregister;
-		}
-
 		ret = request_threaded_irq(client->irq,
 		ret = request_threaded_irq(client->irq,
 					   iio_trigger_generic_data_rdy_poll,
 					   iio_trigger_generic_data_rdy_poll,
 					   NULL,
 					   NULL,
@@ -951,14 +947,24 @@ static int bmc150_magn_probe(struct i2c_client *client,
 		if (ret < 0) {
 		if (ret < 0) {
 			dev_err(&client->dev, "request irq %d failed\n",
 			dev_err(&client->dev, "request irq %d failed\n",
 				client->irq);
 				client->irq);
-			goto err_buffer_cleanup;
+			goto err_trigger_unregister;
 		}
 		}
 	}
 	}
 
 
+	ret = iio_triggered_buffer_setup(indio_dev,
+					 iio_pollfunc_store_time,
+					 bmc150_magn_trigger_handler,
+					 &bmc150_magn_buffer_setup_ops);
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"iio triggered buffer setup failed\n");
+		goto err_free_irq;
+	}
+
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&client->dev, "unable to register iio device\n");
 		dev_err(&client->dev, "unable to register iio device\n");
-		goto err_free_irq;
+		goto err_buffer_cleanup;
 	}
 	}
 
 
 	ret = pm_runtime_set_active(&client->dev);
 	ret = pm_runtime_set_active(&client->dev);
@@ -976,12 +982,11 @@ static int bmc150_magn_probe(struct i2c_client *client,
 
 
 err_iio_unregister:
 err_iio_unregister:
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
+err_buffer_cleanup:
+	iio_triggered_buffer_cleanup(indio_dev);
 err_free_irq:
 err_free_irq:
 	if (client->irq > 0)
 	if (client->irq > 0)
 		free_irq(client->irq, data->dready_trig);
 		free_irq(client->irq, data->dready_trig);
-err_buffer_cleanup:
-	if (data->dready_trig)
-		iio_triggered_buffer_cleanup(indio_dev);
 err_trigger_unregister:
 err_trigger_unregister:
 	if (data->dready_trig)
 	if (data->dready_trig)
 		iio_trigger_unregister(data->dready_trig);
 		iio_trigger_unregister(data->dready_trig);
@@ -1000,14 +1005,13 @@ static int bmc150_magn_remove(struct i2c_client *client)
 	pm_runtime_put_noidle(&client->dev);
 	pm_runtime_put_noidle(&client->dev);
 
 
 	iio_device_unregister(indio_dev);
 	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
 
 
 	if (client->irq > 0)
 	if (client->irq > 0)
 		free_irq(data->client->irq, data->dready_trig);
 		free_irq(data->client->irq, data->dready_trig);
 
 
-	if (data->dready_trig) {
-		iio_triggered_buffer_cleanup(indio_dev);
+	if (data->dready_trig)
 		iio_trigger_unregister(data->dready_trig);
 		iio_trigger_unregister(data->dready_trig);
-	}
 
 
 	mutex_lock(&data->mutex);
 	mutex_lock(&data->mutex);
 	bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND, true);
 	bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND, true);
@@ -1034,6 +1038,9 @@ static int bmc150_magn_runtime_suspend(struct device *dev)
 	return 0;
 	return 0;
 }
 }
 
 
+/*
+ * Should be called with data->mutex held.
+ */
 static int bmc150_magn_runtime_resume(struct device *dev)
 static int bmc150_magn_runtime_resume(struct device *dev)
 {
 {
 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
@@ -1082,12 +1089,14 @@ static const struct dev_pm_ops bmc150_magn_pm_ops = {
 
 
 static const struct acpi_device_id bmc150_magn_acpi_match[] = {
 static const struct acpi_device_id bmc150_magn_acpi_match[] = {
 	{"BMC150B", 0},
 	{"BMC150B", 0},
+	{"BMC156B", 0},
 	{},
 	{},
 };
 };
 MODULE_DEVICE_TABLE(acpi, bmc150_magn_acpi_match);
 MODULE_DEVICE_TABLE(acpi, bmc150_magn_acpi_match);
 
 
 static const struct i2c_device_id bmc150_magn_id[] = {
 static const struct i2c_device_id bmc150_magn_id[] = {
 	{"bmc150_magn", 0},
 	{"bmc150_magn", 0},
+	{"bmc156_magn", 0},
 	{},
 	{},
 };
 };
 MODULE_DEVICE_TABLE(i2c, bmc150_magn_id);
 MODULE_DEVICE_TABLE(i2c, bmc150_magn_id);

+ 20 - 13
drivers/iio/magnetometer/mmc35240.c

@@ -316,31 +316,31 @@ static int mmc35240_read_measurement(struct mmc35240_data *data, __le16 buf[3])
 static int mmc35240_raw_to_mgauss(struct mmc35240_data *data, int index,
 static int mmc35240_raw_to_mgauss(struct mmc35240_data *data, int index,
 				  __le16 buf[], int *val)
 				  __le16 buf[], int *val)
 {
 {
-	int raw_x, raw_y, raw_z;
-	int sens_x, sens_y, sens_z;
+	int raw[3];
+	int sens[3];
 	int nfo;
 	int nfo;
 
 
-	raw_x = le16_to_cpu(buf[AXIS_X]);
-	raw_y = le16_to_cpu(buf[AXIS_Y]);
-	raw_z = le16_to_cpu(buf[AXIS_Z]);
+	raw[AXIS_X] = le16_to_cpu(buf[AXIS_X]);
+	raw[AXIS_Y] = le16_to_cpu(buf[AXIS_Y]);
+	raw[AXIS_Z] = le16_to_cpu(buf[AXIS_Z]);
 
 
-	sens_x = mmc35240_props_table[data->res].sens[AXIS_X];
-	sens_y = mmc35240_props_table[data->res].sens[AXIS_Y];
-	sens_z = mmc35240_props_table[data->res].sens[AXIS_Z];
+	sens[AXIS_X] = mmc35240_props_table[data->res].sens[AXIS_X];
+	sens[AXIS_Y] = mmc35240_props_table[data->res].sens[AXIS_Y];
+	sens[AXIS_Z] = mmc35240_props_table[data->res].sens[AXIS_Z];
 
 
 	nfo = mmc35240_props_table[data->res].nfo;
 	nfo = mmc35240_props_table[data->res].nfo;
 
 
 	switch (index) {
 	switch (index) {
 	case AXIS_X:
 	case AXIS_X:
-		*val = (raw_x - nfo) * 1000 / sens_x;
+		*val = (raw[AXIS_X] - nfo) * 1000 / sens[AXIS_X];
 		break;
 		break;
 	case AXIS_Y:
 	case AXIS_Y:
-		*val = (raw_y - nfo) * 1000 / sens_y -
-			(raw_z - nfo)  * 1000 / sens_z;
+		*val = (raw[AXIS_Y] - nfo) * 1000 / sens[AXIS_Y] -
+			(raw[AXIS_Z] - nfo)  * 1000 / sens[AXIS_Z];
 		break;
 		break;
 	case AXIS_Z:
 	case AXIS_Z:
-		*val = (raw_y - nfo) * 1000 / sens_y +
-			(raw_z - nfo) * 1000 / sens_z;
+		*val = (raw[AXIS_Y] - nfo) * 1000 / sens[AXIS_Y] +
+			(raw[AXIS_Z] - nfo) * 1000 / sens[AXIS_Z];
 		break;
 		break;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
@@ -559,6 +559,12 @@ static const struct dev_pm_ops mmc35240_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(mmc35240_suspend, mmc35240_resume)
 	SET_SYSTEM_SLEEP_PM_OPS(mmc35240_suspend, mmc35240_resume)
 };
 };
 
 
+static const struct of_device_id mmc35240_of_match[] = {
+	{ .compatible = "memsic,mmc35240", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mmc35240_of_match);
+
 static const struct acpi_device_id mmc35240_acpi_match[] = {
 static const struct acpi_device_id mmc35240_acpi_match[] = {
 	{"MMC35240", 0},
 	{"MMC35240", 0},
 	{ },
 	{ },
@@ -574,6 +580,7 @@ MODULE_DEVICE_TABLE(i2c, mmc35240_id);
 static struct i2c_driver mmc35240_driver = {
 static struct i2c_driver mmc35240_driver = {
 	.driver = {
 	.driver = {
 		.name = MMC35240_DRV_NAME,
 		.name = MMC35240_DRV_NAME,
+		.of_match_table = mmc35240_of_match,
 		.pm = &mmc35240_pm_ops,
 		.pm = &mmc35240_pm_ops,
 		.acpi_match_table = ACPI_PTR(mmc35240_acpi_match),
 		.acpi_match_table = ACPI_PTR(mmc35240_acpi_match),
 	},
 	},

+ 3 - 0
drivers/iio/magnetometer/st_magn.h

@@ -18,6 +18,7 @@
 #define LSM303DLHC_MAGN_DEV_NAME	"lsm303dlhc_magn"
 #define LSM303DLHC_MAGN_DEV_NAME	"lsm303dlhc_magn"
 #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"
+#define LSM303AGR_MAGN_DEV_NAME		"lsm303agr_magn"
 
 
 int st_magn_common_probe(struct iio_dev *indio_dev);
 int st_magn_common_probe(struct iio_dev *indio_dev);
 void st_magn_common_remove(struct iio_dev *indio_dev);
 void st_magn_common_remove(struct iio_dev *indio_dev);
@@ -25,6 +26,8 @@ void st_magn_common_remove(struct iio_dev *indio_dev);
 #ifdef CONFIG_IIO_BUFFER
 #ifdef CONFIG_IIO_BUFFER
 int st_magn_allocate_ring(struct iio_dev *indio_dev);
 int st_magn_allocate_ring(struct iio_dev *indio_dev);
 void st_magn_deallocate_ring(struct iio_dev *indio_dev);
 void st_magn_deallocate_ring(struct iio_dev *indio_dev);
+int st_magn_trig_set_state(struct iio_trigger *trig, bool state);
+#define ST_MAGN_TRIGGER_SET_STATE (&st_magn_trig_set_state)
 #else /* CONFIG_IIO_BUFFER */
 #else /* CONFIG_IIO_BUFFER */
 static inline int st_magn_probe_trigger(struct iio_dev *indio_dev, int irq)
 static inline int st_magn_probe_trigger(struct iio_dev *indio_dev, int irq)
 {
 {

+ 7 - 0
drivers/iio/magnetometer/st_magn_buffer.c

@@ -23,6 +23,13 @@
 #include <linux/iio/common/st_sensors.h>
 #include <linux/iio/common/st_sensors.h>
 #include "st_magn.h"
 #include "st_magn.h"
 
 
+int st_magn_trig_set_state(struct iio_trigger *trig, bool state)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+
+	return st_sensors_set_dataready_irq(indio_dev, state);
+}
+
 static int st_magn_buffer_preenable(struct iio_dev *indio_dev)
 static int st_magn_buffer_preenable(struct iio_dev *indio_dev)
 {
 {
 	return st_sensors_set_enable(indio_dev, true);
 	return st_sensors_set_enable(indio_dev, true);

+ 97 - 1
drivers/iio/magnetometer/st_magn_core.c

@@ -43,6 +43,7 @@
 #define ST_MAGN_FS_AVL_8000MG			8000
 #define ST_MAGN_FS_AVL_8000MG			8000
 #define ST_MAGN_FS_AVL_8100MG			8100
 #define ST_MAGN_FS_AVL_8100MG			8100
 #define ST_MAGN_FS_AVL_12000MG			12000
 #define ST_MAGN_FS_AVL_12000MG			12000
+#define ST_MAGN_FS_AVL_15000MG			15000
 #define ST_MAGN_FS_AVL_16000MG			16000
 #define ST_MAGN_FS_AVL_16000MG			16000
 
 
 /* CUSTOM VALUES FOR SENSOR 0 */
 /* CUSTOM VALUES FOR SENSOR 0 */
@@ -157,6 +158,29 @@
 #define ST_MAGN_2_OUT_Y_L_ADDR			0x2a
 #define ST_MAGN_2_OUT_Y_L_ADDR			0x2a
 #define ST_MAGN_2_OUT_Z_L_ADDR			0x2c
 #define ST_MAGN_2_OUT_Z_L_ADDR			0x2c
 
 
+/* CUSTOM VALUES FOR SENSOR 3 */
+#define ST_MAGN_3_WAI_ADDR			0x4f
+#define ST_MAGN_3_WAI_EXP			0x40
+#define ST_MAGN_3_ODR_ADDR			0x60
+#define ST_MAGN_3_ODR_MASK			0x0c
+#define ST_MAGN_3_ODR_AVL_10HZ_VAL		0x00
+#define ST_MAGN_3_ODR_AVL_20HZ_VAL		0x01
+#define ST_MAGN_3_ODR_AVL_50HZ_VAL		0x02
+#define ST_MAGN_3_ODR_AVL_100HZ_VAL		0x03
+#define ST_MAGN_3_PW_ADDR			0x60
+#define ST_MAGN_3_PW_MASK			0x03
+#define ST_MAGN_3_PW_ON				0x00
+#define ST_MAGN_3_PW_OFF			0x03
+#define ST_MAGN_3_BDU_ADDR			0x62
+#define ST_MAGN_3_BDU_MASK			0x10
+#define ST_MAGN_3_DRDY_IRQ_ADDR			0x62
+#define ST_MAGN_3_DRDY_INT_MASK			0x01
+#define ST_MAGN_3_FS_AVL_15000_GAIN		1500
+#define ST_MAGN_3_MULTIREAD_BIT			false
+#define ST_MAGN_3_OUT_X_L_ADDR			0x68
+#define ST_MAGN_3_OUT_Y_L_ADDR			0x6a
+#define ST_MAGN_3_OUT_Z_L_ADDR			0x6c
+
 static const struct iio_chan_spec st_magn_16bit_channels[] = {
 static const struct iio_chan_spec st_magn_16bit_channels[] = {
 	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
 	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
@@ -189,9 +213,26 @@ static const struct iio_chan_spec st_magn_2_16bit_channels[] = {
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 	IIO_CHAN_SOFT_TIMESTAMP(3)
 };
 };
 
 
+static const struct iio_chan_spec st_magn_3_16bit_channels[] = {
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
+			ST_MAGN_3_OUT_X_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
+			ST_MAGN_3_OUT_Y_L_ADDR),
+	ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
+			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
+			ST_MAGN_3_OUT_Z_L_ADDR),
+	IIO_CHAN_SOFT_TIMESTAMP(3)
+};
+
 static const struct st_sensor_settings st_magn_sensors_settings[] = {
 static const struct st_sensor_settings st_magn_sensors_settings[] = {
 	{
 	{
 		.wai = 0, /* This sensor has no valid WhoAmI report 0 */
 		.wai = 0, /* This sensor has no valid WhoAmI report 0 */
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LSM303DLH_MAGN_DEV_NAME,
 			[0] = LSM303DLH_MAGN_DEV_NAME,
 		},
 		},
@@ -268,6 +309,7 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_MAGN_1_WAI_EXP,
 		.wai = ST_MAGN_1_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LSM303DLHC_MAGN_DEV_NAME,
 			[0] = LSM303DLHC_MAGN_DEV_NAME,
 			[1] = LSM303DLM_MAGN_DEV_NAME,
 			[1] = LSM303DLM_MAGN_DEV_NAME,
@@ -346,6 +388,7 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_MAGN_2_WAI_EXP,
 		.wai = ST_MAGN_2_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LIS3MDL_MAGN_DEV_NAME,
 			[0] = LIS3MDL_MAGN_DEV_NAME,
 		},
 		},
@@ -399,6 +442,48 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = {
 		.multi_read_bit = ST_MAGN_2_MULTIREAD_BIT,
 		.multi_read_bit = ST_MAGN_2_MULTIREAD_BIT,
 		.bootime = 2,
 		.bootime = 2,
 	},
 	},
+	{
+		.wai = ST_MAGN_3_WAI_EXP,
+		.wai_addr = ST_MAGN_3_WAI_ADDR,
+		.sensors_supported = {
+			[0] = LSM303AGR_MAGN_DEV_NAME,
+		},
+		.ch = (struct iio_chan_spec *)st_magn_3_16bit_channels,
+		.odr = {
+			.addr = ST_MAGN_3_ODR_ADDR,
+			.mask = ST_MAGN_3_ODR_MASK,
+			.odr_avl = {
+				{ 10, ST_MAGN_3_ODR_AVL_10HZ_VAL, },
+				{ 20, ST_MAGN_3_ODR_AVL_20HZ_VAL, },
+				{ 50, ST_MAGN_3_ODR_AVL_50HZ_VAL, },
+				{ 100, ST_MAGN_3_ODR_AVL_100HZ_VAL, },
+			},
+		},
+		.pw = {
+			.addr = ST_MAGN_3_PW_ADDR,
+			.mask = ST_MAGN_3_PW_MASK,
+			.value_on = ST_MAGN_3_PW_ON,
+			.value_off = ST_MAGN_3_PW_OFF,
+		},
+		.fs = {
+			.fs_avl = {
+				[0] = {
+					.num = ST_MAGN_FS_AVL_15000MG,
+					.gain = ST_MAGN_3_FS_AVL_15000_GAIN,
+				},
+			},
+		},
+		.bdu = {
+			.addr = ST_MAGN_3_BDU_ADDR,
+			.mask = ST_MAGN_3_BDU_MASK,
+		},
+		.drdy_irq = {
+			.addr = ST_MAGN_3_DRDY_IRQ_ADDR,
+			.mask_int1 = ST_MAGN_3_DRDY_INT_MASK,
+		},
+		.multi_read_bit = ST_MAGN_3_MULTIREAD_BIT,
+		.bootime = 2,
+	},
 };
 };
 
 
 static int st_magn_read_raw(struct iio_dev *indio_dev,
 static int st_magn_read_raw(struct iio_dev *indio_dev,
@@ -477,6 +562,16 @@ static const struct iio_info magn_info = {
 	.write_raw = &st_magn_write_raw,
 	.write_raw = &st_magn_write_raw,
 };
 };
 
 
+#ifdef CONFIG_IIO_TRIGGER
+static const struct iio_trigger_ops st_magn_trigger_ops = {
+	.owner = THIS_MODULE,
+	.set_trigger_state = ST_MAGN_TRIGGER_SET_STATE,
+};
+#define ST_MAGN_TRIGGER_OPS (&st_magn_trigger_ops)
+#else
+#define ST_MAGN_TRIGGER_OPS NULL
+#endif
+
 int st_magn_common_probe(struct iio_dev *indio_dev)
 int st_magn_common_probe(struct iio_dev *indio_dev)
 {
 {
 	struct st_sensor_data *mdata = iio_priv(indio_dev);
 	struct st_sensor_data *mdata = iio_priv(indio_dev);
@@ -513,7 +608,8 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
 		return err;
 		return err;
 
 
 	if (irq > 0) {
 	if (irq > 0) {
-		err = st_sensors_allocate_trigger(indio_dev, NULL);
+		err = st_sensors_allocate_trigger(indio_dev,
+						ST_MAGN_TRIGGER_OPS);
 		if (err < 0)
 		if (err < 0)
 			goto st_magn_probe_trigger_error;
 			goto st_magn_probe_trigger_error;
 	}
 	}

+ 5 - 1
drivers/iio/magnetometer/st_magn_i2c.c

@@ -36,6 +36,10 @@ static const struct of_device_id st_magn_of_match[] = {
 		.compatible = "st,lis3mdl-magn",
 		.compatible = "st,lis3mdl-magn",
 		.data = LIS3MDL_MAGN_DEV_NAME,
 		.data = LIS3MDL_MAGN_DEV_NAME,
 	},
 	},
+	{
+		.compatible = "st,lsm303agr-magn",
+		.data = LSM303AGR_MAGN_DEV_NAME,
+	},
 	{},
 	{},
 };
 };
 MODULE_DEVICE_TABLE(of, st_magn_of_match);
 MODULE_DEVICE_TABLE(of, st_magn_of_match);
@@ -79,13 +83,13 @@ static const struct i2c_device_id st_magn_id_table[] = {
 	{ LSM303DLHC_MAGN_DEV_NAME },
 	{ LSM303DLHC_MAGN_DEV_NAME },
 	{ LSM303DLM_MAGN_DEV_NAME },
 	{ LSM303DLM_MAGN_DEV_NAME },
 	{ LIS3MDL_MAGN_DEV_NAME },
 	{ LIS3MDL_MAGN_DEV_NAME },
+	{ LSM303AGR_MAGN_DEV_NAME },
 	{},
 	{},
 };
 };
 MODULE_DEVICE_TABLE(i2c, st_magn_id_table);
 MODULE_DEVICE_TABLE(i2c, st_magn_id_table);
 
 
 static struct i2c_driver st_magn_driver = {
 static struct i2c_driver st_magn_driver = {
 	.driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name = "st-magn-i2c",
 		.name = "st-magn-i2c",
 		.of_match_table = of_match_ptr(st_magn_of_match),
 		.of_match_table = of_match_ptr(st_magn_of_match),
 	},
 	},

+ 1 - 0
drivers/iio/magnetometer/st_magn_spi.c

@@ -51,6 +51,7 @@ static const struct spi_device_id st_magn_id_table[] = {
 	{ LSM303DLHC_MAGN_DEV_NAME },
 	{ LSM303DLHC_MAGN_DEV_NAME },
 	{ LSM303DLM_MAGN_DEV_NAME },
 	{ LSM303DLM_MAGN_DEV_NAME },
 	{ LIS3MDL_MAGN_DEV_NAME },
 	{ LIS3MDL_MAGN_DEV_NAME },
+	{ LSM303AGR_MAGN_DEV_NAME },
 	{},
 	{},
 };
 };
 MODULE_DEVICE_TABLE(spi, st_magn_id_table);
 MODULE_DEVICE_TABLE(spi, st_magn_id_table);

+ 3 - 3
drivers/iio/pressure/Kconfig

@@ -53,10 +53,10 @@ config MPL3115
           will be called mpl3115.
           will be called mpl3115.
 
 
 config MS5611
 config MS5611
-	tristate "Measurement Specialities MS5611 pressure sensor driver"
+	tristate "Measurement Specialties MS5611 pressure sensor driver"
 	help
 	help
-	  Say Y here to build support for the Measurement Specialities
-	  MS5611 pressure and temperature sensor.
+	  Say Y here to build support for the Measurement Specialties
+	  MS5611, MS5607 pressure and temperature sensors.
 
 
 	  To compile this driver as a module, choose M here: the module will
 	  To compile this driver as a module, choose M here: the module will
 	  be called ms5611_core.
 	  be called ms5611_core.

+ 14 - 2
drivers/iio/pressure/ms5611.h

@@ -27,6 +27,18 @@
 
 
 #define MS5611_PROM_WORDS_NB		8
 #define MS5611_PROM_WORDS_NB		8
 
 
+enum {
+	MS5611,
+	MS5607,
+};
+
+struct ms5611_chip_info {
+	u16 prom[MS5611_PROM_WORDS_NB];
+
+	int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info,
+					    s32 *temp, s32 *pressure);
+};
+
 struct ms5611_state {
 struct ms5611_state {
 	void *client;
 	void *client;
 	struct mutex lock;
 	struct mutex lock;
@@ -36,9 +48,9 @@ struct ms5611_state {
 	int (*read_adc_temp_and_pressure)(struct device *dev,
 	int (*read_adc_temp_and_pressure)(struct device *dev,
 					  s32 *temp, s32 *pressure);
 					  s32 *temp, s32 *pressure);
 
 
-	u16 prom[MS5611_PROM_WORDS_NB];
+	struct ms5611_chip_info *chip_info;
 };
 };
 
 
-int ms5611_probe(struct iio_dev *indio_dev, struct device *dev);
+int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, int type);
 
 
 #endif /* _MS5611_H */
 #endif /* _MS5611_H */

+ 68 - 14
drivers/iio/pressure/ms5611_core.c

@@ -9,6 +9,7 @@
  *
  *
  * Data sheet:
  * Data sheet:
  *  http://www.meas-spec.com/downloads/MS5611-01BA03.pdf
  *  http://www.meas-spec.com/downloads/MS5611-01BA03.pdf
+ *  http://www.meas-spec.com/downloads/MS5607-02BA03.pdf
  *
  *
  */
  */
 
 
@@ -50,7 +51,8 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
 	struct ms5611_state *st = iio_priv(indio_dev);
 	struct ms5611_state *st = iio_priv(indio_dev);
 
 
 	for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
 	for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
-		ret = st->read_prom_word(&indio_dev->dev, i, &st->prom[i]);
+		ret = st->read_prom_word(&indio_dev->dev,
+					 i, &st->chip_info->prom[i]);
 		if (ret < 0) {
 		if (ret < 0) {
 			dev_err(&indio_dev->dev,
 			dev_err(&indio_dev->dev,
 				"failed to read prom at %d\n", i);
 				"failed to read prom at %d\n", i);
@@ -58,7 +60,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
 		}
 		}
 	}
 	}
 
 
-	if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) {
+	if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) {
 		dev_err(&indio_dev->dev, "PROM integrity check failed\n");
 		dev_err(&indio_dev->dev, "PROM integrity check failed\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
@@ -70,22 +72,30 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
 					 s32 *temp, s32 *pressure)
 					 s32 *temp, s32 *pressure)
 {
 {
 	int ret;
 	int ret;
-	s32 t, p;
-	s64 off, sens, dt;
 	struct ms5611_state *st = iio_priv(indio_dev);
 	struct ms5611_state *st = iio_priv(indio_dev);
 
 
-	ret = st->read_adc_temp_and_pressure(&indio_dev->dev, &t, &p);
+	ret = st->read_adc_temp_and_pressure(&indio_dev->dev, temp, pressure);
 	if (ret < 0) {
 	if (ret < 0) {
 		dev_err(&indio_dev->dev,
 		dev_err(&indio_dev->dev,
 			"failed to read temperature and pressure\n");
 			"failed to read temperature and pressure\n");
 		return ret;
 		return ret;
 	}
 	}
 
 
-	dt = t - (st->prom[5] << 8);
-	off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7);
-	sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8);
+	return st->chip_info->temp_and_pressure_compensate(st->chip_info,
+							   temp, pressure);
+}
+
+static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
+					       s32 *temp, s32 *pressure)
+{
+	s32 t = *temp, p = *pressure;
+	s64 off, sens, dt;
 
 
-	t = 2000 + ((st->prom[6] * dt) >> 23);
+	dt = t - (chip_info->prom[5] << 8);
+	off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7);
+	sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8);
+
+	t = 2000 + ((chip_info->prom[6] * dt) >> 23);
 	if (t < 2000) {
 	if (t < 2000) {
 		s64 off2, sens2, t2;
 		s64 off2, sens2, t2;
 
 
@@ -111,6 +121,42 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
 	return 0;
 	return 0;
 }
 }
 
 
+static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
+					       s32 *temp, s32 *pressure)
+{
+	s32 t = *temp, p = *pressure;
+	s64 off, sens, dt;
+
+	dt = t - (chip_info->prom[5] << 8);
+	off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6);
+	sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7);
+
+	t = 2000 + ((chip_info->prom[6] * dt) >> 23);
+	if (t < 2000) {
+		s64 off2, sens2, t2;
+
+		t2 = (dt * dt) >> 31;
+		off2 = (61 * (t - 2000) * (t - 2000)) >> 4;
+		sens2 = off2 << 1;
+
+		if (t < -1500) {
+			s64 tmp = (t + 1500) * (t + 1500);
+
+			off2 += 15 * tmp;
+			sens2 += (8 * tmp);
+		}
+
+		t -= t2;
+		off -= off2;
+		sens -= sens2;
+	}
+
+	*temp = t;
+	*pressure = (((p * sens) >> 21) - off) >> 15;
+
+	return 0;
+}
+
 static int ms5611_reset(struct iio_dev *indio_dev)
 static int ms5611_reset(struct iio_dev *indio_dev)
 {
 {
 	int ret;
 	int ret;
@@ -160,16 +206,23 @@ static int ms5611_read_raw(struct iio_dev *indio_dev,
 	return -EINVAL;
 	return -EINVAL;
 }
 }
 
 
+static struct ms5611_chip_info chip_info_tbl[] = {
+	[MS5611] = {
+		.temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate,
+	},
+	[MS5607] = {
+		.temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate,
+	}
+};
+
 static const struct iio_chan_spec ms5611_channels[] = {
 static const struct iio_chan_spec ms5611_channels[] = {
 	{
 	{
 		.type = IIO_PRESSURE,
 		.type = IIO_PRESSURE,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
-			BIT(IIO_CHAN_INFO_SCALE)
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 	},
 	},
 	{
 	{
 		.type = IIO_TEMP,
 		.type = IIO_TEMP,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
-			BIT(IIO_CHAN_INFO_SCALE)
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 	}
 	}
 };
 };
 
 
@@ -189,12 +242,13 @@ static int ms5611_init(struct iio_dev *indio_dev)
 	return ms5611_read_prom(indio_dev);
 	return ms5611_read_prom(indio_dev);
 }
 }
 
 
-int ms5611_probe(struct iio_dev *indio_dev, struct device *dev)
+int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, int type)
 {
 {
 	int ret;
 	int ret;
 	struct ms5611_state *st = iio_priv(indio_dev);
 	struct ms5611_state *st = iio_priv(indio_dev);
 
 
 	mutex_init(&st->lock);
 	mutex_init(&st->lock);
+	st->chip_info = &chip_info_tbl[type];
 	indio_dev->dev.parent = dev;
 	indio_dev->dev.parent = dev;
 	indio_dev->name = dev->driver->name;
 	indio_dev->name = dev->driver->name;
 	indio_dev->info = &ms5611_info;
 	indio_dev->info = &ms5611_info;

+ 3 - 3
drivers/iio/pressure/ms5611_i2c.c

@@ -104,11 +104,12 @@ static int ms5611_i2c_probe(struct i2c_client *client,
 	st->read_adc_temp_and_pressure = ms5611_i2c_read_adc_temp_and_pressure;
 	st->read_adc_temp_and_pressure = ms5611_i2c_read_adc_temp_and_pressure;
 	st->client = client;
 	st->client = client;
 
 
-	return ms5611_probe(indio_dev, &client->dev);
+	return ms5611_probe(indio_dev, &client->dev, id->driver_data);
 }
 }
 
 
 static const struct i2c_device_id ms5611_id[] = {
 static const struct i2c_device_id ms5611_id[] = {
-	{ "ms5611", 0 },
+	{ "ms5611", MS5611 },
+	{ "ms5607", MS5607 },
 	{ }
 	{ }
 };
 };
 MODULE_DEVICE_TABLE(i2c, ms5611_id);
 MODULE_DEVICE_TABLE(i2c, ms5611_id);
@@ -116,7 +117,6 @@ MODULE_DEVICE_TABLE(i2c, ms5611_id);
 static struct i2c_driver ms5611_driver = {
 static struct i2c_driver ms5611_driver = {
 	.driver = {
 	.driver = {
 		.name = "ms5611",
 		.name = "ms5611",
-		.owner = THIS_MODULE,
 	},
 	},
 	.id_table = ms5611_id,
 	.id_table = ms5611_id,
 	.probe = ms5611_i2c_probe,
 	.probe = ms5611_i2c_probe,

+ 4 - 2
drivers/iio/pressure/ms5611_spi.c

@@ -103,11 +103,13 @@ static int ms5611_spi_probe(struct spi_device *spi)
 	st->read_adc_temp_and_pressure = ms5611_spi_read_adc_temp_and_pressure;
 	st->read_adc_temp_and_pressure = ms5611_spi_read_adc_temp_and_pressure;
 	st->client = spi;
 	st->client = spi;
 
 
-	return ms5611_probe(indio_dev, &spi->dev);
+	return ms5611_probe(indio_dev, &spi->dev,
+			    spi_get_device_id(spi)->driver_data);
 }
 }
 
 
 static const struct spi_device_id ms5611_id[] = {
 static const struct spi_device_id ms5611_id[] = {
-	{ "ms5611", 0 },
+	{ "ms5611", MS5611 },
+	{ "ms5607", MS5607 },
 	{ }
 	{ }
 };
 };
 MODULE_DEVICE_TABLE(spi, ms5611_id);
 MODULE_DEVICE_TABLE(spi, ms5611_id);

+ 3 - 0
drivers/iio/pressure/st_pressure_core.c

@@ -178,6 +178,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = {
 static const struct st_sensor_settings st_press_sensors_settings[] = {
 static const struct st_sensor_settings st_press_sensors_settings[] = {
 	{
 	{
 		.wai = ST_PRESS_LPS331AP_WAI_EXP,
 		.wai = ST_PRESS_LPS331AP_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LPS331AP_PRESS_DEV_NAME,
 			[0] = LPS331AP_PRESS_DEV_NAME,
 		},
 		},
@@ -225,6 +226,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_PRESS_LPS001WP_WAI_EXP,
 		.wai = ST_PRESS_LPS001WP_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LPS001WP_PRESS_DEV_NAME,
 			[0] = LPS001WP_PRESS_DEV_NAME,
 		},
 		},
@@ -260,6 +262,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
 	},
 	},
 	{
 	{
 		.wai = ST_PRESS_LPS25H_WAI_EXP,
 		.wai = ST_PRESS_LPS25H_WAI_EXP,
+		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 		.sensors_supported = {
 		.sensors_supported = {
 			[0] = LPS25H_PRESS_DEV_NAME,
 			[0] = LPS25H_PRESS_DEV_NAME,
 		},
 		},

+ 0 - 1
drivers/iio/pressure/st_pressure_i2c.c

@@ -79,7 +79,6 @@ MODULE_DEVICE_TABLE(i2c, st_press_id_table);
 
 
 static struct i2c_driver st_press_driver = {
 static struct i2c_driver st_press_driver = {
 	.driver = {
 	.driver = {
-		.owner = THIS_MODULE,
 		.name = "st-press-i2c",
 		.name = "st-press-i2c",
 		.of_match_table = of_match_ptr(st_press_of_match),
 		.of_match_table = of_match_ptr(st_press_of_match),
 	},
 	},

+ 14 - 7
drivers/iio/temperature/mlx90614.c

@@ -65,6 +65,13 @@
 
 
 #define MLX90614_AUTOSLEEP_DELAY 5000 /* default autosleep delay */
 #define MLX90614_AUTOSLEEP_DELAY 5000 /* default autosleep delay */
 
 
+/* Magic constants */
+#define MLX90614_CONST_OFFSET_DEC -13657 /* decimal part of the Kelvin offset */
+#define MLX90614_CONST_OFFSET_REM 500000 /* remainder of offset (273.15*50) */
+#define MLX90614_CONST_SCALE 20 /* Scale in milliKelvin (0.02 * 1000) */
+#define MLX90614_CONST_RAW_EMISSIVITY_MAX 65535 /* max value for emissivity */
+#define MLX90614_CONST_EMISSIVITY_RESOLUTION 15259 /* 1/65535 ~ 0.000015259 */
+
 struct mlx90614_data {
 struct mlx90614_data {
 	struct i2c_client *client;
 	struct i2c_client *client;
 	struct mutex lock; /* for EEPROM access only */
 	struct mutex lock; /* for EEPROM access only */
@@ -204,11 +211,11 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
 		*val = ret;
 		*val = ret;
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_OFFSET:
 	case IIO_CHAN_INFO_OFFSET:
-		*val = -13657;
-		*val2 = 500000;
+		*val = MLX90614_CONST_OFFSET_DEC;
+		*val2 = MLX90614_CONST_OFFSET_REM;
 		return IIO_VAL_INT_PLUS_MICRO;
 		return IIO_VAL_INT_PLUS_MICRO;
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_SCALE:
-		*val = 20;
+		*val = MLX90614_CONST_SCALE;
 		return IIO_VAL_INT;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/65535 / LSB */
 	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/65535 / LSB */
 		mlx90614_power_get(data, false);
 		mlx90614_power_get(data, false);
@@ -221,12 +228,12 @@ static int mlx90614_read_raw(struct iio_dev *indio_dev,
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			return ret;
 
 
-		if (ret == 65535) {
+		if (ret == MLX90614_CONST_RAW_EMISSIVITY_MAX) {
 			*val = 1;
 			*val = 1;
 			*val2 = 0;
 			*val2 = 0;
 		} else {
 		} else {
 			*val = 0;
 			*val = 0;
-			*val2 = ret * 15259; /* 1/65535 ~ 0.000015259 */
+			*val2 = ret * MLX90614_CONST_EMISSIVITY_RESOLUTION;
 		}
 		}
 		return IIO_VAL_INT_PLUS_NANO;
 		return IIO_VAL_INT_PLUS_NANO;
 	default:
 	default:
@@ -245,7 +252,8 @@ static int mlx90614_write_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/65535 / LSB */
 	case IIO_CHAN_INFO_CALIBEMISSIVITY: /* 1/65535 / LSB */
 		if (val < 0 || val2 < 0 || val > 1 || (val == 1 && val2 != 0))
 		if (val < 0 || val2 < 0 || val > 1 || (val == 1 && val2 != 0))
 			return -EINVAL;
 			return -EINVAL;
-		val = val * 65535 + val2 / 15259; /* 1/65535 ~ 0.000015259 */
+		val = val * MLX90614_CONST_RAW_EMISSIVITY_MAX +
+			val2 / MLX90614_CONST_EMISSIVITY_RESOLUTION;
 
 
 		mlx90614_power_get(data, false);
 		mlx90614_power_get(data, false);
 		mutex_lock(&data->lock);
 		mutex_lock(&data->lock);
@@ -551,7 +559,6 @@ static const struct dev_pm_ops mlx90614_pm_ops = {
 static struct i2c_driver mlx90614_driver = {
 static struct i2c_driver mlx90614_driver = {
 	.driver = {
 	.driver = {
 		.name	= "mlx90614",
 		.name	= "mlx90614",
-		.owner	= THIS_MODULE,
 		.pm	= &mlx90614_pm_ops,
 		.pm	= &mlx90614_pm_ops,
 	},
 	},
 	.probe = mlx90614_probe,
 	.probe = mlx90614_probe,

+ 2 - 3
drivers/iio/temperature/tmp006.c

@@ -36,9 +36,9 @@
 #define TMP006_CONFIG_DRDY_EN BIT(8)
 #define TMP006_CONFIG_DRDY_EN BIT(8)
 #define TMP006_CONFIG_DRDY BIT(7)
 #define TMP006_CONFIG_DRDY BIT(7)
 
 
-#define TMP006_CONFIG_MOD_MASK 0x7000
+#define TMP006_CONFIG_MOD_MASK GENMASK(14, 12)
 
 
-#define TMP006_CONFIG_CR_MASK 0x0e00
+#define TMP006_CONFIG_CR_MASK GENMASK(11, 9)
 #define TMP006_CONFIG_CR_SHIFT 9
 #define TMP006_CONFIG_CR_SHIFT 9
 
 
 #define TMP006_MANUFACTURER_MAGIC 0x5449
 #define TMP006_MANUFACTURER_MAGIC 0x5449
@@ -280,7 +280,6 @@ static struct i2c_driver tmp006_driver = {
 	.driver = {
 	.driver = {
 		.name	= "tmp006",
 		.name	= "tmp006",
 		.pm	= &tmp006_pm_ops,
 		.pm	= &tmp006_pm_ops,
-		.owner	= THIS_MODULE,
 	},
 	},
 	.probe = tmp006_probe,
 	.probe = tmp006_probe,
 	.remove = tmp006_remove,
 	.remove = tmp006_remove,

+ 2 - 4
drivers/staging/Kconfig

@@ -56,8 +56,6 @@ source "drivers/staging/vt6656/Kconfig"
 
 
 source "drivers/staging/iio/Kconfig"
 source "drivers/staging/iio/Kconfig"
 
 
-source "drivers/staging/sm7xxfb/Kconfig"
-
 source "drivers/staging/sm750fb/Kconfig"
 source "drivers/staging/sm750fb/Kconfig"
 
 
 source "drivers/staging/xgifb/Kconfig"
 source "drivers/staging/xgifb/Kconfig"
@@ -78,8 +76,6 @@ source "drivers/staging/android/Kconfig"
 
 
 source "drivers/staging/board/Kconfig"
 source "drivers/staging/board/Kconfig"
 
 
-source "drivers/staging/ozwpan/Kconfig"
-
 source "drivers/staging/gdm72xx/Kconfig"
 source "drivers/staging/gdm72xx/Kconfig"
 
 
 source "drivers/staging/gdm724x/Kconfig"
 source "drivers/staging/gdm724x/Kconfig"
@@ -112,4 +108,6 @@ source "drivers/staging/fsl-mc/Kconfig"
 
 
 source "drivers/staging/wilc1000/Kconfig"
 source "drivers/staging/wilc1000/Kconfig"
 
 
+source "drivers/staging/most/Kconfig"
+
 endif # STAGING
 endif # STAGING

+ 1 - 2
drivers/staging/Makefile

@@ -22,7 +22,6 @@ obj-$(CONFIG_VT6655)		+= vt6655/
 obj-$(CONFIG_VT6656)		+= vt6656/
 obj-$(CONFIG_VT6656)		+= vt6656/
 obj-$(CONFIG_VME_BUS)		+= vme/
 obj-$(CONFIG_VME_BUS)		+= vme/
 obj-$(CONFIG_IIO)		+= iio/
 obj-$(CONFIG_IIO)		+= iio/
-obj-$(CONFIG_FB_SM7XX)		+= sm7xxfb/
 obj-$(CONFIG_FB_SM750)		+= sm750fb/
 obj-$(CONFIG_FB_SM750)		+= sm750fb/
 obj-$(CONFIG_FB_XGI)		+= xgifb/
 obj-$(CONFIG_FB_XGI)		+= xgifb/
 obj-$(CONFIG_USB_EMXX)		+= emxx_udc/
 obj-$(CONFIG_USB_EMXX)		+= emxx_udc/
@@ -32,7 +31,6 @@ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)	+= ste_rmi4/
 obj-$(CONFIG_MFD_NVEC)		+= nvec/
 obj-$(CONFIG_MFD_NVEC)		+= nvec/
 obj-$(CONFIG_ANDROID)		+= android/
 obj-$(CONFIG_ANDROID)		+= android/
 obj-$(CONFIG_STAGING_BOARD)	+= board/
 obj-$(CONFIG_STAGING_BOARD)	+= board/
-obj-$(CONFIG_USB_WPAN_HCD)	+= ozwpan/
 obj-$(CONFIG_WIMAX_GDM72XX)	+= gdm72xx/
 obj-$(CONFIG_WIMAX_GDM72XX)	+= gdm72xx/
 obj-$(CONFIG_LTE_GDM724X)	+= gdm724x/
 obj-$(CONFIG_LTE_GDM724X)	+= gdm724x/
 obj-$(CONFIG_FIREWIRE_SERIAL)	+= fwserial/
 obj-$(CONFIG_FIREWIRE_SERIAL)	+= fwserial/
@@ -48,3 +46,4 @@ obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)	+= clocking-wizard/
 obj-$(CONFIG_FB_TFT)		+= fbtft/
 obj-$(CONFIG_FB_TFT)		+= fbtft/
 obj-$(CONFIG_FSL_MC_BUS)	+= fsl-mc/
 obj-$(CONFIG_FSL_MC_BUS)	+= fsl-mc/
 obj-$(CONFIG_WILC1000)		+= wilc1000/
 obj-$(CONFIG_WILC1000)		+= wilc1000/
+obj-$(CONFIG_MOST)		+= most/

+ 2 - 1
drivers/staging/android/Kconfig

@@ -20,7 +20,8 @@ config ANDROID_TIMED_OUTPUT
 
 
 config ANDROID_TIMED_GPIO
 config ANDROID_TIMED_GPIO
 	tristate "Android timed gpio driver"
 	tristate "Android timed gpio driver"
-	depends on GPIOLIB && ANDROID_TIMED_OUTPUT
+	depends on GPIOLIB || COMPILE_TEST
+	depends on ANDROID_TIMED_OUTPUT
 	default n
 	default n
         ---help---
         ---help---
 	  Unlike generic gpio is to allow programs to access and manipulate gpio
 	  Unlike generic gpio is to allow programs to access and manipulate gpio

+ 1 - 9
drivers/staging/android/TODO

@@ -2,16 +2,8 @@ TODO:
 	- checkpatch.pl cleanups
 	- checkpatch.pl cleanups
 	- sparse fixes
 	- sparse fixes
 	- rename files to be not so "generic"
 	- rename files to be not so "generic"
-	- make sure things build as modules properly
 	- add proper arch dependencies as needed
 	- add proper arch dependencies as needed
 	- audit userspace interfaces to make sure they are sane
 	- audit userspace interfaces to make sure they are sane
-	- kuid_t should never be exposed to user space as it is
-          kernel internal type. Data structure for this kuid_t is:
-          typedef struct {
-          	uid_t val;
-          } kuid_t;
-	- This bug is introduced by Xiong Zhou in the patch bd471258f2e09
-	- ("staging: android: logger: use kuid_t instead of uid_t")
 
 
 Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc:
 Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc:
-Brian Swetland <swetland@google.com>
+Arve Hjønnevåg <arve@android.com> and Riley Andrews <riandrews@android.com>

+ 2 - 2
drivers/staging/android/ashmem.c

@@ -388,7 +388,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)
 
 
 		/* ... and allocate the backing shmem file */
 		/* ... and allocate the backing shmem file */
 		vmfile = shmem_file_setup(name, asma->size, vma->vm_flags);
 		vmfile = shmem_file_setup(name, asma->size, vma->vm_flags);
-		if (unlikely(IS_ERR(vmfile))) {
+		if (IS_ERR(vmfile)) {
 			ret = PTR_ERR(vmfile);
 			ret = PTR_ERR(vmfile);
 			goto out;
 			goto out;
 		}
 		}
@@ -660,7 +660,7 @@ restart:
 		if (page_range_subsumed_by_range(range, pgstart, pgend))
 		if (page_range_subsumed_by_range(range, pgstart, pgend))
 			return 0;
 			return 0;
 		if (page_range_in_range(range, pgstart, pgend)) {
 		if (page_range_in_range(range, pgstart, pgend)) {
-			pgstart = min_t(size_t, range->pgstart, pgstart),
+			pgstart = min_t(size_t, range->pgstart, pgstart);
 			pgend = max_t(size_t, range->pgend, pgend);
 			pgend = max_t(size_t, range->pgend, pgend);
 			purged |= range->purged;
 			purged |= range->purged;
 			range_del(range);
 			range_del(range);

+ 10 - 14
drivers/staging/android/ion/ion.c

@@ -1103,10 +1103,10 @@ static struct dma_buf_ops dma_buf_ops = {
 struct dma_buf *ion_share_dma_buf(struct ion_client *client,
 struct dma_buf *ion_share_dma_buf(struct ion_client *client,
 						struct ion_handle *handle)
 						struct ion_handle *handle)
 {
 {
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
 	struct ion_buffer *buffer;
 	struct ion_buffer *buffer;
 	struct dma_buf *dmabuf;
 	struct dma_buf *dmabuf;
 	bool valid_handle;
 	bool valid_handle;
-	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
 
 
 	mutex_lock(&client->lock);
 	mutex_lock(&client->lock);
 	valid_handle = ion_handle_validate(client, handle);
 	valid_handle = ion_handle_validate(client, handle);
@@ -1466,7 +1466,6 @@ static const struct file_operations debug_heap_fops = {
 	.release = single_release,
 	.release = single_release,
 };
 };
 
 
-#ifdef DEBUG_HEAP_SHRINKER
 static int debug_shrink_set(void *data, u64 val)
 static int debug_shrink_set(void *data, u64 val)
 {
 {
 	struct ion_heap *heap = data;
 	struct ion_heap *heap = data;
@@ -1474,15 +1473,14 @@ static int debug_shrink_set(void *data, u64 val)
 	int objs;
 	int objs;
 
 
 	sc.gfp_mask = -1;
 	sc.gfp_mask = -1;
-	sc.nr_to_scan = 0;
+	sc.nr_to_scan = val;
 
 
-	if (!val)
-		return 0;
-
-	objs = heap->shrinker.shrink(&heap->shrinker, &sc);
-	sc.nr_to_scan = objs;
+	if (!val) {
+		objs = heap->shrinker.count_objects(&heap->shrinker, &sc);
+		sc.nr_to_scan = objs;
+	}
 
 
-	heap->shrinker.shrink(&heap->shrinker, &sc);
+	heap->shrinker.scan_objects(&heap->shrinker, &sc);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1495,14 +1493,13 @@ static int debug_shrink_get(void *data, u64 *val)
 	sc.gfp_mask = -1;
 	sc.gfp_mask = -1;
 	sc.nr_to_scan = 0;
 	sc.nr_to_scan = 0;
 
 
-	objs = heap->shrinker.shrink(&heap->shrinker, &sc);
+	objs = heap->shrinker.count_objects(&heap->shrinker, &sc);
 	*val = objs;
 	*val = objs;
 	return 0;
 	return 0;
 }
 }
 
 
 DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get,
 DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get,
 			debug_shrink_set, "%llu\n");
 			debug_shrink_set, "%llu\n");
-#endif
 
 
 void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
 void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
 {
 {
@@ -1540,8 +1537,7 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
 			path, heap->name);
 			path, heap->name);
 	}
 	}
 
 
-#ifdef DEBUG_HEAP_SHRINKER
-	if (heap->shrinker.shrink) {
+	if (heap->shrinker.count_objects && heap->shrinker.scan_objects) {
 		char debug_name[64];
 		char debug_name[64];
 
 
 		snprintf(debug_name, 64, "%s_shrink", heap->name);
 		snprintf(debug_name, 64, "%s_shrink", heap->name);
@@ -1556,7 +1552,7 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
 				path, debug_name);
 				path, debug_name);
 		}
 		}
 	}
 	}
-#endif
+
 	up_write(&dev->lock);
 	up_write(&dev->lock);
 }
 }
 
 

Some files were not shown because too many files changed in this diff