All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths
@ 2013-06-11 14:52 Alexandre Relange
  2013-06-11 14:52 ` [PATCH 2/5] iio: mechanical: new category of sensors Alexandre Relange
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Alexandre Relange @ 2013-06-11 14:52 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Alexandre Relange

update ABI documentation with current paths related to scan_elements folder

Paths changed long time ago in commit: 26d25ae3f0d8ffe350aacc75b71198d6b35bd1f4

Signed-off-by: Alexandre Relange <alexandre@relange.org>
---
 Documentation/ABI/testing/sysfs-bus-iio | 90 ++++++++++++++++-----------------
 1 file changed, 45 insertions(+), 45 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 2e33dc6..dda81ff 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -690,45 +690,45 @@ Description:
 		Actually start the buffer capture up.  Will start trigger
 		if first device and appropriate.
 
-What:		/sys/bus/iio/devices/iio:deviceX/buffer/scan_elements
+What:		/sys/bus/iio/devices/iio:deviceX/scan_elements
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
 		Directory containing interfaces for elements that will be
 		captured for a single triggered sample set in the buffer.
 
-What:		/sys/.../buffer/scan_elements/in_accel_x_en
-What:		/sys/.../buffer/scan_elements/in_accel_y_en
-What:		/sys/.../buffer/scan_elements/in_accel_z_en
-What:		/sys/.../buffer/scan_elements/in_anglvel_x_en
-What:		/sys/.../buffer/scan_elements/in_anglvel_y_en
-What:		/sys/.../buffer/scan_elements/in_anglvel_z_en
-What:		/sys/.../buffer/scan_elements/in_magn_x_en
-What:		/sys/.../buffer/scan_elements/in_magn_y_en
-What:		/sys/.../buffer/scan_elements/in_magn_z_en
-What:		/sys/.../buffer/scan_elements/in_timestamp_en
-What:		/sys/.../buffer/scan_elements/in_voltageY_supply_en
-What:		/sys/.../buffer/scan_elements/in_voltageY_en
-What:		/sys/.../buffer/scan_elements/in_voltageY-voltageZ_en
-What:		/sys/.../buffer/scan_elements/in_incli_x_en
-What:		/sys/.../buffer/scan_elements/in_incli_y_en
-What:		/sys/.../buffer/scan_elements/in_pressureY_en
-What:		/sys/.../buffer/scan_elements/in_pressure_en
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_x_en
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_y_en
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_z_en
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_x_en
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_y_en
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_z_en
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_x_en
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_y_en
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_z_en
+What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_en
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_en
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_en
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY-voltageZ_en
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_x_en
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_y_en
+What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_en
+What:		/sys/.../iio:deviceX/scan_elements/in_pressure_en
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
 		Scan element control for triggered data capture.
 
-What:		/sys/.../buffer/scan_elements/in_accel_type
-What:		/sys/.../buffer/scan_elements/in_anglvel_type
-What:		/sys/.../buffer/scan_elements/in_magn_type
-What:		/sys/.../buffer/scan_elements/in_incli_type
-What:		/sys/.../buffer/scan_elements/in_voltageY_type
-What:		/sys/.../buffer/scan_elements/in_voltage_type
-What:		/sys/.../buffer/scan_elements/in_voltageY_supply_type
-What:		/sys/.../buffer/scan_elements/in_timestamp_type
-What:		/sys/.../buffer/scan_elements/in_pressureY_type
-What:		/sys/.../buffer/scan_elements/in_pressure_type
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_type
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_type
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_type
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_type
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_type
+What:		/sys/.../iio:deviceX/scan_elements/in_voltage_type
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_type
+What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_type
+What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_type
+What:		/sys/.../iio:deviceX/scan_elements/in_pressure_type
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
@@ -752,29 +752,29 @@ Description:
 		For other storage combinations this attribute will be extended
 		appropriately.
 
-What:		/sys/.../buffer/scan_elements/in_accel_type_available
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_type_available
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
 		If the type parameter can take one of a small set of values,
 		this attribute lists them.
 
-What:		/sys/.../buffer/scan_elements/in_voltageY_index
-What:		/sys/.../buffer/scan_elements/in_voltageY_supply_index
-What:		/sys/.../buffer/scan_elements/in_accel_x_index
-What:		/sys/.../buffer/scan_elements/in_accel_y_index
-What:		/sys/.../buffer/scan_elements/in_accel_z_index
-What:		/sys/.../buffer/scan_elements/in_anglvel_x_index
-What:		/sys/.../buffer/scan_elements/in_anglvel_y_index
-What:		/sys/.../buffer/scan_elements/in_anglvel_z_index
-What:		/sys/.../buffer/scan_elements/in_magn_x_index
-What:		/sys/.../buffer/scan_elements/in_magn_y_index
-What:		/sys/.../buffer/scan_elements/in_magn_z_index
-What:		/sys/.../buffer/scan_elements/in_incli_x_index
-What:		/sys/.../buffer/scan_elements/in_incli_y_index
-What:		/sys/.../buffer/scan_elements/in_timestamp_index
-What:		/sys/.../buffer/scan_elements/in_pressureY_index
-What:		/sys/.../buffer/scan_elements/in_pressure_index
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_index
+What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_index
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_x_index
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_y_index
+What:		/sys/.../iio:deviceX/scan_elements/in_accel_z_index
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_x_index
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_y_index
+What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_z_index
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_x_index
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_y_index
+What:		/sys/.../iio:deviceX/scan_elements/in_magn_z_index
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_x_index
+What:		/sys/.../iio:deviceX/scan_elements/in_incli_y_index
+What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_index
+What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_index
+What:		/sys/.../iio:deviceX/scan_elements/in_pressure_index
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
-- 
1.8.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/5] iio: mechanical: new category of sensors
  2013-06-11 14:52 [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Alexandre Relange
@ 2013-06-11 14:52 ` Alexandre Relange
  2013-07-07 15:29   ` Jonathan Cameron
  2013-06-11 14:52 ` [PATCH 3/5] iio: new type of channel: STATE Alexandre Relange
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Alexandre Relange @ 2013-06-11 14:52 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Alexandre Relange

adds the category of mechanical sensors (switches,...)

Signed-off-by: Alexandre Relange <alexandre@relange.org>
---
 drivers/iio/Kconfig             | 1 +
 drivers/iio/Makefile            | 1 +
 drivers/iio/mechanical/Kconfig  | 6 ++++++
 drivers/iio/mechanical/Makefile | 3 +++
 4 files changed, 11 insertions(+)
 create mode 100644 drivers/iio/mechanical/Kconfig
 create mode 100644 drivers/iio/mechanical/Makefile

diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index b2f963b..dbed2f1 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -70,5 +70,6 @@ source "drivers/iio/gyro/Kconfig"
 source "drivers/iio/imu/Kconfig"
 source "drivers/iio/light/Kconfig"
 source "drivers/iio/magnetometer/Kconfig"
+source "drivers/iio/mechanical/Kconfig"
 
 endif # IIO
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index a0e8cdd..78ec75b 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -21,3 +21,4 @@ obj-y += frequency/
 obj-y += imu/
 obj-y += light/
 obj-y += magnetometer/
+obj-y += mechanical/
diff --git a/drivers/iio/mechanical/Kconfig b/drivers/iio/mechanical/Kconfig
new file mode 100644
index 0000000..b536fa2
--- /dev/null
+++ b/drivers/iio/mechanical/Kconfig
@@ -0,0 +1,6 @@
+#
+# Mechanical sensors
+#
+menu "Mechanical sensors"
+
+endmenu
diff --git a/drivers/iio/mechanical/Makefile b/drivers/iio/mechanical/Makefile
new file mode 100644
index 0000000..716098f
--- /dev/null
+++ b/drivers/iio/mechanical/Makefile
@@ -0,0 +1,3 @@
+#
+# Makefile for IIO Mechanical sensors
+#
-- 
1.8.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/5] iio: new type of channel: STATE
  2013-06-11 14:52 [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Alexandre Relange
  2013-06-11 14:52 ` [PATCH 2/5] iio: mechanical: new category of sensors Alexandre Relange
@ 2013-06-11 14:52 ` Alexandre Relange
  2013-06-11 14:52 ` [PATCH 4/5] iio: mechanical: new HID sensor boolean switch Alexandre Relange
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Alexandre Relange @ 2013-06-11 14:52 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Alexandre Relange

This type is used for sensing that is not a physical quantity
(e.g. a switch). This type has no unit.
Included ABI documentation update.

Signed-off-by: Alexandre Relange <alexandre@relange.org>
---
 Documentation/ABI/testing/sysfs-bus-iio | 10 ++++++++++
 drivers/iio/industrialio-core.c         |  1 +
 include/linux/iio/types.h               |  1 +
 3 files changed, 12 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index dda81ff..1c2be35 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -197,6 +197,13 @@ Description:
 		Raw pressure measurement from channel Y. Units after
 		application of scale and offset are kilopascal.
 
+What:		/sys/bus/iio/devices/iio:deviceX/in_state_raw
+KernelVersion:	3.11
+Contact:	linux-iio@vger.kernel.org
+Description:
+		State sensing of a device (e.g. switch state). Since this is not a
+		physical quantity, the value has no unit.
+
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_x_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
@@ -714,6 +721,7 @@ What:		/sys/.../iio:deviceX/scan_elements/in_incli_x_en
 What:		/sys/.../iio:deviceX/scan_elements/in_incli_y_en
 What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_en
 What:		/sys/.../iio:deviceX/scan_elements/in_pressure_en
+What:		/sys/.../iio:deviceX/scan_elements/in_state_en
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
@@ -729,6 +737,7 @@ What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_type
 What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_type
 What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_type
 What:		/sys/.../iio:deviceX/scan_elements/in_pressure_type
+What:		/sys/.../iio:deviceX/scan_elements/in_state_type
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
@@ -775,6 +784,7 @@ What:		/sys/.../iio:deviceX/scan_elements/in_incli_y_index
 What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_index
 What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_index
 What:		/sys/.../iio:deviceX/scan_elements/in_pressure_index
+What:		/sys/.../iio:deviceX/scan_elements/in_state_index
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index e145931..0799d39 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -66,6 +66,7 @@ static const char * const iio_chan_type_name_spec[] = {
 	[IIO_ALTVOLTAGE] = "altvoltage",
 	[IIO_CCT] = "cct",
 	[IIO_PRESSURE] = "pressure",
+	[IIO_STATE] = "state",
 };
 
 static const char * const iio_modifier_names[] = {
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 88bf0f0..0aded40 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -29,6 +29,7 @@ enum iio_chan_type {
 	IIO_ALTVOLTAGE,
 	IIO_CCT,
 	IIO_PRESSURE,
+	IIO_STATE,
 };
 
 enum iio_modifier {
-- 
1.8.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/5] iio: mechanical: new HID sensor boolean switch
  2013-06-11 14:52 [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Alexandre Relange
  2013-06-11 14:52 ` [PATCH 2/5] iio: mechanical: new category of sensors Alexandre Relange
  2013-06-11 14:52 ` [PATCH 3/5] iio: new type of channel: STATE Alexandre Relange
@ 2013-06-11 14:52 ` Alexandre Relange
  2013-06-11 17:13   ` Lars-Peter Clausen
                     ` (2 more replies)
  2013-06-11 14:52 ` [PATCH 5/5] iio: mechanical: switch sensor: add ID table Alexandre Relange
                   ` (2 subsequent siblings)
  5 siblings, 3 replies; 16+ messages in thread
From: Alexandre Relange @ 2013-06-11 14:52 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Alexandre Relange

Implements the Boolean Switch sensor from the USB sensor usage tables
http://www.usb.org/developers/hidpage/HUTRR39b.pdf

This code is based on drivers/iio/light/hid-sensor-als.c

Signed-off-by: Alexandre Relange <alexandre@relange.org>
---
 drivers/iio/mechanical/Kconfig             |  14 ++
 drivers/iio/mechanical/Makefile            |   1 +
 drivers/iio/mechanical/hid-sensor-switch.c | 359 +++++++++++++++++++++++++++++
 include/linux/hid-sensor-ids.h             |   4 +
 4 files changed, 378 insertions(+)
 create mode 100644 drivers/iio/mechanical/hid-sensor-switch.c

diff --git a/drivers/iio/mechanical/Kconfig b/drivers/iio/mechanical/Kconfig
index b536fa2..e449588 100644
--- a/drivers/iio/mechanical/Kconfig
+++ b/drivers/iio/mechanical/Kconfig
@@ -3,4 +3,18 @@
 #
 menu "Mechanical sensors"
 
+config HID_SENSOR_SWITCH
+	depends on HID_SENSOR_HUB
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	select HID_SENSOR_IIO_COMMON
+	select HID_SENSOR_IIO_TRIGGER
+	tristate "HID Boolean Switch"
+	help
+	  Say yes here to build support for the HID SENSOR
+	  Boolean Switch sensor.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called hid-sensor-switch.
+
 endmenu
diff --git a/drivers/iio/mechanical/Makefile b/drivers/iio/mechanical/Makefile
index 716098f..30931c5 100644
--- a/drivers/iio/mechanical/Makefile
+++ b/drivers/iio/mechanical/Makefile
@@ -1,3 +1,4 @@
 #
 # Makefile for IIO Mechanical sensors
 #
+obj-$(CONFIG_HID_SENSOR_SWITCH)	+= hid-sensor-switch.o
diff --git a/drivers/iio/mechanical/hid-sensor-switch.c b/drivers/iio/mechanical/hid-sensor-switch.c
new file mode 100644
index 0000000..7027305
--- /dev/null
+++ b/drivers/iio/mechanical/hid-sensor-switch.c
@@ -0,0 +1,359 @@
+/*
+ * HID Sensors Driver
+ * Copyright (c) 2012, Intel Corporation.
+ * Copyright (c) 2013, Alexandre Relange
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/hid-sensor-hub.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include "../common/hid-sensors/hid-sensor-trigger.h"
+
+/*Format: HID-SENSOR-usage_id_in_hex*/
+/*Usage ID from spec for Boolean-Switch: 0x200061*/
+#define DRIVER_NAME "HID-SENSOR-200061"
+
+#define CHANNEL_SCAN_INDEX_SWITCH 0
+
+struct switch_state {
+	struct hid_sensor_hub_callbacks callbacks;
+	struct hid_sensor_common common_attributes;
+	struct hid_sensor_hub_attribute_info switch_attr;
+	u32 value;
+};
+
+/* Channel definitions */
+static const struct iio_chan_spec switch_channels[] = {
+	{
+		.type = IIO_STATE,
+		.info_mask_shared_by_type =
+			BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+			BIT(IIO_CHAN_INFO_HYSTERESIS),
+		.scan_index = CHANNEL_SCAN_INDEX_SWITCH,
+	}
+};
+
+/* Adjust channel real bits based on report descriptor */
+static void switch_adjust_channel_bit_mask(struct iio_chan_spec *channels,
+					int channel, int size)
+{
+	channels[channel].scan_type.sign = 'u';
+	/* Real storage bits will change based on the report desc. */
+	channels[channel].scan_type.realbits = size * 8;
+	/* Maximum size of a sample to capture is u32 */
+	channels[channel].scan_type.storagebits = sizeof(u32) * 8;
+}
+
+/* Channel read_raw handler */
+static int switch_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	struct switch_state *switch_state = iio_priv(indio_dev);
+	int report_id = -1;
+	u32 address;
+	int ret;
+	int ret_type;
+
+	*val = 0;
+	*val2 = 0;
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		switch (chan->scan_index) {
+		case  CHANNEL_SCAN_INDEX_SWITCH:
+			report_id = switch_state->switch_attr.report_id;
+			address =
+			HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE;
+			break;
+		default:
+			report_id = -1;
+			break;
+		}
+		if (report_id >= 0)
+			*val = sensor_hub_input_attr_get_raw_value(
+				switch_state->common_attributes.hsdev,
+				HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, address,
+				report_id);
+		else {
+			*val = 0;
+			return -EINVAL;
+		}
+		ret_type = IIO_VAL_INT;
+		break;
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = hid_sensor_read_samp_freq_value(
+				&switch_state->common_attributes, val, val2);
+		ret_type = IIO_VAL_INT_PLUS_MICRO;
+		break;
+	case IIO_CHAN_INFO_HYSTERESIS:
+		ret = hid_sensor_read_raw_hyst_value(
+				&switch_state->common_attributes, val, val2);
+		ret_type = IIO_VAL_INT_PLUS_MICRO;
+		break;
+	default:
+		ret_type = -EINVAL;
+		break;
+	}
+
+	return ret_type;
+}
+
+/* Channel write_raw handler */
+static int switch_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	struct switch_state *switch_state = iio_priv(indio_dev);
+	int ret = 0;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = hid_sensor_write_samp_freq_value(
+				&switch_state->common_attributes, val, val2);
+		break;
+	case IIO_CHAN_INFO_HYSTERESIS:
+		ret = hid_sensor_write_raw_hyst_value(
+				&switch_state->common_attributes, val, val2);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int switch_write_raw_get_fmt(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       long mask)
+{
+	return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static const struct iio_info switch_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &switch_read_raw,
+	.write_raw = &switch_write_raw,
+	.write_raw_get_fmt = &switch_write_raw_get_fmt,
+};
+
+/* Function to push data to buffer */
+static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+{
+	dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
+	iio_push_to_buffers(indio_dev, (u8 *)data);
+}
+
+/* Callback handler to send event after all samples are received and captured */
+static int switch_proc_event(struct hid_sensor_hub_device *hsdev,
+				unsigned usage_id,
+				void *priv)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(priv);
+	struct switch_state *switch_state = iio_priv(indio_dev);
+
+	dev_dbg(&indio_dev->dev, "switch_proc_event [%d]\n",
+				switch_state->common_attributes.data_ready);
+	if (switch_state->common_attributes.data_ready)
+		hid_sensor_push_data(indio_dev,
+				(u8 *)&switch_state->value,
+				sizeof(switch_state->value));
+
+	return 0;
+}
+
+/* Capture samples in local storage */
+static int switch_capture_sample(struct hid_sensor_hub_device *hsdev,
+				unsigned usage_id,
+				size_t raw_len, char *raw_data,
+				void *priv)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(priv);
+	struct switch_state *switch_state = iio_priv(indio_dev);
+	int ret = -EINVAL;
+
+	switch (usage_id) {
+	case HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE:
+		switch_state->value = *(u32 *)raw_data;
+		ret = 0;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+/* Parse report which is specific to an usage id*/
+static int switch_parse_report(struct platform_device *pdev,
+				struct hid_sensor_hub_device *hsdev,
+				struct iio_chan_spec *channels,
+				unsigned usage_id,
+				struct switch_state *st)
+{
+	int ret;
+
+	ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
+			usage_id,
+			HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE,
+			&st->switch_attr);
+	if (ret < 0)
+		return ret;
+	switch_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_SWITCH,
+					st->switch_attr.size);
+
+	dev_dbg(&pdev->dev, "switch %x:%x\n", st->switch_attr.index,
+			st->switch_attr.report_id);
+
+	return ret;
+}
+
+/* Function to initialize the processing for usage id */
+static int hid_switch_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	static const char *name = "switch";
+	struct iio_dev *indio_dev;
+	struct switch_state *switch_state;
+	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+	struct iio_chan_spec *channels;
+
+	indio_dev = iio_device_alloc(sizeof(struct switch_state));
+	if (indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	platform_set_drvdata(pdev, indio_dev);
+
+	switch_state = iio_priv(indio_dev);
+	switch_state->common_attributes.hsdev = hsdev;
+	switch_state->common_attributes.pdev = pdev;
+
+	ret = hid_sensor_parse_common_attributes(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
+					&switch_state->common_attributes);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to setup common attributes\n");
+		goto error_free_dev;
+	}
+
+	channels = kmemdup(switch_channels, sizeof(switch_channels), GFP_KERNEL);
+	if (!channels) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "failed to duplicate channels\n");
+		goto error_free_dev;
+	}
+
+	ret = switch_parse_report(pdev, hsdev, channels,
+				HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, switch_state);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to setup attributes\n");
+		goto error_free_dev_mem;
+	}
+
+	indio_dev->channels = channels;
+	indio_dev->num_channels =
+				ARRAY_SIZE(switch_channels);
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->info = &switch_info;
+	indio_dev->name = name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+		NULL, NULL);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
+		goto error_free_dev_mem;
+	}
+	switch_state->common_attributes.data_ready = false;
+	ret = hid_sensor_setup_trigger(indio_dev, name,
+				&switch_state->common_attributes);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "trigger setup failed\n");
+		goto error_unreg_buffer_funcs;
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret) {
+		dev_err(&pdev->dev, "device register failed\n");
+		goto error_remove_trigger;
+	}
+
+	switch_state->callbacks.send_event = switch_proc_event;
+	switch_state->callbacks.capture_sample = switch_capture_sample;
+	switch_state->callbacks.pdev = pdev;
+	ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
+					&switch_state->callbacks);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "callback reg failed\n");
+		goto error_iio_unreg;
+	}
+
+	return ret;
+
+error_iio_unreg:
+	iio_device_unregister(indio_dev);
+error_remove_trigger:
+	hid_sensor_remove_trigger(indio_dev);
+error_unreg_buffer_funcs:
+	iio_triggered_buffer_cleanup(indio_dev);
+error_free_dev_mem:
+	kfree(indio_dev->channels);
+error_free_dev:
+	iio_device_free(indio_dev);
+error_ret:
+	return ret;
+}
+
+/* Function to deinitialize the processing for usage id */
+static int hid_switch_remove(struct platform_device *pdev)
+{
+	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+
+	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH);
+	iio_device_unregister(indio_dev);
+	hid_sensor_remove_trigger(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+	kfree(indio_dev->channels);
+	iio_device_free(indio_dev);
+
+	return 0;
+}
+
+static struct platform_driver hid_switch_platform_driver = {
+	.driver = {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= hid_switch_probe,
+	.remove		= hid_switch_remove,
+};
+module_platform_driver(hid_switch_platform_driver);
+
+MODULE_DESCRIPTION("HID Sensor Boolean Switch");
+MODULE_AUTHOR("Alexandre Relange <alexandre@relange.org>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
index 6f24446..e469078 100644
--- a/include/linux/hid-sensor-ids.h
+++ b/include/linux/hid-sensor-ids.h
@@ -31,6 +31,10 @@
 #define HID_USAGE_SENSOR_ALS					0x200041
 #define HID_USAGE_SENSOR_LIGHT_ILLUM				0x2004d1
 
+/* MECHANICAL: Boolean Switch: (200061) */
+#define HID_USAGE_SENSOR_MECHA_BOOL_SWITCH			0x200061
+#define HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE		0x200491
+
 /* Gyro 3D: (200076) */
 #define HID_USAGE_SENSOR_GYRO_3D				0x200076
 #define HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS			0x200457
-- 
1.8.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/5] iio: mechanical: switch sensor: add ID table
  2013-06-11 14:52 [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Alexandre Relange
                   ` (2 preceding siblings ...)
  2013-06-11 14:52 ` [PATCH 4/5] iio: mechanical: new HID sensor boolean switch Alexandre Relange
@ 2013-06-11 14:52 ` Alexandre Relange
  2013-06-11 17:07 ` [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Lars-Peter Clausen
  2013-06-11 20:10 ` Jonathan Cameron
  5 siblings, 0 replies; 16+ messages in thread
From: Alexandre Relange @ 2013-06-11 14:52 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Alexandre Relange

auto-probes module when device is detected and prepare module extension
to other hid mechanical sensors.

Signed-off-by: Alexandre Relange <alexandre@relange.org>
---
 drivers/iio/mechanical/hid-sensor-switch.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/iio/mechanical/hid-sensor-switch.c b/drivers/iio/mechanical/hid-sensor-switch.c
index 7027305..1556ee5 100644
--- a/drivers/iio/mechanical/hid-sensor-switch.c
+++ b/drivers/iio/mechanical/hid-sensor-switch.c
@@ -344,11 +344,18 @@ static int hid_switch_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct platform_device_id switch_id_table[] = {
+        { "HID-SENSOR-200061", 0 },
+        {  } /* Terminating Entry */
+};
+MODULE_DEVICE_TABLE(platform, switch_id_table);
+
 static struct platform_driver hid_switch_platform_driver = {
 	.driver = {
 		.name	= DRIVER_NAME,
 		.owner	= THIS_MODULE,
 	},
+	.id_table	= switch_id_table,
 	.probe		= hid_switch_probe,
 	.remove		= hid_switch_remove,
 };
-- 
1.8.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths
  2013-06-11 14:52 [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Alexandre Relange
                   ` (3 preceding siblings ...)
  2013-06-11 14:52 ` [PATCH 5/5] iio: mechanical: switch sensor: add ID table Alexandre Relange
@ 2013-06-11 17:07 ` Lars-Peter Clausen
  2013-06-11 20:10 ` Jonathan Cameron
  5 siblings, 0 replies; 16+ messages in thread
From: Lars-Peter Clausen @ 2013-06-11 17:07 UTC (permalink / raw)
  To: Alexandre Relange; +Cc: Jonathan Cameron, linux-iio

On 06/11/2013 04:52 PM, Alexandre Relange wrote:
> update ABI documentation with current paths related to scan_elements folder
> 
> Paths changed long time ago in commit: 26d25ae3f0d8ffe350aacc75b71198d6b35bd1f4
> 

Hi,

It looks like patch 3 and 5 in series went missing.

- Lars

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/5] iio: mechanical: new HID sensor boolean switch
  2013-06-11 14:52 ` [PATCH 4/5] iio: mechanical: new HID sensor boolean switch Alexandre Relange
@ 2013-06-11 17:13   ` Lars-Peter Clausen
  2013-06-11 20:18     ` Jonathan Cameron
  2013-07-07 15:36   ` Jonathan Cameron
  2013-07-12 19:34   ` Alexander Holler
  2 siblings, 1 reply; 16+ messages in thread
From: Lars-Peter Clausen @ 2013-06-11 17:13 UTC (permalink / raw)
  To: Alexandre Relange; +Cc: Jonathan Cameron, linux-iio

On 06/11/2013 04:52 PM, Alexandre Relange wrote:
> Implements the Boolean Switch sensor from the USB sensor usage tables
> http://www.usb.org/developers/hidpage/HUTRR39b.pdf
> 
> This code is based on drivers/iio/light/hid-sensor-als.c
> 
> Signed-off-by: Alexandre Relange <alexandre@relange.org>

I'm wondering, how is this different from a GPIO (or GPI for that matter)?

> ---
>  drivers/iio/mechanical/Kconfig             |  14 ++
>  drivers/iio/mechanical/Makefile            |   1 +
>  drivers/iio/mechanical/hid-sensor-switch.c | 359 +++++++++++++++++++++++++++++
>  include/linux/hid-sensor-ids.h             |   4 +
>  4 files changed, 378 insertions(+)
>  create mode 100644 drivers/iio/mechanical/hid-sensor-switch.c
> 
> diff --git a/drivers/iio/mechanical/Kconfig b/drivers/iio/mechanical/Kconfig
> index b536fa2..e449588 100644
> --- a/drivers/iio/mechanical/Kconfig
> +++ b/drivers/iio/mechanical/Kconfig
> @@ -3,4 +3,18 @@
>  #
>  menu "Mechanical sensors"
>  
> +config HID_SENSOR_SWITCH
> +	depends on HID_SENSOR_HUB
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
> +	select HID_SENSOR_IIO_COMMON
> +	select HID_SENSOR_IIO_TRIGGER
> +	tristate "HID Boolean Switch"
> +	help
> +	  Say yes here to build support for the HID SENSOR
> +	  Boolean Switch sensor.
> +
> +	  This driver can also be built as a module.  If so, the module
> +	  will be called hid-sensor-switch.
> +
>  endmenu
> diff --git a/drivers/iio/mechanical/Makefile b/drivers/iio/mechanical/Makefile
> index 716098f..30931c5 100644
> --- a/drivers/iio/mechanical/Makefile
> +++ b/drivers/iio/mechanical/Makefile
> @@ -1,3 +1,4 @@
>  #
>  # Makefile for IIO Mechanical sensors
>  #
> +obj-$(CONFIG_HID_SENSOR_SWITCH)	+= hid-sensor-switch.o
> diff --git a/drivers/iio/mechanical/hid-sensor-switch.c b/drivers/iio/mechanical/hid-sensor-switch.c
> new file mode 100644
> index 0000000..7027305
> --- /dev/null
> +++ b/drivers/iio/mechanical/hid-sensor-switch.c
> @@ -0,0 +1,359 @@
> +/*
> + * HID Sensors Driver
> + * Copyright (c) 2012, Intel Corporation.
> + * Copyright (c) 2013, Alexandre Relange
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + */
> +#include <linux/device.h>
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/slab.h>
> +#include <linux/hid-sensor-hub.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
> +#include "../common/hid-sensors/hid-sensor-trigger.h"
> +
> +/*Format: HID-SENSOR-usage_id_in_hex*/
> +/*Usage ID from spec for Boolean-Switch: 0x200061*/
> +#define DRIVER_NAME "HID-SENSOR-200061"
> +
> +#define CHANNEL_SCAN_INDEX_SWITCH 0
> +
> +struct switch_state {
> +	struct hid_sensor_hub_callbacks callbacks;
> +	struct hid_sensor_common common_attributes;
> +	struct hid_sensor_hub_attribute_info switch_attr;
> +	u32 value;
> +};
> +
> +/* Channel definitions */
> +static const struct iio_chan_spec switch_channels[] = {
> +	{
> +		.type = IIO_STATE,
> +		.info_mask_shared_by_type =
> +			BIT(IIO_CHAN_INFO_SAMP_FREQ) |
> +			BIT(IIO_CHAN_INFO_HYSTERESIS),
> +		.scan_index = CHANNEL_SCAN_INDEX_SWITCH,
> +	}
> +};
> +
> +/* Adjust channel real bits based on report descriptor */
> +static void switch_adjust_channel_bit_mask(struct iio_chan_spec *channels,
> +					int channel, int size)
> +{
> +	channels[channel].scan_type.sign = 'u';
> +	/* Real storage bits will change based on the report desc. */
> +	channels[channel].scan_type.realbits = size * 8;
> +	/* Maximum size of a sample to capture is u32 */
> +	channels[channel].scan_type.storagebits = sizeof(u32) * 8;
> +}
> +
> +/* Channel read_raw handler */
> +static int switch_read_raw(struct iio_dev *indio_dev,
> +			      struct iio_chan_spec const *chan,
> +			      int *val, int *val2,
> +			      long mask)
> +{
> +	struct switch_state *switch_state = iio_priv(indio_dev);
> +	int report_id = -1;
> +	u32 address;
> +	int ret;
> +	int ret_type;
> +
> +	*val = 0;
> +	*val2 = 0;
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		switch (chan->scan_index) {
> +		case  CHANNEL_SCAN_INDEX_SWITCH:
> +			report_id = switch_state->switch_attr.report_id;
> +			address =
> +			HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE;
> +			break;
> +		default:
> +			report_id = -1;
> +			break;
> +		}
> +		if (report_id >= 0)
> +			*val = sensor_hub_input_attr_get_raw_value(
> +				switch_state->common_attributes.hsdev,
> +				HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, address,
> +				report_id);
> +		else {
> +			*val = 0;
> +			return -EINVAL;
> +		}
> +		ret_type = IIO_VAL_INT;
> +		break;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		ret = hid_sensor_read_samp_freq_value(
> +				&switch_state->common_attributes, val, val2);
> +		ret_type = IIO_VAL_INT_PLUS_MICRO;
> +		break;
> +	case IIO_CHAN_INFO_HYSTERESIS:
> +		ret = hid_sensor_read_raw_hyst_value(
> +				&switch_state->common_attributes, val, val2);
> +		ret_type = IIO_VAL_INT_PLUS_MICRO;
> +		break;
> +	default:
> +		ret_type = -EINVAL;
> +		break;
> +	}
> +
> +	return ret_type;
> +}
> +
> +/* Channel write_raw handler */
> +static int switch_write_raw(struct iio_dev *indio_dev,
> +			       struct iio_chan_spec const *chan,
> +			       int val,
> +			       int val2,
> +			       long mask)
> +{
> +	struct switch_state *switch_state = iio_priv(indio_dev);
> +	int ret = 0;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		ret = hid_sensor_write_samp_freq_value(
> +				&switch_state->common_attributes, val, val2);
> +		break;
> +	case IIO_CHAN_INFO_HYSTERESIS:
> +		ret = hid_sensor_write_raw_hyst_value(
> +				&switch_state->common_attributes, val, val2);
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static int switch_write_raw_get_fmt(struct iio_dev *indio_dev,
> +			       struct iio_chan_spec const *chan,
> +			       long mask)
> +{
> +	return IIO_VAL_INT_PLUS_MICRO;
> +}
> +
> +static const struct iio_info switch_info = {
> +	.driver_module = THIS_MODULE,
> +	.read_raw = &switch_read_raw,
> +	.write_raw = &switch_write_raw,
> +	.write_raw_get_fmt = &switch_write_raw_get_fmt,
> +};
> +
> +/* Function to push data to buffer */
> +static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
> +{
> +	dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
> +	iio_push_to_buffers(indio_dev, (u8 *)data);
> +}
> +
> +/* Callback handler to send event after all samples are received and captured */
> +static int switch_proc_event(struct hid_sensor_hub_device *hsdev,
> +				unsigned usage_id,
> +				void *priv)
> +{
> +	struct iio_dev *indio_dev = platform_get_drvdata(priv);
> +	struct switch_state *switch_state = iio_priv(indio_dev);
> +
> +	dev_dbg(&indio_dev->dev, "switch_proc_event [%d]\n",
> +				switch_state->common_attributes.data_ready);
> +	if (switch_state->common_attributes.data_ready)
> +		hid_sensor_push_data(indio_dev,
> +				(u8 *)&switch_state->value,
> +				sizeof(switch_state->value));
> +
> +	return 0;
> +}
> +
> +/* Capture samples in local storage */
> +static int switch_capture_sample(struct hid_sensor_hub_device *hsdev,
> +				unsigned usage_id,
> +				size_t raw_len, char *raw_data,
> +				void *priv)
> +{
> +	struct iio_dev *indio_dev = platform_get_drvdata(priv);
> +	struct switch_state *switch_state = iio_priv(indio_dev);
> +	int ret = -EINVAL;
> +
> +	switch (usage_id) {
> +	case HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE:
> +		switch_state->value = *(u32 *)raw_data;
> +		ret = 0;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +/* Parse report which is specific to an usage id*/
> +static int switch_parse_report(struct platform_device *pdev,
> +				struct hid_sensor_hub_device *hsdev,
> +				struct iio_chan_spec *channels,
> +				unsigned usage_id,
> +				struct switch_state *st)
> +{
> +	int ret;
> +
> +	ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
> +			usage_id,
> +			HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE,
> +			&st->switch_attr);
> +	if (ret < 0)
> +		return ret;
> +	switch_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_SWITCH,
> +					st->switch_attr.size);
> +
> +	dev_dbg(&pdev->dev, "switch %x:%x\n", st->switch_attr.index,
> +			st->switch_attr.report_id);
> +
> +	return ret;
> +}
> +
> +/* Function to initialize the processing for usage id */
> +static int hid_switch_probe(struct platform_device *pdev)
> +{
> +	int ret = 0;
> +	static const char *name = "switch";
> +	struct iio_dev *indio_dev;
> +	struct switch_state *switch_state;
> +	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
> +	struct iio_chan_spec *channels;
> +
> +	indio_dev = iio_device_alloc(sizeof(struct switch_state));
> +	if (indio_dev == NULL) {
> +		ret = -ENOMEM;
> +		goto error_ret;
> +	}
> +	platform_set_drvdata(pdev, indio_dev);
> +
> +	switch_state = iio_priv(indio_dev);
> +	switch_state->common_attributes.hsdev = hsdev;
> +	switch_state->common_attributes.pdev = pdev;
> +
> +	ret = hid_sensor_parse_common_attributes(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
> +					&switch_state->common_attributes);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to setup common attributes\n");
> +		goto error_free_dev;
> +	}
> +
> +	channels = kmemdup(switch_channels, sizeof(switch_channels), GFP_KERNEL);
> +	if (!channels) {
> +		ret = -ENOMEM;
> +		dev_err(&pdev->dev, "failed to duplicate channels\n");
> +		goto error_free_dev;
> +	}
> +
> +	ret = switch_parse_report(pdev, hsdev, channels,
> +				HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, switch_state);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to setup attributes\n");
> +		goto error_free_dev_mem;
> +	}
> +
> +	indio_dev->channels = channels;
> +	indio_dev->num_channels =
> +				ARRAY_SIZE(switch_channels);
> +	indio_dev->dev.parent = &pdev->dev;
> +	indio_dev->info = &switch_info;
> +	indio_dev->name = name;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +
> +	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> +		NULL, NULL);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
> +		goto error_free_dev_mem;
> +	}
> +	switch_state->common_attributes.data_ready = false;
> +	ret = hid_sensor_setup_trigger(indio_dev, name,
> +				&switch_state->common_attributes);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "trigger setup failed\n");
> +		goto error_unreg_buffer_funcs;
> +	}
> +
> +	ret = iio_device_register(indio_dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "device register failed\n");
> +		goto error_remove_trigger;
> +	}
> +
> +	switch_state->callbacks.send_event = switch_proc_event;
> +	switch_state->callbacks.capture_sample = switch_capture_sample;
> +	switch_state->callbacks.pdev = pdev;
> +	ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
> +					&switch_state->callbacks);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "callback reg failed\n");
> +		goto error_iio_unreg;
> +	}
> +
> +	return ret;
> +
> +error_iio_unreg:
> +	iio_device_unregister(indio_dev);
> +error_remove_trigger:
> +	hid_sensor_remove_trigger(indio_dev);
> +error_unreg_buffer_funcs:
> +	iio_triggered_buffer_cleanup(indio_dev);
> +error_free_dev_mem:
> +	kfree(indio_dev->channels);
> +error_free_dev:
> +	iio_device_free(indio_dev);
> +error_ret:
> +	return ret;
> +}
> +
> +/* Function to deinitialize the processing for usage id */
> +static int hid_switch_remove(struct platform_device *pdev)
> +{
> +	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
> +	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH);
> +	iio_device_unregister(indio_dev);
> +	hid_sensor_remove_trigger(indio_dev);
> +	iio_triggered_buffer_cleanup(indio_dev);
> +	kfree(indio_dev->channels);
> +	iio_device_free(indio_dev);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver hid_switch_platform_driver = {
> +	.driver = {
> +		.name	= DRIVER_NAME,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= hid_switch_probe,
> +	.remove		= hid_switch_remove,
> +};
> +module_platform_driver(hid_switch_platform_driver);
> +
> +MODULE_DESCRIPTION("HID Sensor Boolean Switch");
> +MODULE_AUTHOR("Alexandre Relange <alexandre@relange.org>");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
> index 6f24446..e469078 100644
> --- a/include/linux/hid-sensor-ids.h
> +++ b/include/linux/hid-sensor-ids.h
> @@ -31,6 +31,10 @@
>  #define HID_USAGE_SENSOR_ALS					0x200041
>  #define HID_USAGE_SENSOR_LIGHT_ILLUM				0x2004d1
>  
> +/* MECHANICAL: Boolean Switch: (200061) */
> +#define HID_USAGE_SENSOR_MECHA_BOOL_SWITCH			0x200061
> +#define HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE		0x200491
> +
>  /* Gyro 3D: (200076) */
>  #define HID_USAGE_SENSOR_GYRO_3D				0x200076
>  #define HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS			0x200457

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths
  2013-06-11 14:52 [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Alexandre Relange
                   ` (4 preceding siblings ...)
  2013-06-11 17:07 ` [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Lars-Peter Clausen
@ 2013-06-11 20:10 ` Jonathan Cameron
  5 siblings, 0 replies; 16+ messages in thread
From: Jonathan Cameron @ 2013-06-11 20:10 UTC (permalink / raw)
  To: Alexandre Relange; +Cc: Jonathan Cameron, linux-iio

On 06/11/2013 03:52 PM, Alexandre Relange wrote:
> update ABI documentation with current paths related to scan_elements folder
> 
> Paths changed long time ago in commit: 26d25ae3f0d8ffe350aacc75b71198d6b35bd1f4
Good spot, that's been wrong for a long time.
> 
> Signed-off-by: Alexandre Relange <alexandre@relange.org>
Applied to the togreg branch of iio.git

Thanks,

> ---
>  Documentation/ABI/testing/sysfs-bus-iio | 90 ++++++++++++++++-----------------
>  1 file changed, 45 insertions(+), 45 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 2e33dc6..dda81ff 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -690,45 +690,45 @@ Description:
>  		Actually start the buffer capture up.  Will start trigger
>  		if first device and appropriate.
>  
> -What:		/sys/bus/iio/devices/iio:deviceX/buffer/scan_elements
> +What:		/sys/bus/iio/devices/iio:deviceX/scan_elements
>  KernelVersion:	2.6.37
>  Contact:	linux-iio@vger.kernel.org
>  Description:
>  		Directory containing interfaces for elements that will be
>  		captured for a single triggered sample set in the buffer.
>  
> -What:		/sys/.../buffer/scan_elements/in_accel_x_en
> -What:		/sys/.../buffer/scan_elements/in_accel_y_en
> -What:		/sys/.../buffer/scan_elements/in_accel_z_en
> -What:		/sys/.../buffer/scan_elements/in_anglvel_x_en
> -What:		/sys/.../buffer/scan_elements/in_anglvel_y_en
> -What:		/sys/.../buffer/scan_elements/in_anglvel_z_en
> -What:		/sys/.../buffer/scan_elements/in_magn_x_en
> -What:		/sys/.../buffer/scan_elements/in_magn_y_en
> -What:		/sys/.../buffer/scan_elements/in_magn_z_en
> -What:		/sys/.../buffer/scan_elements/in_timestamp_en
> -What:		/sys/.../buffer/scan_elements/in_voltageY_supply_en
> -What:		/sys/.../buffer/scan_elements/in_voltageY_en
> -What:		/sys/.../buffer/scan_elements/in_voltageY-voltageZ_en
> -What:		/sys/.../buffer/scan_elements/in_incli_x_en
> -What:		/sys/.../buffer/scan_elements/in_incli_y_en
> -What:		/sys/.../buffer/scan_elements/in_pressureY_en
> -What:		/sys/.../buffer/scan_elements/in_pressure_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_accel_x_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_accel_y_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_accel_z_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_x_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_y_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_z_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_magn_x_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_magn_y_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_magn_z_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_voltageY-voltageZ_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_incli_x_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_incli_y_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_en
> +What:		/sys/.../iio:deviceX/scan_elements/in_pressure_en
>  KernelVersion:	2.6.37
>  Contact:	linux-iio@vger.kernel.org
>  Description:
>  		Scan element control for triggered data capture.
>  
> -What:		/sys/.../buffer/scan_elements/in_accel_type
> -What:		/sys/.../buffer/scan_elements/in_anglvel_type
> -What:		/sys/.../buffer/scan_elements/in_magn_type
> -What:		/sys/.../buffer/scan_elements/in_incli_type
> -What:		/sys/.../buffer/scan_elements/in_voltageY_type
> -What:		/sys/.../buffer/scan_elements/in_voltage_type
> -What:		/sys/.../buffer/scan_elements/in_voltageY_supply_type
> -What:		/sys/.../buffer/scan_elements/in_timestamp_type
> -What:		/sys/.../buffer/scan_elements/in_pressureY_type
> -What:		/sys/.../buffer/scan_elements/in_pressure_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_accel_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_magn_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_incli_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_voltage_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_type
> +What:		/sys/.../iio:deviceX/scan_elements/in_pressure_type
>  KernelVersion:	2.6.37
>  Contact:	linux-iio@vger.kernel.org
>  Description:
> @@ -752,29 +752,29 @@ Description:
>  		For other storage combinations this attribute will be extended
>  		appropriately.
>  
> -What:		/sys/.../buffer/scan_elements/in_accel_type_available
> +What:		/sys/.../iio:deviceX/scan_elements/in_accel_type_available
>  KernelVersion:	2.6.37
>  Contact:	linux-iio@vger.kernel.org
>  Description:
>  		If the type parameter can take one of a small set of values,
>  		this attribute lists them.
>  
> -What:		/sys/.../buffer/scan_elements/in_voltageY_index
> -What:		/sys/.../buffer/scan_elements/in_voltageY_supply_index
> -What:		/sys/.../buffer/scan_elements/in_accel_x_index
> -What:		/sys/.../buffer/scan_elements/in_accel_y_index
> -What:		/sys/.../buffer/scan_elements/in_accel_z_index
> -What:		/sys/.../buffer/scan_elements/in_anglvel_x_index
> -What:		/sys/.../buffer/scan_elements/in_anglvel_y_index
> -What:		/sys/.../buffer/scan_elements/in_anglvel_z_index
> -What:		/sys/.../buffer/scan_elements/in_magn_x_index
> -What:		/sys/.../buffer/scan_elements/in_magn_y_index
> -What:		/sys/.../buffer/scan_elements/in_magn_z_index
> -What:		/sys/.../buffer/scan_elements/in_incli_x_index
> -What:		/sys/.../buffer/scan_elements/in_incli_y_index
> -What:		/sys/.../buffer/scan_elements/in_timestamp_index
> -What:		/sys/.../buffer/scan_elements/in_pressureY_index
> -What:		/sys/.../buffer/scan_elements/in_pressure_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_voltageY_supply_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_accel_x_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_accel_y_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_accel_z_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_x_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_y_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_anglvel_z_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_magn_x_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_magn_y_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_magn_z_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_incli_x_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_incli_y_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_timestamp_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_pressureY_index
> +What:		/sys/.../iio:deviceX/scan_elements/in_pressure_index
>  KernelVersion:	2.6.37
>  Contact:	linux-iio@vger.kernel.org
>  Description:
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/5] iio: mechanical: new HID sensor boolean switch
  2013-06-11 17:13   ` Lars-Peter Clausen
@ 2013-06-11 20:18     ` Jonathan Cameron
  0 siblings, 0 replies; 16+ messages in thread
From: Jonathan Cameron @ 2013-06-11 20:18 UTC (permalink / raw)
  To: Lars-Peter Clausen; +Cc: Alexandre Relange, Jonathan Cameron, linux-iio

On 06/11/2013 06:13 PM, Lars-Peter Clausen wrote:
> On 06/11/2013 04:52 PM, Alexandre Relange wrote:
>> Implements the Boolean Switch sensor from the USB sensor usage tables
>> http://www.usb.org/developers/hidpage/HUTRR39b.pdf
>>
>> This code is based on drivers/iio/light/hid-sensor-als.c
>>
>> Signed-off-by: Alexandre Relange <alexandre@relange.org>
> 
> I'm wondering, how is this different from a GPIO (or GPI for that matter)?
Clearly this is merit it having boolean type inputs in IIO as they
can be captured alongside other forms of data when triggers occur.
However, I agree with Lars-Peter that this needs a less hid-sensors
oriented name.  Whilst we are here, that spec also defines multiple
value switches and arrays of switches. Fun fun fun.

Just as an aside, what does hysterisis mean for a switch?

> 
>> ---
>>  drivers/iio/mechanical/Kconfig             |  14 ++
>>  drivers/iio/mechanical/Makefile            |   1 +
>>  drivers/iio/mechanical/hid-sensor-switch.c | 359 +++++++++++++++++++++++++++++
>>  include/linux/hid-sensor-ids.h             |   4 +
>>  4 files changed, 378 insertions(+)
>>  create mode 100644 drivers/iio/mechanical/hid-sensor-switch.c
>>
>> diff --git a/drivers/iio/mechanical/Kconfig b/drivers/iio/mechanical/Kconfig
>> index b536fa2..e449588 100644
>> --- a/drivers/iio/mechanical/Kconfig
>> +++ b/drivers/iio/mechanical/Kconfig
>> @@ -3,4 +3,18 @@
>>  #
>>  menu "Mechanical sensors"
>>  
>> +config HID_SENSOR_SWITCH
>> +	depends on HID_SENSOR_HUB
>> +	select IIO_BUFFER
>> +	select IIO_TRIGGERED_BUFFER
>> +	select HID_SENSOR_IIO_COMMON
>> +	select HID_SENSOR_IIO_TRIGGER
>> +	tristate "HID Boolean Switch"
>> +	help
>> +	  Say yes here to build support for the HID SENSOR
>> +	  Boolean Switch sensor.
>> +
>> +	  This driver can also be built as a module.  If so, the module
>> +	  will be called hid-sensor-switch.
>> +
>>  endmenu
>> diff --git a/drivers/iio/mechanical/Makefile b/drivers/iio/mechanical/Makefile
>> index 716098f..30931c5 100644
>> --- a/drivers/iio/mechanical/Makefile
>> +++ b/drivers/iio/mechanical/Makefile
>> @@ -1,3 +1,4 @@
>>  #
>>  # Makefile for IIO Mechanical sensors
>>  #
>> +obj-$(CONFIG_HID_SENSOR_SWITCH)	+= hid-sensor-switch.o
>> diff --git a/drivers/iio/mechanical/hid-sensor-switch.c b/drivers/iio/mechanical/hid-sensor-switch.c
>> new file mode 100644
>> index 0000000..7027305
>> --- /dev/null
>> +++ b/drivers/iio/mechanical/hid-sensor-switch.c
>> @@ -0,0 +1,359 @@
>> +/*
>> + * HID Sensors Driver
>> + * Copyright (c) 2012, Intel Corporation.
>> + * Copyright (c) 2013, Alexandre Relange
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
>> + * more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program; if not, write to the Free Software Foundation, Inc.,
>> + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
>> + *
>> + */
>> +#include <linux/device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/module.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/irq.h>
>> +#include <linux/slab.h>
>> +#include <linux/hid-sensor-hub.h>
>> +#include <linux/iio/iio.h>
>> +#include <linux/iio/sysfs.h>
>> +#include <linux/iio/buffer.h>
>> +#include <linux/iio/trigger_consumer.h>
>> +#include <linux/iio/triggered_buffer.h>
>> +#include "../common/hid-sensors/hid-sensor-trigger.h"
>> +
>> +/*Format: HID-SENSOR-usage_id_in_hex*/
>> +/*Usage ID from spec for Boolean-Switch: 0x200061*/
>> +#define DRIVER_NAME "HID-SENSOR-200061"
>> +
>> +#define CHANNEL_SCAN_INDEX_SWITCH 0
>> +
>> +struct switch_state {
>> +	struct hid_sensor_hub_callbacks callbacks;
>> +	struct hid_sensor_common common_attributes;
>> +	struct hid_sensor_hub_attribute_info switch_attr;
>> +	u32 value;
>> +};
>> +
>> +/* Channel definitions */
>> +static const struct iio_chan_spec switch_channels[] = {
>> +	{
>> +		.type = IIO_STATE,
>> +		.info_mask_shared_by_type =
>> +			BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>> +			BIT(IIO_CHAN_INFO_HYSTERESIS),
>> +		.scan_index = CHANNEL_SCAN_INDEX_SWITCH,
>> +	}
>> +};
>> +
>> +/* Adjust channel real bits based on report descriptor */
>> +static void switch_adjust_channel_bit_mask(struct iio_chan_spec *channels,
>> +					int channel, int size)
>> +{
>> +	channels[channel].scan_type.sign = 'u';
>> +	/* Real storage bits will change based on the report desc. */
>> +	channels[channel].scan_type.realbits = size * 8;
>> +	/* Maximum size of a sample to capture is u32 */
>> +	channels[channel].scan_type.storagebits = sizeof(u32) * 8;
>> +}
>> +
>> +/* Channel read_raw handler */
>> +static int switch_read_raw(struct iio_dev *indio_dev,
>> +			      struct iio_chan_spec const *chan,
>> +			      int *val, int *val2,
>> +			      long mask)
>> +{
>> +	struct switch_state *switch_state = iio_priv(indio_dev);
>> +	int report_id = -1;
>> +	u32 address;
>> +	int ret;
>> +	int ret_type;
>> +
>> +	*val = 0;
>> +	*val2 = 0;
>> +	switch (mask) {
>> +	case IIO_CHAN_INFO_RAW:
>> +		switch (chan->scan_index) {
>> +		case  CHANNEL_SCAN_INDEX_SWITCH:
>> +			report_id = switch_state->switch_attr.report_id;
>> +			address =
>> +			HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE;
>> +			break;
>> +		default:
>> +			report_id = -1;
>> +			break;
>> +		}
>> +		if (report_id >= 0)
>> +			*val = sensor_hub_input_attr_get_raw_value(
>> +				switch_state->common_attributes.hsdev,
>> +				HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, address,
>> +				report_id);
>> +		else {
>> +			*val = 0;
>> +			return -EINVAL;
>> +		}
>> +		ret_type = IIO_VAL_INT;
>> +		break;
>> +	case IIO_CHAN_INFO_SAMP_FREQ:
>> +		ret = hid_sensor_read_samp_freq_value(
>> +				&switch_state->common_attributes, val, val2);
>> +		ret_type = IIO_VAL_INT_PLUS_MICRO;
>> +		break;
>> +	case IIO_CHAN_INFO_HYSTERESIS:
>> +		ret = hid_sensor_read_raw_hyst_value(
>> +				&switch_state->common_attributes, val, val2);
>> +		ret_type = IIO_VAL_INT_PLUS_MICRO;
>> +		break;
>> +	default:
>> +		ret_type = -EINVAL;
>> +		break;
>> +	}
>> +
>> +	return ret_type;
>> +}
>> +
>> +/* Channel write_raw handler */
>> +static int switch_write_raw(struct iio_dev *indio_dev,
>> +			       struct iio_chan_spec const *chan,
>> +			       int val,
>> +			       int val2,
>> +			       long mask)
>> +{
>> +	struct switch_state *switch_state = iio_priv(indio_dev);
>> +	int ret = 0;
>> +
>> +	switch (mask) {
>> +	case IIO_CHAN_INFO_SAMP_FREQ:
>> +		ret = hid_sensor_write_samp_freq_value(
>> +				&switch_state->common_attributes, val, val2);
>> +		break;
>> +	case IIO_CHAN_INFO_HYSTERESIS:
>> +		ret = hid_sensor_write_raw_hyst_value(
>> +				&switch_state->common_attributes, val, val2);
>> +		break;
>> +	default:
>> +		ret = -EINVAL;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static int switch_write_raw_get_fmt(struct iio_dev *indio_dev,
>> +			       struct iio_chan_spec const *chan,
>> +			       long mask)
>> +{
>> +	return IIO_VAL_INT_PLUS_MICRO;
>> +}
>> +
>> +static const struct iio_info switch_info = {
>> +	.driver_module = THIS_MODULE,
>> +	.read_raw = &switch_read_raw,
>> +	.write_raw = &switch_write_raw,
>> +	.write_raw_get_fmt = &switch_write_raw_get_fmt,
>> +};
>> +
>> +/* Function to push data to buffer */
>> +static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
>> +{
>> +	dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
>> +	iio_push_to_buffers(indio_dev, (u8 *)data);
>> +}
>> +
>> +/* Callback handler to send event after all samples are received and captured */
>> +static int switch_proc_event(struct hid_sensor_hub_device *hsdev,
>> +				unsigned usage_id,
>> +				void *priv)
>> +{
>> +	struct iio_dev *indio_dev = platform_get_drvdata(priv);
>> +	struct switch_state *switch_state = iio_priv(indio_dev);
>> +
>> +	dev_dbg(&indio_dev->dev, "switch_proc_event [%d]\n",
>> +				switch_state->common_attributes.data_ready);
>> +	if (switch_state->common_attributes.data_ready)
>> +		hid_sensor_push_data(indio_dev,
>> +				(u8 *)&switch_state->value,
>> +				sizeof(switch_state->value));
>> +
>> +	return 0;
>> +}
>> +
>> +/* Capture samples in local storage */
>> +static int switch_capture_sample(struct hid_sensor_hub_device *hsdev,
>> +				unsigned usage_id,
>> +				size_t raw_len, char *raw_data,
>> +				void *priv)
>> +{
>> +	struct iio_dev *indio_dev = platform_get_drvdata(priv);
>> +	struct switch_state *switch_state = iio_priv(indio_dev);
>> +	int ret = -EINVAL;
>> +
>> +	switch (usage_id) {
>> +	case HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE:
>> +		switch_state->value = *(u32 *)raw_data;
>> +		ret = 0;
>> +		break;
>> +	default:
>> +		break;
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +/* Parse report which is specific to an usage id*/
>> +static int switch_parse_report(struct platform_device *pdev,
>> +				struct hid_sensor_hub_device *hsdev,
>> +				struct iio_chan_spec *channels,
>> +				unsigned usage_id,
>> +				struct switch_state *st)
>> +{
>> +	int ret;
>> +
>> +	ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
>> +			usage_id,
>> +			HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE,
>> +			&st->switch_attr);
>> +	if (ret < 0)
>> +		return ret;
>> +	switch_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_SWITCH,
>> +					st->switch_attr.size);
>> +
>> +	dev_dbg(&pdev->dev, "switch %x:%x\n", st->switch_attr.index,
>> +			st->switch_attr.report_id);
>> +
>> +	return ret;
>> +}
>> +
>> +/* Function to initialize the processing for usage id */
>> +static int hid_switch_probe(struct platform_device *pdev)
>> +{
>> +	int ret = 0;
>> +	static const char *name = "switch";
>> +	struct iio_dev *indio_dev;
>> +	struct switch_state *switch_state;
>> +	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
>> +	struct iio_chan_spec *channels;
>> +
>> +	indio_dev = iio_device_alloc(sizeof(struct switch_state));
>> +	if (indio_dev == NULL) {
>> +		ret = -ENOMEM;
>> +		goto error_ret;
>> +	}
>> +	platform_set_drvdata(pdev, indio_dev);
>> +
>> +	switch_state = iio_priv(indio_dev);
>> +	switch_state->common_attributes.hsdev = hsdev;
>> +	switch_state->common_attributes.pdev = pdev;
>> +
>> +	ret = hid_sensor_parse_common_attributes(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
>> +					&switch_state->common_attributes);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "failed to setup common attributes\n");
>> +		goto error_free_dev;
>> +	}
>> +
>> +	channels = kmemdup(switch_channels, sizeof(switch_channels), GFP_KERNEL);
>> +	if (!channels) {
>> +		ret = -ENOMEM;
>> +		dev_err(&pdev->dev, "failed to duplicate channels\n");
>> +		goto error_free_dev;
>> +	}
>> +
>> +	ret = switch_parse_report(pdev, hsdev, channels,
>> +				HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, switch_state);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "failed to setup attributes\n");
>> +		goto error_free_dev_mem;
>> +	}
>> +
>> +	indio_dev->channels = channels;
>> +	indio_dev->num_channels =
>> +				ARRAY_SIZE(switch_channels);
>> +	indio_dev->dev.parent = &pdev->dev;
>> +	indio_dev->info = &switch_info;
>> +	indio_dev->name = name;
>> +	indio_dev->modes = INDIO_DIRECT_MODE;
>> +
>> +	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
>> +		NULL, NULL);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
>> +		goto error_free_dev_mem;
>> +	}
>> +	switch_state->common_attributes.data_ready = false;
>> +	ret = hid_sensor_setup_trigger(indio_dev, name,
>> +				&switch_state->common_attributes);
>> +	if (ret < 0) {
>> +		dev_err(&pdev->dev, "trigger setup failed\n");
>> +		goto error_unreg_buffer_funcs;
>> +	}
>> +
>> +	ret = iio_device_register(indio_dev);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "device register failed\n");
>> +		goto error_remove_trigger;
>> +	}
>> +
>> +	switch_state->callbacks.send_event = switch_proc_event;
>> +	switch_state->callbacks.capture_sample = switch_capture_sample;
>> +	switch_state->callbacks.pdev = pdev;
>> +	ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
>> +					&switch_state->callbacks);
>> +	if (ret < 0) {
>> +		dev_err(&pdev->dev, "callback reg failed\n");
>> +		goto error_iio_unreg;
>> +	}
>> +
>> +	return ret;
>> +
>> +error_iio_unreg:
>> +	iio_device_unregister(indio_dev);
>> +error_remove_trigger:
>> +	hid_sensor_remove_trigger(indio_dev);
>> +error_unreg_buffer_funcs:
>> +	iio_triggered_buffer_cleanup(indio_dev);
>> +error_free_dev_mem:
>> +	kfree(indio_dev->channels);
>> +error_free_dev:
>> +	iio_device_free(indio_dev);
>> +error_ret:
>> +	return ret;
>> +}
>> +
>> +/* Function to deinitialize the processing for usage id */
>> +static int hid_switch_remove(struct platform_device *pdev)
>> +{
>> +	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
>> +	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>> +
>> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH);
>> +	iio_device_unregister(indio_dev);
>> +	hid_sensor_remove_trigger(indio_dev);
>> +	iio_triggered_buffer_cleanup(indio_dev);
>> +	kfree(indio_dev->channels);
>> +	iio_device_free(indio_dev);
>> +
>> +	return 0;
>> +}
>> +
>> +static struct platform_driver hid_switch_platform_driver = {
>> +	.driver = {
>> +		.name	= DRIVER_NAME,
>> +		.owner	= THIS_MODULE,
>> +	},
>> +	.probe		= hid_switch_probe,
>> +	.remove		= hid_switch_remove,
>> +};
>> +module_platform_driver(hid_switch_platform_driver);
>> +
>> +MODULE_DESCRIPTION("HID Sensor Boolean Switch");
>> +MODULE_AUTHOR("Alexandre Relange <alexandre@relange.org>");
>> +MODULE_LICENSE("GPL");
>> diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
>> index 6f24446..e469078 100644
>> --- a/include/linux/hid-sensor-ids.h
>> +++ b/include/linux/hid-sensor-ids.h
>> @@ -31,6 +31,10 @@
>>  #define HID_USAGE_SENSOR_ALS					0x200041
>>  #define HID_USAGE_SENSOR_LIGHT_ILLUM				0x2004d1
>>  
>> +/* MECHANICAL: Boolean Switch: (200061) */
>> +#define HID_USAGE_SENSOR_MECHA_BOOL_SWITCH			0x200061
>> +#define HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE		0x200491
>> +
>>  /* Gyro 3D: (200076) */
>>  #define HID_USAGE_SENSOR_GYRO_3D				0x200076
>>  #define HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS			0x200457
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/5] iio: mechanical: new category of sensors
  2013-06-11 14:52 ` [PATCH 2/5] iio: mechanical: new category of sensors Alexandre Relange
@ 2013-07-07 15:29   ` Jonathan Cameron
  2013-07-08 15:01     ` Alexandre Relange
  0 siblings, 1 reply; 16+ messages in thread
From: Jonathan Cameron @ 2013-07-07 15:29 UTC (permalink / raw)
  To: Alexandre Relange; +Cc: Jonathan Cameron, linux-iio

On 06/11/2013 03:52 PM, Alexandre Relange wrote:
> adds the category of mechanical sensors (switches,...)
> 
> Signed-off-by: Alexandre Relange <alexandre@relange.org>
Support like this should be introduced with the first driver, i.e.
in the same patch in my view.

The outstanding issue not answered yet for these is how a mechanical
switch is different from a general purpose input?

> ---
>  drivers/iio/Kconfig             | 1 +
>  drivers/iio/Makefile            | 1 +
>  drivers/iio/mechanical/Kconfig  | 6 ++++++
>  drivers/iio/mechanical/Makefile | 3 +++
>  4 files changed, 11 insertions(+)
>  create mode 100644 drivers/iio/mechanical/Kconfig
>  create mode 100644 drivers/iio/mechanical/Makefile
> 
> diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
> index b2f963b..dbed2f1 100644
> --- a/drivers/iio/Kconfig
> +++ b/drivers/iio/Kconfig
> @@ -70,5 +70,6 @@ source "drivers/iio/gyro/Kconfig"
>  source "drivers/iio/imu/Kconfig"
>  source "drivers/iio/light/Kconfig"
>  source "drivers/iio/magnetometer/Kconfig"
> +source "drivers/iio/mechanical/Kconfig"
>  
>  endif # IIO
> diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
> index a0e8cdd..78ec75b 100644
> --- a/drivers/iio/Makefile
> +++ b/drivers/iio/Makefile
> @@ -21,3 +21,4 @@ obj-y += frequency/
>  obj-y += imu/
>  obj-y += light/
>  obj-y += magnetometer/
> +obj-y += mechanical/
> diff --git a/drivers/iio/mechanical/Kconfig b/drivers/iio/mechanical/Kconfig
> new file mode 100644
> index 0000000..b536fa2
> --- /dev/null
> +++ b/drivers/iio/mechanical/Kconfig
> @@ -0,0 +1,6 @@
> +#
> +# Mechanical sensors
> +#
> +menu "Mechanical sensors"
> +
> +endmenu
> diff --git a/drivers/iio/mechanical/Makefile b/drivers/iio/mechanical/Makefile
> new file mode 100644
> index 0000000..716098f
> --- /dev/null
> +++ b/drivers/iio/mechanical/Makefile
> @@ -0,0 +1,3 @@
> +#
> +# Makefile for IIO Mechanical sensors
> +#
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/5] iio: mechanical: new HID sensor boolean switch
  2013-06-11 14:52 ` [PATCH 4/5] iio: mechanical: new HID sensor boolean switch Alexandre Relange
  2013-06-11 17:13   ` Lars-Peter Clausen
@ 2013-07-07 15:36   ` Jonathan Cameron
  2013-07-08 15:17     ` Alexandre Relange
  2013-07-12 19:34   ` Alexander Holler
  2 siblings, 1 reply; 16+ messages in thread
From: Jonathan Cameron @ 2013-07-07 15:36 UTC (permalink / raw)
  To: Alexandre Relange; +Cc: Jonathan Cameron, linux-iio

On 06/11/2013 03:52 PM, Alexandre Relange wrote:
> Implements the Boolean Switch sensor from the USB sensor usage tables
> http://www.usb.org/developers/hidpage/HUTRR39b.pdf
> 
> This code is based on drivers/iio/light/hid-sensor-als.c
> 
> Signed-off-by: Alexandre Relange <alexandre@relange.org>

Other than the issue of what to call this it mostly looks fine.
But what is hysterisis when applied to a mechanical switch?

> ---
>  drivers/iio/mechanical/Kconfig             |  14 ++
>  drivers/iio/mechanical/Makefile            |   1 +
>  drivers/iio/mechanical/hid-sensor-switch.c | 359 +++++++++++++++++++++++++++++
>  include/linux/hid-sensor-ids.h             |   4 +
>  4 files changed, 378 insertions(+)
>  create mode 100644 drivers/iio/mechanical/hid-sensor-switch.c
> 
> diff --git a/drivers/iio/mechanical/Kconfig b/drivers/iio/mechanical/Kconfig
> index b536fa2..e449588 100644
> --- a/drivers/iio/mechanical/Kconfig
> +++ b/drivers/iio/mechanical/Kconfig
> @@ -3,4 +3,18 @@
>  #
>  menu "Mechanical sensors"
>  
> +config HID_SENSOR_SWITCH
> +	depends on HID_SENSOR_HUB
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
> +	select HID_SENSOR_IIO_COMMON
> +	select HID_SENSOR_IIO_TRIGGER
> +	tristate "HID Boolean Switch"
> +	help
> +	  Say yes here to build support for the HID SENSOR
> +	  Boolean Switch sensor.
> +
> +	  This driver can also be built as a module.  If so, the module
> +	  will be called hid-sensor-switch.
> +
>  endmenu
> diff --git a/drivers/iio/mechanical/Makefile b/drivers/iio/mechanical/Makefile
> index 716098f..30931c5 100644
> --- a/drivers/iio/mechanical/Makefile
> +++ b/drivers/iio/mechanical/Makefile
> @@ -1,3 +1,4 @@
>  #
>  # Makefile for IIO Mechanical sensors
>  #
> +obj-$(CONFIG_HID_SENSOR_SWITCH)	+= hid-sensor-switch.o
> diff --git a/drivers/iio/mechanical/hid-sensor-switch.c b/drivers/iio/mechanical/hid-sensor-switch.c
> new file mode 100644
> index 0000000..7027305
> --- /dev/null
> +++ b/drivers/iio/mechanical/hid-sensor-switch.c
> @@ -0,0 +1,359 @@
> +/*
> + * HID Sensors Driver
> + * Copyright (c) 2012, Intel Corporation.
> + * Copyright (c) 2013, Alexandre Relange
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + */
> +#include <linux/device.h>
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/slab.h>
> +#include <linux/hid-sensor-hub.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
> +#include "../common/hid-sensors/hid-sensor-trigger.h"
> +
> +/*Format: HID-SENSOR-usage_id_in_hex*/
> +/*Usage ID from spec for Boolean-Switch: 0x200061*/
> +#define DRIVER_NAME "HID-SENSOR-200061"
> +
> +#define CHANNEL_SCAN_INDEX_SWITCH 0
> +
> +struct switch_state {
> +	struct hid_sensor_hub_callbacks callbacks;
> +	struct hid_sensor_common common_attributes;
> +	struct hid_sensor_hub_attribute_info switch_attr;
> +	u32 value;
> +};
> +
> +/* Channel definitions */
> +static const struct iio_chan_spec switch_channels[] = {
> +	{
> +		.type = IIO_STATE,
> +		.info_mask_shared_by_type =
> +			BIT(IIO_CHAN_INFO_SAMP_FREQ) |
> +			BIT(IIO_CHAN_INFO_HYSTERESIS),
> +		.scan_index = CHANNEL_SCAN_INDEX_SWITCH,
> +	}
> +};
> +
> +/* Adjust channel real bits based on report descriptor */
> +static void switch_adjust_channel_bit_mask(struct iio_chan_spec *channels,
> +					int channel, int size)
> +{
> +	channels[channel].scan_type.sign = 'u';
> +	/* Real storage bits will change based on the report desc. */
> +	channels[channel].scan_type.realbits = size * 8;
> +	/* Maximum size of a sample to capture is u32 */
> +	channels[channel].scan_type.storagebits = sizeof(u32) * 8;
> +}
> +
> +/* Channel read_raw handler */
> +static int switch_read_raw(struct iio_dev *indio_dev,
> +			      struct iio_chan_spec const *chan,
> +			      int *val, int *val2,
> +			      long mask)
> +{
> +	struct switch_state *switch_state = iio_priv(indio_dev);
> +	int report_id = -1;
> +	u32 address;
> +	int ret;
> +	int ret_type;
> +
> +	*val = 0;
> +	*val2 = 0;
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		switch (chan->scan_index) {
> +		case  CHANNEL_SCAN_INDEX_SWITCH:
> +			report_id = switch_state->switch_attr.report_id;
> +			address =
> +			HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE;
> +			break;
> +		default:
> +			report_id = -1;
> +			break;
> +		}
> +		if (report_id >= 0)
> +			*val = sensor_hub_input_attr_get_raw_value(
> +				switch_state->common_attributes.hsdev,
> +				HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, address,
> +				report_id);
> +		else {
> +			*val = 0;
> +			return -EINVAL;
> +		}
> +		ret_type = IIO_VAL_INT;
> +		break;
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		ret = hid_sensor_read_samp_freq_value(
> +				&switch_state->common_attributes, val, val2);
> +		ret_type = IIO_VAL_INT_PLUS_MICRO;
> +		break;
> +	case IIO_CHAN_INFO_HYSTERESIS:
> +		ret = hid_sensor_read_raw_hyst_value(
> +				&switch_state->common_attributes, val, val2);
> +		ret_type = IIO_VAL_INT_PLUS_MICRO;
> +		break;
> +	default:
> +		ret_type = -EINVAL;
> +		break;
> +	}
> +
> +	return ret_type;
> +}
> +
> +/* Channel write_raw handler */
> +static int switch_write_raw(struct iio_dev *indio_dev,
> +			       struct iio_chan_spec const *chan,
> +			       int val,
> +			       int val2,
> +			       long mask)
> +{
> +	struct switch_state *switch_state = iio_priv(indio_dev);
> +	int ret = 0;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_SAMP_FREQ:
> +		ret = hid_sensor_write_samp_freq_value(
> +				&switch_state->common_attributes, val, val2);
> +		break;
> +	case IIO_CHAN_INFO_HYSTERESIS:
> +		ret = hid_sensor_write_raw_hyst_value(
> +				&switch_state->common_attributes, val, val2);
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static int switch_write_raw_get_fmt(struct iio_dev *indio_dev,
> +			       struct iio_chan_spec const *chan,
> +			       long mask)
> +{
> +	return IIO_VAL_INT_PLUS_MICRO;
> +}
> +
> +static const struct iio_info switch_info = {
> +	.driver_module = THIS_MODULE,
> +	.read_raw = &switch_read_raw,
> +	.write_raw = &switch_write_raw,
> +	.write_raw_get_fmt = &switch_write_raw_get_fmt,
> +};
> +
> +/* Function to push data to buffer */
> +static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
> +{
> +	dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
> +	iio_push_to_buffers(indio_dev, (u8 *)data);
> +}
> +
> +/* Callback handler to send event after all samples are received and captured */
> +static int switch_proc_event(struct hid_sensor_hub_device *hsdev,
> +				unsigned usage_id,
> +				void *priv)
> +{
> +	struct iio_dev *indio_dev = platform_get_drvdata(priv);
> +	struct switch_state *switch_state = iio_priv(indio_dev);
> +
> +	dev_dbg(&indio_dev->dev, "switch_proc_event [%d]\n",
> +				switch_state->common_attributes.data_ready);
> +	if (switch_state->common_attributes.data_ready)
> +		hid_sensor_push_data(indio_dev,
> +				(u8 *)&switch_state->value,
> +				sizeof(switch_state->value));
> +
> +	return 0;
> +}
> +
> +/* Capture samples in local storage */
> +static int switch_capture_sample(struct hid_sensor_hub_device *hsdev,
> +				unsigned usage_id,
> +				size_t raw_len, char *raw_data,
> +				void *priv)
> +{
> +	struct iio_dev *indio_dev = platform_get_drvdata(priv);
> +	struct switch_state *switch_state = iio_priv(indio_dev);
> +	int ret = -EINVAL;
> +
> +	switch (usage_id) {
> +	case HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE:
> +		switch_state->value = *(u32 *)raw_data;
> +		ret = 0;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +/* Parse report which is specific to an usage id*/
> +static int switch_parse_report(struct platform_device *pdev,
> +				struct hid_sensor_hub_device *hsdev,
> +				struct iio_chan_spec *channels,
> +				unsigned usage_id,
> +				struct switch_state *st)
> +{
> +	int ret;
> +
> +	ret = sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT,
> +			usage_id,
> +			HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE,
> +			&st->switch_attr);
> +	if (ret < 0)
> +		return ret;
> +	switch_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_SWITCH,
> +					st->switch_attr.size);
> +
> +	dev_dbg(&pdev->dev, "switch %x:%x\n", st->switch_attr.index,
> +			st->switch_attr.report_id);
> +
> +	return ret;
> +}
> +
> +/* Function to initialize the processing for usage id */
> +static int hid_switch_probe(struct platform_device *pdev)
> +{
> +	int ret = 0;
> +	static const char *name = "switch";
> +	struct iio_dev *indio_dev;
> +	struct switch_state *switch_state;
> +	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
> +	struct iio_chan_spec *channels;
> +
> +	indio_dev = iio_device_alloc(sizeof(struct switch_state));
> +	if (indio_dev == NULL) {
> +		ret = -ENOMEM;
> +		goto error_ret;
> +	}
> +	platform_set_drvdata(pdev, indio_dev);
> +
> +	switch_state = iio_priv(indio_dev);
> +	switch_state->common_attributes.hsdev = hsdev;
> +	switch_state->common_attributes.pdev = pdev;
> +
> +	ret = hid_sensor_parse_common_attributes(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
> +					&switch_state->common_attributes);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to setup common attributes\n");
> +		goto error_free_dev;
> +	}
> +
> +	channels = kmemdup(switch_channels, sizeof(switch_channels), GFP_KERNEL);
> +	if (!channels) {
> +		ret = -ENOMEM;
> +		dev_err(&pdev->dev, "failed to duplicate channels\n");
> +		goto error_free_dev;
> +	}
> +
> +	ret = switch_parse_report(pdev, hsdev, channels,
> +				HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, switch_state);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to setup attributes\n");
> +		goto error_free_dev_mem;
> +	}
> +
> +	indio_dev->channels = channels;
> +	indio_dev->num_channels =
> +				ARRAY_SIZE(switch_channels);
> +	indio_dev->dev.parent = &pdev->dev;
> +	indio_dev->info = &switch_info;
> +	indio_dev->name = name;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +
> +	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> +		NULL, NULL);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to initialize trigger buffer\n");
> +		goto error_free_dev_mem;
> +	}
> +	switch_state->common_attributes.data_ready = false;
> +	ret = hid_sensor_setup_trigger(indio_dev, name,
> +				&switch_state->common_attributes);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "trigger setup failed\n");
> +		goto error_unreg_buffer_funcs;
> +	}
> +
> +	ret = iio_device_register(indio_dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "device register failed\n");
> +		goto error_remove_trigger;
> +	}
> +
> +	switch_state->callbacks.send_event = switch_proc_event;
> +	switch_state->callbacks.capture_sample = switch_capture_sample;
> +	switch_state->callbacks.pdev = pdev;
> +	ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
> +					&switch_state->callbacks);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "callback reg failed\n");
> +		goto error_iio_unreg;
> +	}
> +
> +	return ret;
> +
> +error_iio_unreg:
> +	iio_device_unregister(indio_dev);
> +error_remove_trigger:
> +	hid_sensor_remove_trigger(indio_dev);
> +error_unreg_buffer_funcs:
> +	iio_triggered_buffer_cleanup(indio_dev);
> +error_free_dev_mem:
> +	kfree(indio_dev->channels);
> +error_free_dev:
> +	iio_device_free(indio_dev);
> +error_ret:
> +	return ret;
> +}
> +
> +/* Function to deinitialize the processing for usage id */
> +static int hid_switch_remove(struct platform_device *pdev)
> +{
> +	struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
> +	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> +	sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_MECHA_BOOL_SWITCH);
> +	iio_device_unregister(indio_dev);
> +	hid_sensor_remove_trigger(indio_dev);
> +	iio_triggered_buffer_cleanup(indio_dev);
> +	kfree(indio_dev->channels);
> +	iio_device_free(indio_dev);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver hid_switch_platform_driver = {
> +	.driver = {
> +		.name	= DRIVER_NAME,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= hid_switch_probe,
> +	.remove		= hid_switch_remove,
> +};
> +module_platform_driver(hid_switch_platform_driver);
> +
> +MODULE_DESCRIPTION("HID Sensor Boolean Switch");
> +MODULE_AUTHOR("Alexandre Relange <alexandre@relange.org>");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
> index 6f24446..e469078 100644
> --- a/include/linux/hid-sensor-ids.h
> +++ b/include/linux/hid-sensor-ids.h
> @@ -31,6 +31,10 @@
>  #define HID_USAGE_SENSOR_ALS					0x200041
>  #define HID_USAGE_SENSOR_LIGHT_ILLUM				0x2004d1
>  
> +/* MECHANICAL: Boolean Switch: (200061) */
> +#define HID_USAGE_SENSOR_MECHA_BOOL_SWITCH			0x200061
> +#define HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE		0x200491
> +
>  /* Gyro 3D: (200076) */
>  #define HID_USAGE_SENSOR_GYRO_3D				0x200076
>  #define HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS			0x200457
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/5] iio: mechanical: new category of sensors
  2013-07-07 15:29   ` Jonathan Cameron
@ 2013-07-08 15:01     ` Alexandre Relange
  2013-07-09 18:05       ` Jonathan Cameron
  0 siblings, 1 reply; 16+ messages in thread
From: Alexandre Relange @ 2013-07-08 15:01 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: Jonathan Cameron, linux-iio

Le 07/07/2013 17:29, Jonathan Cameron a écrit :
> On 06/11/2013 03:52 PM, Alexandre Relange wrote:
>> adds the category of mechanical sensors (switches,...)
>>
>> Signed-off-by: Alexandre Relange <alexandre@relange.org>
> Support like this should be introduced with the first driver, i.e. in
> the same patch in my view.
>
> The outstanding issue not answered yet for these is how a mechanical
> switch is different from a general purpose input?

Sorry not to have taken the time to solve this earlier.
Moving this driver in "gpio" is fine for me.
But I finally do not really like to create this one-driver-catergory for
some reasons:
- we should be more confident that category will be useful for other drivers
- hid-sensors-switch might not stay for long. I guess our maintainer
will not like to have one hid-sensor driver for each one of the hundred
of sensor classes, especially since this architecture is not fully
compliant. I will send details on this issue later.
Unless you think this simple driver is a good reason to create a 'gpio'
category that will be useful for other drivers, I suggest to give it up
and I will work on the architecture issue as soon as I have the time to
do it, but it seems it will not be for the 3.11...

> 
>> --- drivers/iio/Kconfig             | 1 + drivers/iio/Makefile
>> | 1 + drivers/iio/mechanical/Kconfig  | 6 ++++++
>> drivers/iio/mechanical/Makefile | 3 +++ 4 files changed, 11
>> insertions(+) create mode 100644 drivers/iio/mechanical/Kconfig
>> create mode 100644 drivers/iio/mechanical/Makefile
>>
>> diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index
>> b2f963b..dbed2f1 100644 --- a/drivers/iio/Kconfig +++
>> b/drivers/iio/Kconfig @@ -70,5 +70,6 @@ source
>> "drivers/iio/gyro/Kconfig" source "drivers/iio/imu/Kconfig" source
>> "drivers/iio/light/Kconfig" source
>> "drivers/iio/magnetometer/Kconfig" +source
>> "drivers/iio/mechanical/Kconfig"
>>
>> endif # IIO diff --git a/drivers/iio/Makefile
>> b/drivers/iio/Makefile index a0e8cdd..78ec75b 100644 ---
>> a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -21,3 +21,4 @@
>> obj-y += frequency/ obj-y += imu/ obj-y += light/ obj-y +=
>> magnetometer/ +obj-y += mechanical/ diff --git
>> a/drivers/iio/mechanical/Kconfig b/drivers/iio/mechanical/Kconfig
>> new file mode 100644 index 0000000..b536fa2 --- /dev/null +++
>> b/drivers/iio/mechanical/Kconfig @@ -0,0 +1,6 @@ +# +# Mechanical
>> sensors +# +menu "Mechanical sensors" + +endmenu diff --git
>> a/drivers/iio/mechanical/Makefile
>> b/drivers/iio/mechanical/Makefile new file mode 100644 index
>> 0000000..716098f --- /dev/null +++
>> b/drivers/iio/mechanical/Makefile @@ -0,0 +1,3 @@ +# +# Makefile
>> for IIO Mechanical sensors +#
>>



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/5] iio: mechanical: new HID sensor boolean switch
  2013-07-07 15:36   ` Jonathan Cameron
@ 2013-07-08 15:17     ` Alexandre Relange
  2013-07-09 18:06       ` Jonathan Cameron
  0 siblings, 1 reply; 16+ messages in thread
From: Alexandre Relange @ 2013-07-08 15:17 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: Jonathan Cameron, linux-iio

Le 07/07/2013 17:36, Jonathan Cameron a écrit :
> On 06/11/2013 03:52 PM, Alexandre Relange wrote:
>> Implements the Boolean Switch sensor from the USB sensor usage
>> tables http://www.usb.org/developers/hidpage/HUTRR39b.pdf
>>
>> This code is based on drivers/iio/light/hid-sensor-als.c
>>
>> Signed-off-by: Alexandre Relange <alexandre@relange.org>
>
> Other than the issue of what to call this it mostly looks fine. But
> what is hysterisis when applied to a mechanical switch?

Unfortunately, if the use is explicit (for reference, p124 generic field
SENSITIVITY_ABS) the use case is NOT explicit. This is a generic field
that is valid for every hid-sensor devices. Although, without more
details in the standard, the behavior of this field will be vendor specific.
As an example, I guess it could be used to set what are 'on' and 'off'
states of a switch accord to the pressure on a button.

> 
>> --- drivers/iio/mechanical/Kconfig             |  14 ++
>> drivers/iio/mechanical/Makefile            |   1 +
>> drivers/iio/mechanical/hid-sensor-switch.c | 359
>> +++++++++++++++++++++++++++++ include/linux/hid-sensor-ids.h
>> |   4 + 4 files changed, 378 insertions(+) create mode 100644
>> drivers/iio/mechanical/hid-sensor-switch.c
>>
>> diff --git a/drivers/iio/mechanical/Kconfig
>> b/drivers/iio/mechanical/Kconfig index b536fa2..e449588 100644 ---
>> a/drivers/iio/mechanical/Kconfig +++
>> b/drivers/iio/mechanical/Kconfig @@ -3,4 +3,18 @@ # menu
>> "Mechanical sensors"
>>
>> +config HID_SENSOR_SWITCH +    depends on HID_SENSOR_HUB +    select
>> IIO_BUFFER +    select IIO_TRIGGERED_BUFFER +    select
>> HID_SENSOR_IIO_COMMON +    select HID_SENSOR_IIO_TRIGGER +    tristate
>> "HID Boolean Switch" +    help +      Say yes here to build support for
>> the HID SENSOR +      Boolean Switch sensor. + +      This driver can
>> also be built as a module.  If so, the module +      will be called
>> hid-sensor-switch. + endmenu diff --git
>> a/drivers/iio/mechanical/Makefile
>> b/drivers/iio/mechanical/Makefile index 716098f..30931c5 100644 ---
>> a/drivers/iio/mechanical/Makefile +++
>> b/drivers/iio/mechanical/Makefile @@ -1,3 +1,4 @@ # # Makefile for
>> IIO Mechanical sensors # +obj-$(CONFIG_HID_SENSOR_SWITCH)    +=
>> hid-sensor-switch.o diff --git
>> a/drivers/iio/mechanical/hid-sensor-switch.c
>> b/drivers/iio/mechanical/hid-sensor-switch.c new file mode 100644
>> index 0000000..7027305 --- /dev/null +++
>> b/drivers/iio/mechanical/hid-sensor-switch.c @@ -0,0 +1,359 @@ +/*
>> + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. +
>> * Copyright (c) 2013, Alexandre Relange + * + * This program is
>> free software; you can redistribute it and/or modify it + * under
>> the terms and conditions of the GNU General Public License, + *
>> version 2, as published by the Free Software Foundation. + * + *
>> This program is distributed in the hope it will be useful, but
>> WITHOUT + * ANY WARRANTY; without even the implied warranty of
>> MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the
>> GNU General Public License for + * more details. + * + * You should
>> have received a copy of the GNU General Public License along with +
>> * this program; if not, write to the Free Software Foundation,
>> Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
>> + * + */ +#include <linux/device.h> +#include
>> <linux/platform_device.h> +#include <linux/module.h> +#include
>> <linux/interrupt.h> +#include <linux/irq.h> +#include
>> <linux/slab.h> +#include <linux/hid-sensor-hub.h> +#include
>> <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include
>> <linux/iio/buffer.h> +#include <linux/iio/trigger_consumer.h>
>> +#include <linux/iio/triggered_buffer.h> +#include
>> "../common/hid-sensors/hid-sensor-trigger.h" + +/*Format:
>> HID-SENSOR-usage_id_in_hex*/ +/*Usage ID from spec for
>> Boolean-Switch: 0x200061*/ +#define DRIVER_NAME
>> "HID-SENSOR-200061" + +#define CHANNEL_SCAN_INDEX_SWITCH 0 +
>> +struct switch_state { +    struct hid_sensor_hub_callbacks
>> callbacks; +    struct hid_sensor_common common_attributes; +    struct
>> hid_sensor_hub_attribute_info switch_attr; +    u32 value; +}; + +/*
>> Channel definitions */ +static const struct iio_chan_spec
>> switch_channels[] = { +    { +        .type = IIO_STATE, +
>> .info_mask_shared_by_type = +            BIT(IIO_CHAN_INFO_SAMP_FREQ) | +
>> BIT(IIO_CHAN_INFO_HYSTERESIS), +        .scan_index =
>> CHANNEL_SCAN_INDEX_SWITCH, +    } +}; + +/* Adjust channel real bits
>> based on report descriptor */ +static void
>> switch_adjust_channel_bit_mask(struct iio_chan_spec *channels, +
>> int channel, int size) +{ +    channels[channel].scan_type.sign =
>> 'u'; +    /* Real storage bits will change based on the report desc.
>> */ +    channels[channel].scan_type.realbits = size * 8; +    /* Maximum
>> size of a sample to capture is u32 */ +
>> channels[channel].scan_type.storagebits = sizeof(u32) * 8; +} + +/*
>> Channel read_raw handler */ +static int switch_read_raw(struct
>> iio_dev *indio_dev, +                  struct iio_chan_spec const
*chan, +
>> int *val, int *val2, +                  long mask) +{ +    struct
switch_state
>> *switch_state = iio_priv(indio_dev); +    int report_id = -1; +    u32
>> address; +    int ret; +    int ret_type; + +    *val = 0; +    *val2
= 0; +
>> switch (mask) { +    case IIO_CHAN_INFO_RAW: +        switch
>> (chan->scan_index) { +        case  CHANNEL_SCAN_INDEX_SWITCH: +
>> report_id = switch_state->switch_attr.report_id; +            address = +
>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE; +            break; +   
    default: +
>> report_id = -1; +            break; +        } +        if (report_id
>= 0) +            *val =
>> sensor_hub_input_attr_get_raw_value( +
>> switch_state->common_attributes.hsdev, +
>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, address, +               
report_id); +
>> else { +            *val = 0; +            return -EINVAL; +        }
+        ret_type =
>> IIO_VAL_INT; +        break; +    case IIO_CHAN_INFO_SAMP_FREQ: +   
    ret =
>> hid_sensor_read_samp_freq_value( +
>> &switch_state->common_attributes, val, val2); +        ret_type =
>> IIO_VAL_INT_PLUS_MICRO; +        break; +    case
IIO_CHAN_INFO_HYSTERESIS:
>> +        ret = hid_sensor_read_raw_hyst_value( +
>> &switch_state->common_attributes, val, val2); +        ret_type =
>> IIO_VAL_INT_PLUS_MICRO; +        break; +    default: +        ret_type =
>> -EINVAL; +        break; +    } + +    return ret_type; +} + +/* Channel
>> write_raw handler */ +static int switch_write_raw(struct iio_dev
>> *indio_dev, +                   struct iio_chan_spec const *chan, +
>> int val, +                   int val2, +                   long mask)
+{ +    struct
>> switch_state *switch_state = iio_priv(indio_dev); +    int ret = 0; +
>> +    switch (mask) { +    case IIO_CHAN_INFO_SAMP_FREQ: +        ret =
>> hid_sensor_write_samp_freq_value( +
>> &switch_state->common_attributes, val, val2); +        break; +    case
>> IIO_CHAN_INFO_HYSTERESIS: +        ret =
>> hid_sensor_write_raw_hyst_value( +
>> &switch_state->common_attributes, val, val2); +        break; +   
default:
>> +        ret = -EINVAL; +    } + +    return ret; +} + +static int
>> switch_write_raw_get_fmt(struct iio_dev *indio_dev, +
>> struct iio_chan_spec const *chan, +                   long mask) +{
+    return
>> IIO_VAL_INT_PLUS_MICRO; +} + +static const struct iio_info
>> switch_info = { +    .driver_module = THIS_MODULE, +    .read_raw =
>> &switch_read_raw, +    .write_raw = &switch_write_raw, +
>> .write_raw_get_fmt = &switch_write_raw_get_fmt, +}; + +/* Function
>> to push data to buffer */ +static void hid_sensor_push_data(struct
>> iio_dev *indio_dev, u8 *data, int len) +{ +
>> dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); +
>> iio_push_to_buffers(indio_dev, (u8 *)data); +} + +/* Callback
>> handler to send event after all samples are received and captured
>> */ +static int switch_proc_event(struct hid_sensor_hub_device
>> *hsdev, +                unsigned usage_id, +                void
*priv) +{ +    struct
>> iio_dev *indio_dev = platform_get_drvdata(priv); +    struct
>> switch_state *switch_state = iio_priv(indio_dev); + +
>> dev_dbg(&indio_dev->dev, "switch_proc_event [%d]\n", +
>> switch_state->common_attributes.data_ready); +    if
>> (switch_state->common_attributes.data_ready) +
>> hid_sensor_push_data(indio_dev, +                (u8
*)&switch_state->value, +
>> sizeof(switch_state->value)); + +    return 0; +} + +/* Capture
>> samples in local storage */ +static int
>> switch_capture_sample(struct hid_sensor_hub_device *hsdev, +
>> unsigned usage_id, +                size_t raw_len, char *raw_data,
+                void
>> *priv) +{ +    struct iio_dev *indio_dev =
>> platform_get_drvdata(priv); +    struct switch_state *switch_state =
>> iio_priv(indio_dev); +    int ret = -EINVAL; + +    switch (usage_id) { +
>> case HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE: +
>> switch_state->value = *(u32 *)raw_data; +        ret = 0; +       
break; +
>> default: +        break; +    } + +    return ret; +} + +/* Parse
report which
>> is specific to an usage id*/ +static int switch_parse_report(struct
>> platform_device *pdev, +                struct hid_sensor_hub_device
*hsdev, +
>> struct iio_chan_spec *channels, +                unsigned usage_id,
+                struct
>> switch_state *st) +{ +    int ret; + +    ret =
>> sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT, +
>> usage_id, +            HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE, +
>> &st->switch_attr); +    if (ret < 0) +        return ret; +
>> switch_adjust_channel_bit_mask(channels,
>> CHANNEL_SCAN_INDEX_SWITCH, +                   
st->switch_attr.size); + +
>> dev_dbg(&pdev->dev, "switch %x:%x\n", st->switch_attr.index, +
>> st->switch_attr.report_id); + +    return ret; +} + +/* Function to
>> initialize the processing for usage id */ +static int
>> hid_switch_probe(struct platform_device *pdev) +{ +    int ret = 0; +
>> static const char *name = "switch"; +    struct iio_dev *indio_dev; +
>> struct switch_state *switch_state; +    struct hid_sensor_hub_device
>> *hsdev = pdev->dev.platform_data; +    struct iio_chan_spec
>> *channels; + +    indio_dev = iio_device_alloc(sizeof(struct
>> switch_state)); +    if (indio_dev == NULL) { +        ret = -ENOMEM; +
>> goto error_ret; +    } +    platform_set_drvdata(pdev, indio_dev); + +
>> switch_state = iio_priv(indio_dev); +
>> switch_state->common_attributes.hsdev = hsdev; +
>> switch_state->common_attributes.pdev = pdev; + +    ret =
>> hid_sensor_parse_common_attributes(hsdev,
>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, +
>> &switch_state->common_attributes); +    if (ret) { +
>> dev_err(&pdev->dev, "failed to setup common attributes\n"); +        goto
>> error_free_dev; +    } + +    channels = kmemdup(switch_channels,
>> sizeof(switch_channels), GFP_KERNEL); +    if (!channels) { +       
ret =
>> -ENOMEM; +        dev_err(&pdev->dev, "failed to duplicate channels\n");
>> +        goto error_free_dev; +    } + +    ret =
switch_parse_report(pdev,
>> hsdev, channels, +                HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
>> switch_state); +    if (ret) { +        dev_err(&pdev->dev, "failed
to setup
>> attributes\n"); +        goto error_free_dev_mem; +    } + +
>> indio_dev->channels = channels; +    indio_dev->num_channels = +
>> ARRAY_SIZE(switch_channels); +    indio_dev->dev.parent = &pdev->dev;
>> +    indio_dev->info = &switch_info; +    indio_dev->name = name; +
>> indio_dev->modes = INDIO_DIRECT_MODE; + +    ret =
>> iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, +
>> NULL, NULL); +    if (ret) { +        dev_err(&pdev->dev, "failed to
>> initialize trigger buffer\n"); +        goto error_free_dev_mem; +    } +
>> switch_state->common_attributes.data_ready = false; +    ret =
>> hid_sensor_setup_trigger(indio_dev, name, +
>> &switch_state->common_attributes); +    if (ret < 0) { +
>> dev_err(&pdev->dev, "trigger setup failed\n"); +        goto
>> error_unreg_buffer_funcs; +    } + +    ret =
>> iio_device_register(indio_dev); +    if (ret) { +       
dev_err(&pdev->dev,
>> "device register failed\n"); +        goto error_remove_trigger; +   
} + +
>> switch_state->callbacks.send_event = switch_proc_event; +
>> switch_state->callbacks.capture_sample = switch_capture_sample; +
>> switch_state->callbacks.pdev = pdev; +    ret =
>> sensor_hub_register_callback(hsdev,
>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, +
>> &switch_state->callbacks); +    if (ret < 0) { +       
dev_err(&pdev->dev,
>> "callback reg failed\n"); +        goto error_iio_unreg; +    } +
+    return
>> ret; + +error_iio_unreg: +    iio_device_unregister(indio_dev);
>> +error_remove_trigger: +    hid_sensor_remove_trigger(indio_dev);
>> +error_unreg_buffer_funcs: +
>> iio_triggered_buffer_cleanup(indio_dev); +error_free_dev_mem: +
>> kfree(indio_dev->channels); +error_free_dev: +
>> iio_device_free(indio_dev); +error_ret: +    return ret; +} + +/*
>> Function to deinitialize the processing for usage id */ +static int
>> hid_switch_remove(struct platform_device *pdev) +{ +    struct
>> hid_sensor_hub_device *hsdev = pdev->dev.platform_data; +    struct
>> iio_dev *indio_dev = platform_get_drvdata(pdev); + +
>> sensor_hub_remove_callback(hsdev,
>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH); +
>> iio_device_unregister(indio_dev); +
>> hid_sensor_remove_trigger(indio_dev); +
>> iio_triggered_buffer_cleanup(indio_dev); +
>> kfree(indio_dev->channels); +    iio_device_free(indio_dev); + +
>> return 0; +} + +static struct platform_driver
>> hid_switch_platform_driver = { +    .driver = { +        .name    =
>> DRIVER_NAME, +        .owner    = THIS_MODULE, +    }, +    .probe   
    =
>> hid_switch_probe, +    .remove        = hid_switch_remove, +};
>> +module_platform_driver(hid_switch_platform_driver); +
>> +MODULE_DESCRIPTION("HID Sensor Boolean Switch");
>> +MODULE_AUTHOR("Alexandre Relange <alexandre@relange.org>");
>> +MODULE_LICENSE("GPL"); diff --git a/include/linux/hid-sensor-ids.h
>> b/include/linux/hid-sensor-ids.h index 6f24446..e469078 100644 ---
>> a/include/linux/hid-sensor-ids.h +++
>> b/include/linux/hid-sensor-ids.h @@ -31,6 +31,10 @@ #define
>> HID_USAGE_SENSOR_ALS                    0x200041 #define
>> HID_USAGE_SENSOR_LIGHT_ILLUM                0x2004d1
>>
>> +/* MECHANICAL: Boolean Switch: (200061) */ +#define
>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH            0x200061 +#define
>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE        0x200491 + /* Gyro 3D:
>> (200076) */ #define HID_USAGE_SENSOR_GYRO_3D                0x200076
#define
>> HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS            0x200457
>>



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/5] iio: mechanical: new category of sensors
  2013-07-08 15:01     ` Alexandre Relange
@ 2013-07-09 18:05       ` Jonathan Cameron
  0 siblings, 0 replies; 16+ messages in thread
From: Jonathan Cameron @ 2013-07-09 18:05 UTC (permalink / raw)
  To: Alexandre Relange; +Cc: Jonathan Cameron, linux-iio

On 07/08/2013 04:01 PM, Alexandre Relange wrote:
> Le 07/07/2013 17:29, Jonathan Cameron a écrit :
>> On 06/11/2013 03:52 PM, Alexandre Relange wrote:
>>> adds the category of mechanical sensors (switches,...)
>>>
>>> Signed-off-by: Alexandre Relange <alexandre@relange.org>
>> Support like this should be introduced with the first driver, i.e. in
>> the same patch in my view.
>>
>> The outstanding issue not answered yet for these is how a mechanical
>> switch is different from a general purpose input?
> 
> Sorry not to have taken the time to solve this earlier.
> Moving this driver in "gpio" is fine for me.

> But I finally do not really like to create this one-driver-catergory for
> some reasons:
> - we should be more confident that category will be useful for other drivers
Whilst we might not have any straight gpio devices, there are plenty of compound
devices out there with GPIs alongside other forms of sensor.  Right now I don't
think we have any where it is truely sampled alongside the main channels, but
this is common on data capture cards so is sure to be integrated on some parts.

> - hid-sensors-switch might not stay for long. I guess our maintainer
> will not like to have one hid-sensor driver for each one of the hundred
> of sensor classes, especially since this architecture is not fully
> compliant. I will send details on this issue later.
> Unless you think this simple driver is a good reason to create a 'gpio'
> category that will be useful for other drivers, I suggest to give it up
> and I will work on the architecture issue as soon as I have the time to
> do it, but it seems it will not be for the 3.11...

Up to you either way.
> 
>>
>>> --- drivers/iio/Kconfig             | 1 + drivers/iio/Makefile
>>> | 1 + drivers/iio/mechanical/Kconfig  | 6 ++++++
>>> drivers/iio/mechanical/Makefile | 3 +++ 4 files changed, 11
>>> insertions(+) create mode 100644 drivers/iio/mechanical/Kconfig
>>> create mode 100644 drivers/iio/mechanical/Makefile
>>>
>>> diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index
>>> b2f963b..dbed2f1 100644 --- a/drivers/iio/Kconfig +++
>>> b/drivers/iio/Kconfig @@ -70,5 +70,6 @@ source
>>> "drivers/iio/gyro/Kconfig" source "drivers/iio/imu/Kconfig" source
>>> "drivers/iio/light/Kconfig" source
>>> "drivers/iio/magnetometer/Kconfig" +source
>>> "drivers/iio/mechanical/Kconfig"
>>>
>>> endif # IIO diff --git a/drivers/iio/Makefile
>>> b/drivers/iio/Makefile index a0e8cdd..78ec75b 100644 ---
>>> a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -21,3 +21,4 @@
>>> obj-y += frequency/ obj-y += imu/ obj-y += light/ obj-y +=
>>> magnetometer/ +obj-y += mechanical/ diff --git
>>> a/drivers/iio/mechanical/Kconfig b/drivers/iio/mechanical/Kconfig
>>> new file mode 100644 index 0000000..b536fa2 --- /dev/null +++
>>> b/drivers/iio/mechanical/Kconfig @@ -0,0 +1,6 @@ +# +# Mechanical
>>> sensors +# +menu "Mechanical sensors" + +endmenu diff --git
>>> a/drivers/iio/mechanical/Makefile
>>> b/drivers/iio/mechanical/Makefile new file mode 100644 index
>>> 0000000..716098f --- /dev/null +++
>>> b/drivers/iio/mechanical/Makefile @@ -0,0 +1,3 @@ +# +# Makefile
>>> for IIO Mechanical sensors +#
>>>
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/5] iio: mechanical: new HID sensor boolean switch
  2013-07-08 15:17     ` Alexandre Relange
@ 2013-07-09 18:06       ` Jonathan Cameron
  0 siblings, 0 replies; 16+ messages in thread
From: Jonathan Cameron @ 2013-07-09 18:06 UTC (permalink / raw)
  To: Alexandre Relange; +Cc: Jonathan Cameron, linux-iio

On 07/08/2013 04:17 PM, Alexandre Relange wrote:
> Le 07/07/2013 17:36, Jonathan Cameron a écrit :
>> On 06/11/2013 03:52 PM, Alexandre Relange wrote:
>>> Implements the Boolean Switch sensor from the USB sensor usage
>>> tables http://www.usb.org/developers/hidpage/HUTRR39b.pdf
>>>
>>> This code is based on drivers/iio/light/hid-sensor-als.c
>>>
>>> Signed-off-by: Alexandre Relange <alexandre@relange.org>
>>
>> Other than the issue of what to call this it mostly looks fine. But
>> what is hysterisis when applied to a mechanical switch?
> 
> Unfortunately, if the use is explicit (for reference, p124 generic field
> SENSITIVITY_ABS) the use case is NOT explicit. This is a generic field
> that is valid for every hid-sensor devices. Although, without more
> details in the standard, the behavior of this field will be vendor specific.
> As an example, I guess it could be used to set what are 'on' and 'off'
> states of a switch accord to the pressure on a button.
The wonders of over generalization.  This is downright silly and we
would want any thing like pressure on a button to be explicit, not
hidden behind a random term that really does not apply.

> 
>>
>>> --- drivers/iio/mechanical/Kconfig             |  14 ++
>>> drivers/iio/mechanical/Makefile            |   1 +
>>> drivers/iio/mechanical/hid-sensor-switch.c | 359
>>> +++++++++++++++++++++++++++++ include/linux/hid-sensor-ids.h
>>> |   4 + 4 files changed, 378 insertions(+) create mode 100644
>>> drivers/iio/mechanical/hid-sensor-switch.c
>>>
>>> diff --git a/drivers/iio/mechanical/Kconfig
>>> b/drivers/iio/mechanical/Kconfig index b536fa2..e449588 100644 ---
>>> a/drivers/iio/mechanical/Kconfig +++
>>> b/drivers/iio/mechanical/Kconfig @@ -3,4 +3,18 @@ # menu
>>> "Mechanical sensors"
>>>
>>> +config HID_SENSOR_SWITCH +    depends on HID_SENSOR_HUB +    select
>>> IIO_BUFFER +    select IIO_TRIGGERED_BUFFER +    select
>>> HID_SENSOR_IIO_COMMON +    select HID_SENSOR_IIO_TRIGGER +    tristate
>>> "HID Boolean Switch" +    help +      Say yes here to build support for
>>> the HID SENSOR +      Boolean Switch sensor. + +      This driver can
>>> also be built as a module.  If so, the module +      will be called
>>> hid-sensor-switch. + endmenu diff --git
>>> a/drivers/iio/mechanical/Makefile
>>> b/drivers/iio/mechanical/Makefile index 716098f..30931c5 100644 ---
>>> a/drivers/iio/mechanical/Makefile +++
>>> b/drivers/iio/mechanical/Makefile @@ -1,3 +1,4 @@ # # Makefile for
>>> IIO Mechanical sensors # +obj-$(CONFIG_HID_SENSOR_SWITCH)    +=
>>> hid-sensor-switch.o diff --git
>>> a/drivers/iio/mechanical/hid-sensor-switch.c
>>> b/drivers/iio/mechanical/hid-sensor-switch.c new file mode 100644
>>> index 0000000..7027305 --- /dev/null +++
>>> b/drivers/iio/mechanical/hid-sensor-switch.c @@ -0,0 +1,359 @@ +/*
>>> + * HID Sensors Driver + * Copyright (c) 2012, Intel Corporation. +
>>> * Copyright (c) 2013, Alexandre Relange + * + * This program is
>>> free software; you can redistribute it and/or modify it + * under
>>> the terms and conditions of the GNU General Public License, + *
>>> version 2, as published by the Free Software Foundation. + * + *
>>> This program is distributed in the hope it will be useful, but
>>> WITHOUT + * ANY WARRANTY; without even the implied warranty of
>>> MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> GNU General Public License for + * more details. + * + * You should
>>> have received a copy of the GNU General Public License along with +
>>> * this program; if not, write to the Free Software Foundation,
>>> Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
>>> + * + */ +#include <linux/device.h> +#include
>>> <linux/platform_device.h> +#include <linux/module.h> +#include
>>> <linux/interrupt.h> +#include <linux/irq.h> +#include
>>> <linux/slab.h> +#include <linux/hid-sensor-hub.h> +#include
>>> <linux/iio/iio.h> +#include <linux/iio/sysfs.h> +#include
>>> <linux/iio/buffer.h> +#include <linux/iio/trigger_consumer.h>
>>> +#include <linux/iio/triggered_buffer.h> +#include
>>> "../common/hid-sensors/hid-sensor-trigger.h" + +/*Format:
>>> HID-SENSOR-usage_id_in_hex*/ +/*Usage ID from spec for
>>> Boolean-Switch: 0x200061*/ +#define DRIVER_NAME
>>> "HID-SENSOR-200061" + +#define CHANNEL_SCAN_INDEX_SWITCH 0 +
>>> +struct switch_state { +    struct hid_sensor_hub_callbacks
>>> callbacks; +    struct hid_sensor_common common_attributes; +    struct
>>> hid_sensor_hub_attribute_info switch_attr; +    u32 value; +}; + +/*
>>> Channel definitions */ +static const struct iio_chan_spec
>>> switch_channels[] = { +    { +        .type = IIO_STATE, +
>>> .info_mask_shared_by_type = +            BIT(IIO_CHAN_INFO_SAMP_FREQ) | +
>>> BIT(IIO_CHAN_INFO_HYSTERESIS), +        .scan_index =
>>> CHANNEL_SCAN_INDEX_SWITCH, +    } +}; + +/* Adjust channel real bits
>>> based on report descriptor */ +static void
>>> switch_adjust_channel_bit_mask(struct iio_chan_spec *channels, +
>>> int channel, int size) +{ +    channels[channel].scan_type.sign =
>>> 'u'; +    /* Real storage bits will change based on the report desc.
>>> */ +    channels[channel].scan_type.realbits = size * 8; +    /* Maximum
>>> size of a sample to capture is u32 */ +
>>> channels[channel].scan_type.storagebits = sizeof(u32) * 8; +} + +/*
>>> Channel read_raw handler */ +static int switch_read_raw(struct
>>> iio_dev *indio_dev, +                  struct iio_chan_spec const
> *chan, +
>>> int *val, int *val2, +                  long mask) +{ +    struct
> switch_state
>>> *switch_state = iio_priv(indio_dev); +    int report_id = -1; +    u32
>>> address; +    int ret; +    int ret_type; + +    *val = 0; +    *val2
> = 0; +
>>> switch (mask) { +    case IIO_CHAN_INFO_RAW: +        switch
>>> (chan->scan_index) { +        case  CHANNEL_SCAN_INDEX_SWITCH: +
>>> report_id = switch_state->switch_attr.report_id; +            address = +
>>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE; +            break; +   
>     default: +
>>> report_id = -1; +            break; +        } +        if (report_id
>> = 0) +            *val =
>>> sensor_hub_input_attr_get_raw_value( +
>>> switch_state->common_attributes.hsdev, +
>>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, address, +               
> report_id); +
>>> else { +            *val = 0; +            return -EINVAL; +        }
> +        ret_type =
>>> IIO_VAL_INT; +        break; +    case IIO_CHAN_INFO_SAMP_FREQ: +   
>     ret =
>>> hid_sensor_read_samp_freq_value( +
>>> &switch_state->common_attributes, val, val2); +        ret_type =
>>> IIO_VAL_INT_PLUS_MICRO; +        break; +    case
> IIO_CHAN_INFO_HYSTERESIS:
>>> +        ret = hid_sensor_read_raw_hyst_value( +
>>> &switch_state->common_attributes, val, val2); +        ret_type =
>>> IIO_VAL_INT_PLUS_MICRO; +        break; +    default: +        ret_type =
>>> -EINVAL; +        break; +    } + +    return ret_type; +} + +/* Channel
>>> write_raw handler */ +static int switch_write_raw(struct iio_dev
>>> *indio_dev, +                   struct iio_chan_spec const *chan, +
>>> int val, +                   int val2, +                   long mask)
> +{ +    struct
>>> switch_state *switch_state = iio_priv(indio_dev); +    int ret = 0; +
>>> +    switch (mask) { +    case IIO_CHAN_INFO_SAMP_FREQ: +        ret =
>>> hid_sensor_write_samp_freq_value( +
>>> &switch_state->common_attributes, val, val2); +        break; +    case
>>> IIO_CHAN_INFO_HYSTERESIS: +        ret =
>>> hid_sensor_write_raw_hyst_value( +
>>> &switch_state->common_attributes, val, val2); +        break; +   
> default:
>>> +        ret = -EINVAL; +    } + +    return ret; +} + +static int
>>> switch_write_raw_get_fmt(struct iio_dev *indio_dev, +
>>> struct iio_chan_spec const *chan, +                   long mask) +{
> +    return
>>> IIO_VAL_INT_PLUS_MICRO; +} + +static const struct iio_info
>>> switch_info = { +    .driver_module = THIS_MODULE, +    .read_raw =
>>> &switch_read_raw, +    .write_raw = &switch_write_raw, +
>>> .write_raw_get_fmt = &switch_write_raw_get_fmt, +}; + +/* Function
>>> to push data to buffer */ +static void hid_sensor_push_data(struct
>>> iio_dev *indio_dev, u8 *data, int len) +{ +
>>> dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); +
>>> iio_push_to_buffers(indio_dev, (u8 *)data); +} + +/* Callback
>>> handler to send event after all samples are received and captured
>>> */ +static int switch_proc_event(struct hid_sensor_hub_device
>>> *hsdev, +                unsigned usage_id, +                void
> *priv) +{ +    struct
>>> iio_dev *indio_dev = platform_get_drvdata(priv); +    struct
>>> switch_state *switch_state = iio_priv(indio_dev); + +
>>> dev_dbg(&indio_dev->dev, "switch_proc_event [%d]\n", +
>>> switch_state->common_attributes.data_ready); +    if
>>> (switch_state->common_attributes.data_ready) +
>>> hid_sensor_push_data(indio_dev, +                (u8
> *)&switch_state->value, +
>>> sizeof(switch_state->value)); + +    return 0; +} + +/* Capture
>>> samples in local storage */ +static int
>>> switch_capture_sample(struct hid_sensor_hub_device *hsdev, +
>>> unsigned usage_id, +                size_t raw_len, char *raw_data,
> +                void
>>> *priv) +{ +    struct iio_dev *indio_dev =
>>> platform_get_drvdata(priv); +    struct switch_state *switch_state =
>>> iio_priv(indio_dev); +    int ret = -EINVAL; + +    switch (usage_id) { +
>>> case HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE: +
>>> switch_state->value = *(u32 *)raw_data; +        ret = 0; +       
> break; +
>>> default: +        break; +    } + +    return ret; +} + +/* Parse
> report which
>>> is specific to an usage id*/ +static int switch_parse_report(struct
>>> platform_device *pdev, +                struct hid_sensor_hub_device
> *hsdev, +
>>> struct iio_chan_spec *channels, +                unsigned usage_id,
> +                struct
>>> switch_state *st) +{ +    int ret; + +    ret =
>>> sensor_hub_input_get_attribute_info(hsdev, HID_INPUT_REPORT, +
>>> usage_id, +            HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE, +
>>> &st->switch_attr); +    if (ret < 0) +        return ret; +
>>> switch_adjust_channel_bit_mask(channels,
>>> CHANNEL_SCAN_INDEX_SWITCH, +                   
> st->switch_attr.size); + +
>>> dev_dbg(&pdev->dev, "switch %x:%x\n", st->switch_attr.index, +
>>> st->switch_attr.report_id); + +    return ret; +} + +/* Function to
>>> initialize the processing for usage id */ +static int
>>> hid_switch_probe(struct platform_device *pdev) +{ +    int ret = 0; +
>>> static const char *name = "switch"; +    struct iio_dev *indio_dev; +
>>> struct switch_state *switch_state; +    struct hid_sensor_hub_device
>>> *hsdev = pdev->dev.platform_data; +    struct iio_chan_spec
>>> *channels; + +    indio_dev = iio_device_alloc(sizeof(struct
>>> switch_state)); +    if (indio_dev == NULL) { +        ret = -ENOMEM; +
>>> goto error_ret; +    } +    platform_set_drvdata(pdev, indio_dev); + +
>>> switch_state = iio_priv(indio_dev); +
>>> switch_state->common_attributes.hsdev = hsdev; +
>>> switch_state->common_attributes.pdev = pdev; + +    ret =
>>> hid_sensor_parse_common_attributes(hsdev,
>>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, +
>>> &switch_state->common_attributes); +    if (ret) { +
>>> dev_err(&pdev->dev, "failed to setup common attributes\n"); +        goto
>>> error_free_dev; +    } + +    channels = kmemdup(switch_channels,
>>> sizeof(switch_channels), GFP_KERNEL); +    if (!channels) { +       
> ret =
>>> -ENOMEM; +        dev_err(&pdev->dev, "failed to duplicate channels\n");
>>> +        goto error_free_dev; +    } + +    ret =
> switch_parse_report(pdev,
>>> hsdev, channels, +                HID_USAGE_SENSOR_MECHA_BOOL_SWITCH,
>>> switch_state); +    if (ret) { +        dev_err(&pdev->dev, "failed
> to setup
>>> attributes\n"); +        goto error_free_dev_mem; +    } + +
>>> indio_dev->channels = channels; +    indio_dev->num_channels = +
>>> ARRAY_SIZE(switch_channels); +    indio_dev->dev.parent = &pdev->dev;
>>> +    indio_dev->info = &switch_info; +    indio_dev->name = name; +
>>> indio_dev->modes = INDIO_DIRECT_MODE; + +    ret =
>>> iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, +
>>> NULL, NULL); +    if (ret) { +        dev_err(&pdev->dev, "failed to
>>> initialize trigger buffer\n"); +        goto error_free_dev_mem; +    } +
>>> switch_state->common_attributes.data_ready = false; +    ret =
>>> hid_sensor_setup_trigger(indio_dev, name, +
>>> &switch_state->common_attributes); +    if (ret < 0) { +
>>> dev_err(&pdev->dev, "trigger setup failed\n"); +        goto
>>> error_unreg_buffer_funcs; +    } + +    ret =
>>> iio_device_register(indio_dev); +    if (ret) { +       
> dev_err(&pdev->dev,
>>> "device register failed\n"); +        goto error_remove_trigger; +   
> } + +
>>> switch_state->callbacks.send_event = switch_proc_event; +
>>> switch_state->callbacks.capture_sample = switch_capture_sample; +
>>> switch_state->callbacks.pdev = pdev; +    ret =
>>> sensor_hub_register_callback(hsdev,
>>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH, +
>>> &switch_state->callbacks); +    if (ret < 0) { +       
> dev_err(&pdev->dev,
>>> "callback reg failed\n"); +        goto error_iio_unreg; +    } +
> +    return
>>> ret; + +error_iio_unreg: +    iio_device_unregister(indio_dev);
>>> +error_remove_trigger: +    hid_sensor_remove_trigger(indio_dev);
>>> +error_unreg_buffer_funcs: +
>>> iio_triggered_buffer_cleanup(indio_dev); +error_free_dev_mem: +
>>> kfree(indio_dev->channels); +error_free_dev: +
>>> iio_device_free(indio_dev); +error_ret: +    return ret; +} + +/*
>>> Function to deinitialize the processing for usage id */ +static int
>>> hid_switch_remove(struct platform_device *pdev) +{ +    struct
>>> hid_sensor_hub_device *hsdev = pdev->dev.platform_data; +    struct
>>> iio_dev *indio_dev = platform_get_drvdata(pdev); + +
>>> sensor_hub_remove_callback(hsdev,
>>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH); +
>>> iio_device_unregister(indio_dev); +
>>> hid_sensor_remove_trigger(indio_dev); +
>>> iio_triggered_buffer_cleanup(indio_dev); +
>>> kfree(indio_dev->channels); +    iio_device_free(indio_dev); + +
>>> return 0; +} + +static struct platform_driver
>>> hid_switch_platform_driver = { +    .driver = { +        .name    =
>>> DRIVER_NAME, +        .owner    = THIS_MODULE, +    }, +    .probe   
>     =
>>> hid_switch_probe, +    .remove        = hid_switch_remove, +};
>>> +module_platform_driver(hid_switch_platform_driver); +
>>> +MODULE_DESCRIPTION("HID Sensor Boolean Switch");
>>> +MODULE_AUTHOR("Alexandre Relange <alexandre@relange.org>");
>>> +MODULE_LICENSE("GPL"); diff --git a/include/linux/hid-sensor-ids.h
>>> b/include/linux/hid-sensor-ids.h index 6f24446..e469078 100644 ---
>>> a/include/linux/hid-sensor-ids.h +++
>>> b/include/linux/hid-sensor-ids.h @@ -31,6 +31,10 @@ #define
>>> HID_USAGE_SENSOR_ALS                    0x200041 #define
>>> HID_USAGE_SENSOR_LIGHT_ILLUM                0x2004d1
>>>
>>> +/* MECHANICAL: Boolean Switch: (200061) */ +#define
>>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH            0x200061 +#define
>>> HID_USAGE_SENSOR_MECHA_BOOL_SWITCH_STATE        0x200491 + /* Gyro 3D:
>>> (200076) */ #define HID_USAGE_SENSOR_GYRO_3D                0x200076
> #define
>>> HID_USAGE_SENSOR_ANGL_VELOCITY_X_AXIS            0x200457
>>>
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/5] iio: mechanical: new HID sensor boolean switch
  2013-06-11 14:52 ` [PATCH 4/5] iio: mechanical: new HID sensor boolean switch Alexandre Relange
  2013-06-11 17:13   ` Lars-Peter Clausen
  2013-07-07 15:36   ` Jonathan Cameron
@ 2013-07-12 19:34   ` Alexander Holler
  2 siblings, 0 replies; 16+ messages in thread
From: Alexander Holler @ 2013-07-12 19:34 UTC (permalink / raw)
  To: Alexandre Relange; +Cc: Jonathan Cameron, linux-iio

Am 11.06.2013 16:52, schrieb Alexandre Relange:
> Implements the Boolean Switch sensor from the USB sensor usage tables
> http://www.usb.org/developers/hidpage/HUTRR39b.pdf
> 
> This code is based on drivers/iio/light/hid-sensor-als.c
> 
> Signed-off-by: Alexandre Relange <alexandre@relange.org>
> ---

...

> +
> +/*Format: HID-SENSOR-usage_id_in_hex*/
> +/*Usage ID from spec for Boolean-Switch: 0x200061*/
> +#define DRIVER_NAME "HID-SENSOR-200061"
> +

...

> +static struct platform_driver hid_switch_platform_driver = {
> +	.driver = {
> +		.name	= DRIVER_NAME,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= hid_switch_probe,
> +	.remove		= hid_switch_remove,
> +};
> +module_platform_driver(hid_switch_platform_driver);
> +

You already might add the fix I've recently posted for all the other iio
HID drivers to let the module automatically loaded. It gives a nicier
driver name too.

I've pasted the patch for the als-driver for your reference below.
Be sure to change the usage id to the one for your driver.

Regards,

Alexander Holler

--------
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -30,10 +30,6 @@
 #include <linux/iio/triggered_buffer.h>
 #include "../common/hid-sensors/hid-sensor-trigger.h"

-/*Format: HID-SENSOR-usage_id_in_hex*/
-/*Usage ID from spec for Ambiant-Light: 0x200041*/
-#define DRIVER_NAME "HID-SENSOR-200041"
-
 #define CHANNEL_SCAN_INDEX_ILLUM 0

 struct als_state {
@@ -355,9 +351,19 @@ static int hid_als_remove(struct platform_device *pdev)
 	return 0;
 }

+static struct platform_device_id hid_als_ids[] = {
+	{
+		/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
+		.name = "HID-SENSOR-200041",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, hid_als_ids);
+
 static struct platform_driver hid_als_platform_driver = {
+	.id_table = hid_als_ids,
 	.driver = {
-		.name	= DRIVER_NAME,
+		.name	= KBUILD_MODNAME,
 		.owner	= THIS_MODULE,
 	},
 	.probe		= hid_als_probe,
-- 1.8.1.5



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2013-07-12 19:35 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-11 14:52 [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Alexandre Relange
2013-06-11 14:52 ` [PATCH 2/5] iio: mechanical: new category of sensors Alexandre Relange
2013-07-07 15:29   ` Jonathan Cameron
2013-07-08 15:01     ` Alexandre Relange
2013-07-09 18:05       ` Jonathan Cameron
2013-06-11 14:52 ` [PATCH 3/5] iio: new type of channel: STATE Alexandre Relange
2013-06-11 14:52 ` [PATCH 4/5] iio: mechanical: new HID sensor boolean switch Alexandre Relange
2013-06-11 17:13   ` Lars-Peter Clausen
2013-06-11 20:18     ` Jonathan Cameron
2013-07-07 15:36   ` Jonathan Cameron
2013-07-08 15:17     ` Alexandre Relange
2013-07-09 18:06       ` Jonathan Cameron
2013-07-12 19:34   ` Alexander Holler
2013-06-11 14:52 ` [PATCH 5/5] iio: mechanical: switch sensor: add ID table Alexandre Relange
2013-06-11 17:07 ` [PATCH 1/5] iio: ABI doc: update scan_elements sysfs paths Lars-Peter Clausen
2013-06-11 20:10 ` Jonathan Cameron

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.