iio: Move IIO Dummy Driver out of staging
authorCristina Opriceana <cristina.opriceana@gmail.com>
Fri, 9 Oct 2015 13:31:28 +0000 (16:31 +0300)
committerJonathan Cameron <jic23@kernel.org>
Sun, 25 Oct 2015 12:33:01 +0000 (12:33 +0000)
This patch moves the reference IIO dummy driver from drivers/staging/iio
into a separate folder, drivers/iio/dummy and adds the proper Kconfig
and Makefile for it.

A new config menu entry called IIO dummy driver has also been added
in the Industrial I/O support menu, corresponding to this driver.

Signed-off-by: Cristina Opriceana <cristina.opriceana@gmail.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
18 files changed:
drivers/iio/Kconfig
drivers/iio/Makefile
drivers/iio/dummy/Kconfig [new file with mode: 0644]
drivers/iio/dummy/Makefile [new file with mode: 0644]
drivers/iio/dummy/iio_dummy_evgen.c [new file with mode: 0644]
drivers/iio/dummy/iio_dummy_evgen.h [new file with mode: 0644]
drivers/iio/dummy/iio_simple_dummy.c [new file with mode: 0644]
drivers/iio/dummy/iio_simple_dummy.h [new file with mode: 0644]
drivers/iio/dummy/iio_simple_dummy_buffer.c [new file with mode: 0644]
drivers/iio/dummy/iio_simple_dummy_events.c [new file with mode: 0644]
drivers/staging/iio/Kconfig
drivers/staging/iio/Makefile
drivers/staging/iio/iio_dummy_evgen.c [deleted file]
drivers/staging/iio/iio_dummy_evgen.h [deleted file]
drivers/staging/iio/iio_simple_dummy.c [deleted file]
drivers/staging/iio/iio_simple_dummy.h [deleted file]
drivers/staging/iio/iio_simple_dummy_buffer.c [deleted file]
drivers/staging/iio/iio_simple_dummy_events.c [deleted file]

index 66792e7..6b8c77c 100644 (file)
@@ -50,6 +50,7 @@ source "drivers/iio/amplifiers/Kconfig"
 source "drivers/iio/chemical/Kconfig"
 source "drivers/iio/common/Kconfig"
 source "drivers/iio/dac/Kconfig"
+source "drivers/iio/dummy/Kconfig"
 source "drivers/iio/frequency/Kconfig"
 source "drivers/iio/gyro/Kconfig"
 source "drivers/iio/humidity/Kconfig"
index aeca726..6769f2f 100644 (file)
@@ -16,6 +16,7 @@ obj-y += buffer/
 obj-y += chemical/
 obj-y += common/
 obj-y += dac/
+obj-y += dummy/
 obj-y += gyro/
 obj-y += frequency/
 obj-y += humidity/
diff --git a/drivers/iio/dummy/Kconfig b/drivers/iio/dummy/Kconfig
new file mode 100644 (file)
index 0000000..e8676aa
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# Industrial I/O subsystem Dummy Driver configuration
+#
+menu "IIO dummy driver"
+       depends on IIO
+
+config IIO_DUMMY_EVGEN
+       tristate
+
+config IIO_SIMPLE_DUMMY
+       tristate "An example driver with no hardware requirements"
+       help
+        Driver intended mainly as documentation for how to write
+        a driver. May also be useful for testing userspace code
+        without hardware.
+
+if IIO_SIMPLE_DUMMY
+
+config IIO_SIMPLE_DUMMY_EVENTS
+       bool "Event generation support"
+       select IIO_DUMMY_EVGEN
+       help
+         Add some dummy events to the simple dummy driver.
+
+config IIO_SIMPLE_DUMMY_BUFFER
+       bool "Buffered capture support"
+       select IIO_BUFFER
+       select IIO_TRIGGER
+       select IIO_KFIFO_BUF
+       help
+         Add buffered data capture to the simple dummy driver.
+
+endif # IIO_SIMPLE_DUMMY
+
+endmenu
diff --git a/drivers/iio/dummy/Makefile b/drivers/iio/dummy/Makefile
new file mode 100644 (file)
index 0000000..0765e93
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile for the IIO Dummy Driver
+#
+
+obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o
+iio_dummy-y := iio_simple_dummy.o
+iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_EVENTS) += iio_simple_dummy_events.o
+iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_BUFFER) += iio_simple_dummy_buffer.o
+
+obj-$(CONFIG_IIO_DUMMY_EVGEN) += iio_dummy_evgen.o
diff --git a/drivers/iio/dummy/iio_dummy_evgen.c b/drivers/iio/dummy/iio_dummy_evgen.c
new file mode 100644 (file)
index 0000000..9e83f34
--- /dev/null
@@ -0,0 +1,262 @@
+/**
+ * Copyright (c) 2011 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * Companion module to the iio simple dummy example driver.
+ * The purpose of this is to generate 'fake' event interrupts thus
+ * allowing that driver's code to be as close as possible to that of
+ * a normal driver talking to hardware.  The approach used here
+ * is not intended to be general and just happens to work for this
+ * particular use case.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/sysfs.h>
+
+#include "iio_dummy_evgen.h"
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/irq_work.h>
+
+/* Fiddly bit of faking and irq without hardware */
+#define IIO_EVENTGEN_NO 10
+
+/**
+ * struct iio_dummy_handle_irq - helper struct to simulate interrupt generation
+ * @work: irq_work used to run handlers from hardirq context
+ * @irq: fake irq line number to trigger an interrupt
+ */
+struct iio_dummy_handle_irq {
+       struct irq_work work;
+       int irq;
+};
+
+/**
+ * struct iio_dummy_evgen - evgen state
+ * @chip: irq chip we are faking
+ * @base: base of irq range
+ * @enabled: mask of which irqs are enabled
+ * @inuse: mask of which irqs are connected
+ * @regs: irq regs we are faking
+ * @lock: protect the evgen state
+ * @handler: helper for a 'hardware-like' interrupt simulation
+ */
+struct iio_dummy_eventgen {
+       struct irq_chip chip;
+       int base;
+       bool enabled[IIO_EVENTGEN_NO];
+       bool inuse[IIO_EVENTGEN_NO];
+       struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
+       struct mutex lock;
+       struct iio_dummy_handle_irq handler;
+};
+
+/* We can only ever have one instance of this 'device' */
+static struct iio_dummy_eventgen *iio_evgen;
+static const char *iio_evgen_name = "iio_dummy_evgen";
+
+static void iio_dummy_event_irqmask(struct irq_data *d)
+{
+       struct irq_chip *chip = irq_data_get_irq_chip(d);
+       struct iio_dummy_eventgen *evgen =
+               container_of(chip, struct iio_dummy_eventgen, chip);
+
+       evgen->enabled[d->irq - evgen->base] = false;
+}
+
+static void iio_dummy_event_irqunmask(struct irq_data *d)
+{
+       struct irq_chip *chip = irq_data_get_irq_chip(d);
+       struct iio_dummy_eventgen *evgen =
+               container_of(chip, struct iio_dummy_eventgen, chip);
+
+       evgen->enabled[d->irq - evgen->base] = true;
+}
+
+static void iio_dummy_work_handler(struct irq_work *work)
+{
+       struct iio_dummy_handle_irq *irq_handler;
+
+       irq_handler = container_of(work, struct iio_dummy_handle_irq, work);
+       handle_simple_irq(irq_to_desc(irq_handler->irq));
+}
+
+static int iio_dummy_evgen_create(void)
+{
+       int ret, i;
+
+       iio_evgen = kzalloc(sizeof(*iio_evgen), GFP_KERNEL);
+       if (!iio_evgen)
+               return -ENOMEM;
+
+       iio_evgen->base = irq_alloc_descs(-1, 0, IIO_EVENTGEN_NO, 0);
+       if (iio_evgen->base < 0) {
+               ret = iio_evgen->base;
+               kfree(iio_evgen);
+               return ret;
+       }
+       iio_evgen->chip.name = iio_evgen_name;
+       iio_evgen->chip.irq_mask = &iio_dummy_event_irqmask;
+       iio_evgen->chip.irq_unmask = &iio_dummy_event_irqunmask;
+       for (i = 0; i < IIO_EVENTGEN_NO; i++) {
+               irq_set_chip(iio_evgen->base + i, &iio_evgen->chip);
+               irq_set_handler(iio_evgen->base + i, &handle_simple_irq);
+               irq_modify_status(iio_evgen->base + i,
+                                 IRQ_NOREQUEST | IRQ_NOAUTOEN,
+                                 IRQ_NOPROBE);
+       }
+       init_irq_work(&iio_evgen->handler.work, iio_dummy_work_handler);
+       mutex_init(&iio_evgen->lock);
+       return 0;
+}
+
+/**
+ * iio_dummy_evgen_get_irq() - get an evgen provided irq for a device
+ *
+ * This function will give a free allocated irq to a client device.
+ * That irq can then be caused to 'fire' by using the associated sysfs file.
+ */
+int iio_dummy_evgen_get_irq(void)
+{
+       int i, ret = 0;
+
+       if (!iio_evgen)
+               return -ENODEV;
+
+       mutex_lock(&iio_evgen->lock);
+       for (i = 0; i < IIO_EVENTGEN_NO; i++)
+               if (!iio_evgen->inuse[i]) {
+                       ret = iio_evgen->base + i;
+                       iio_evgen->inuse[i] = true;
+                       break;
+               }
+       mutex_unlock(&iio_evgen->lock);
+       if (i == IIO_EVENTGEN_NO)
+               return -ENOMEM;
+       return ret;
+}
+EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_irq);
+
+/**
+ * iio_dummy_evgen_release_irq() - give the irq back.
+ * @irq: irq being returned to the pool
+ *
+ * Used by client driver instances to give the irqs back when they disconnect
+ */
+void iio_dummy_evgen_release_irq(int irq)
+{
+       mutex_lock(&iio_evgen->lock);
+       iio_evgen->inuse[irq - iio_evgen->base] = false;
+       mutex_unlock(&iio_evgen->lock);
+}
+EXPORT_SYMBOL_GPL(iio_dummy_evgen_release_irq);
+
+struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq)
+{
+       return &iio_evgen->regs[irq - iio_evgen->base];
+}
+EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs);
+
+static void iio_dummy_evgen_free(void)
+{
+       irq_free_descs(iio_evgen->base, IIO_EVENTGEN_NO);
+       kfree(iio_evgen);
+}
+
+static void iio_evgen_release(struct device *dev)
+{
+       iio_dummy_evgen_free();
+}
+
+static ssize_t iio_evgen_poke(struct device *dev,
+                             struct device_attribute *attr,
+                             const char *buf,
+                             size_t len)
+{
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       unsigned long event;
+       int ret;
+
+       ret = kstrtoul(buf, 10, &event);
+       if (ret)
+               return ret;
+
+       iio_evgen->regs[this_attr->address].reg_id   = this_attr->address;
+       iio_evgen->regs[this_attr->address].reg_data = event;
+
+       iio_evgen->handler.irq = iio_evgen->base + this_attr->address;
+       if (iio_evgen->enabled[this_attr->address])
+               irq_work_queue(&iio_evgen->handler.work);
+
+       return len;
+}
+
+static IIO_DEVICE_ATTR(poke_ev0, S_IWUSR, NULL, &iio_evgen_poke, 0);
+static IIO_DEVICE_ATTR(poke_ev1, S_IWUSR, NULL, &iio_evgen_poke, 1);
+static IIO_DEVICE_ATTR(poke_ev2, S_IWUSR, NULL, &iio_evgen_poke, 2);
+static IIO_DEVICE_ATTR(poke_ev3, S_IWUSR, NULL, &iio_evgen_poke, 3);
+static IIO_DEVICE_ATTR(poke_ev4, S_IWUSR, NULL, &iio_evgen_poke, 4);
+static IIO_DEVICE_ATTR(poke_ev5, S_IWUSR, NULL, &iio_evgen_poke, 5);
+static IIO_DEVICE_ATTR(poke_ev6, S_IWUSR, NULL, &iio_evgen_poke, 6);
+static IIO_DEVICE_ATTR(poke_ev7, S_IWUSR, NULL, &iio_evgen_poke, 7);
+static IIO_DEVICE_ATTR(poke_ev8, S_IWUSR, NULL, &iio_evgen_poke, 8);
+static IIO_DEVICE_ATTR(poke_ev9, S_IWUSR, NULL, &iio_evgen_poke, 9);
+
+static struct attribute *iio_evgen_attrs[] = {
+       &iio_dev_attr_poke_ev0.dev_attr.attr,
+       &iio_dev_attr_poke_ev1.dev_attr.attr,
+       &iio_dev_attr_poke_ev2.dev_attr.attr,
+       &iio_dev_attr_poke_ev3.dev_attr.attr,
+       &iio_dev_attr_poke_ev4.dev_attr.attr,
+       &iio_dev_attr_poke_ev5.dev_attr.attr,
+       &iio_dev_attr_poke_ev6.dev_attr.attr,
+       &iio_dev_attr_poke_ev7.dev_attr.attr,
+       &iio_dev_attr_poke_ev8.dev_attr.attr,
+       &iio_dev_attr_poke_ev9.dev_attr.attr,
+       NULL,
+};
+
+static const struct attribute_group iio_evgen_group = {
+       .attrs = iio_evgen_attrs,
+};
+
+static const struct attribute_group *iio_evgen_groups[] = {
+       &iio_evgen_group,
+       NULL
+};
+
+static struct device iio_evgen_dev = {
+       .bus = &iio_bus_type,
+       .groups = iio_evgen_groups,
+       .release = &iio_evgen_release,
+};
+
+static __init int iio_dummy_evgen_init(void)
+{
+       int ret = iio_dummy_evgen_create();
+
+       if (ret < 0)
+               return ret;
+       device_initialize(&iio_evgen_dev);
+       dev_set_name(&iio_evgen_dev, "iio_evgen");
+       return device_add(&iio_evgen_dev);
+}
+module_init(iio_dummy_evgen_init);
+
+static __exit void iio_dummy_evgen_exit(void)
+{
+       device_unregister(&iio_evgen_dev);
+}
+module_exit(iio_dummy_evgen_exit);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
+MODULE_DESCRIPTION("IIO dummy driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dummy/iio_dummy_evgen.h b/drivers/iio/dummy/iio_dummy_evgen.h
new file mode 100644 (file)
index 0000000..d044b94
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _IIO_DUMMY_EVGEN_H_
+#define _IIO_DUMMY_EVGEN_H_
+
+struct iio_dummy_regs {
+       u32 reg_id;
+       u32 reg_data;
+};
+
+struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq);
+int iio_dummy_evgen_get_irq(void);
+void iio_dummy_evgen_release_irq(int irq);
+
+#endif /* _IIO_DUMMY_EVGEN_H_ */
diff --git a/drivers/iio/dummy/iio_simple_dummy.c b/drivers/iio/dummy/iio_simple_dummy.c
new file mode 100644 (file)
index 0000000..381f90f
--- /dev/null
@@ -0,0 +1,748 @@
+/**
+ * Copyright (c) 2011 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * A reference industrial I/O driver to illustrate the functionality available.
+ *
+ * There are numerous real drivers to illustrate the finer points.
+ * The purpose of this driver is to provide a driver with far more comments
+ * and explanatory notes than any 'real' driver would have.
+ * Anyone starting out writing an IIO driver should first make sure they
+ * understand all of this driver except those bits specifically marked
+ * as being present to allow us to 'fake' the presence of hardware.
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+#include <linux/iio/buffer.h>
+#include "iio_simple_dummy.h"
+
+/*
+ * A few elements needed to fake a bus for this driver
+ * Note instances parameter controls how many of these
+ * dummy devices are registered.
+ */
+static unsigned instances = 1;
+module_param(instances, uint, 0);
+
+/* Pointer array used to fake bus elements */
+static struct iio_dev **iio_dummy_devs;
+
+/* Fake a name for the part number, usually obtained from the id table */
+static const char *iio_dummy_part_number = "iio_dummy_part_no";
+
+/**
+ * struct iio_dummy_accel_calibscale - realworld to register mapping
+ * @val: first value in read_raw - here integer part.
+ * @val2: second value in read_raw etc - here micro part.
+ * @regval: register value - magic device specific numbers.
+ */
+struct iio_dummy_accel_calibscale {
+       int val;
+       int val2;
+       int regval; /* what would be written to hardware */
+};
+
+static const struct iio_dummy_accel_calibscale dummy_scales[] = {
+       { 0, 100, 0x8 }, /* 0.000100 */
+       { 0, 133, 0x7 }, /* 0.000133 */
+       { 733, 13, 0x9 }, /* 733.000013 */
+};
+
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+
+/*
+ * simple event - triggered when value rises above
+ * a threshold
+ */
+static const struct iio_event_spec iio_dummy_event = {
+       .type = IIO_EV_TYPE_THRESH,
+       .dir = IIO_EV_DIR_RISING,
+       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
+
+/*
+ * simple step detect event - triggered when a step is detected
+ */
+static const struct iio_event_spec step_detect_event = {
+       .type = IIO_EV_TYPE_CHANGE,
+       .dir = IIO_EV_DIR_NONE,
+       .mask_separate = BIT(IIO_EV_INFO_ENABLE),
+};
+
+/*
+ * simple transition event - triggered when the reported running confidence
+ * value rises above a threshold value
+ */
+static const struct iio_event_spec iio_running_event = {
+       .type = IIO_EV_TYPE_THRESH,
+       .dir = IIO_EV_DIR_RISING,
+       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
+
+/*
+ * simple transition event - triggered when the reported walking confidence
+ * value falls under a threshold value
+ */
+static const struct iio_event_spec iio_walking_event = {
+       .type = IIO_EV_TYPE_THRESH,
+       .dir = IIO_EV_DIR_FALLING,
+       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
+#endif
+
+/*
+ * iio_dummy_channels - Description of available channels
+ *
+ * This array of structures tells the IIO core about what the device
+ * actually provides for a given channel.
+ */
+static const struct iio_chan_spec iio_dummy_channels[] = {
+       /* indexed ADC channel in_voltage0_raw etc */
+       {
+               .type = IIO_VOLTAGE,
+               /* Channel has a numeric index of 0 */
+               .indexed = 1,
+               .channel = 0,
+               /* What other information is available? */
+               .info_mask_separate =
+               /*
+                * in_voltage0_raw
+                * Raw (unscaled no bias removal etc) measurement
+                * from the device.
+                */
+               BIT(IIO_CHAN_INFO_RAW) |
+               /*
+                * in_voltage0_offset
+                * Offset for userspace to apply prior to scale
+                * when converting to standard units (microvolts)
+                */
+               BIT(IIO_CHAN_INFO_OFFSET) |
+               /*
+                * in_voltage0_scale
+                * Multipler for userspace to apply post offset
+                * when converting to standard units (microvolts)
+                */
+               BIT(IIO_CHAN_INFO_SCALE),
+               /*
+                * sampling_frequency
+                * The frequency in Hz at which the channels are sampled
+                */
+               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+               /* The ordering of elements in the buffer via an enum */
+               .scan_index = voltage0,
+               .scan_type = { /* Description of storage in buffer */
+                       .sign = 'u', /* unsigned */
+                       .realbits = 13, /* 13 bits */
+                       .storagebits = 16, /* 16 bits used for storage */
+                       .shift = 0, /* zero shift */
+               },
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+               .event_spec = &iio_dummy_event,
+               .num_event_specs = 1,
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
+       },
+       /* Differential ADC channel in_voltage1-voltage2_raw etc*/
+       {
+               .type = IIO_VOLTAGE,
+               .differential = 1,
+               /*
+                * Indexing for differential channels uses channel
+                * for the positive part, channel2 for the negative.
+                */
+               .indexed = 1,
+               .channel = 1,
+               .channel2 = 2,
+               /*
+                * in_voltage1-voltage2_raw
+                * Raw (unscaled no bias removal etc) measurement
+                * from the device.
+                */
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               /*
+                * in_voltage-voltage_scale
+                * Shared version of scale - shared by differential
+                * input channels of type IIO_VOLTAGE.
+                */
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+               /*
+                * sampling_frequency
+                * The frequency in Hz at which the channels are sampled
+                */
+               .scan_index = diffvoltage1m2,
+               .scan_type = { /* Description of storage in buffer */
+                       .sign = 's', /* signed */
+                       .realbits = 12, /* 12 bits */
+                       .storagebits = 16, /* 16 bits used for storage */
+                       .shift = 0, /* zero shift */
+               },
+       },
+       /* Differential ADC channel in_voltage3-voltage4_raw etc*/
+       {
+               .type = IIO_VOLTAGE,
+               .differential = 1,
+               .indexed = 1,
+               .channel = 3,
+               .channel2 = 4,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+               .scan_index = diffvoltage3m4,
+               .scan_type = {
+                       .sign = 's',
+                       .realbits = 11,
+                       .storagebits = 16,
+                       .shift = 0,
+               },
+       },
+       /*
+        * 'modified' (i.e. axis specified) acceleration channel
+        * in_accel_z_raw
+        */
+       {
+               .type = IIO_ACCEL,
+               .modified = 1,
+               /* Channel 2 is use for modifiers */
+               .channel2 = IIO_MOD_X,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+               /*
+                * Internal bias and gain correction values. Applied
+                * by the hardware or driver prior to userspace
+                * seeing the readings. Typically part of hardware
+                * calibration.
+                */
+               BIT(IIO_CHAN_INFO_CALIBSCALE) |
+               BIT(IIO_CHAN_INFO_CALIBBIAS),
+               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+               .scan_index = accelx,
+               .scan_type = { /* Description of storage in buffer */
+                       .sign = 's', /* signed */
+                       .realbits = 16, /* 16 bits */
+                       .storagebits = 16, /* 16 bits used for storage */
+                       .shift = 0, /* zero shift */
+               },
+       },
+       /*
+        * Convenience macro for timestamps. 4 is the index in
+        * the buffer.
+        */
+       IIO_CHAN_SOFT_TIMESTAMP(4),
+       /* DAC channel out_voltage0_raw */
+       {
+               .type = IIO_VOLTAGE,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .scan_index = -1, /* No buffer support */
+               .output = 1,
+               .indexed = 1,
+               .channel = 0,
+       },
+       {
+               .type = IIO_STEPS,
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_ENABLE) |
+                       BIT(IIO_CHAN_INFO_CALIBHEIGHT),
+               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+               .scan_index = -1, /* No buffer support */
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+               .event_spec = &step_detect_event,
+               .num_event_specs = 1,
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
+       },
+       {
+               .type = IIO_ACTIVITY,
+               .modified = 1,
+               .channel2 = IIO_MOD_RUNNING,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+               .scan_index = -1, /* No buffer support */
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+               .event_spec = &iio_running_event,
+               .num_event_specs = 1,
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
+       },
+       {
+               .type = IIO_ACTIVITY,
+               .modified = 1,
+               .channel2 = IIO_MOD_WALKING,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+               .scan_index = -1, /* No buffer support */
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+               .event_spec = &iio_walking_event,
+               .num_event_specs = 1,
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
+       },
+};
+
+/**
+ * iio_dummy_read_raw() - data read function.
+ * @indio_dev: the struct iio_dev associated with this device instance
+ * @chan:      the channel whose data is to be read
+ * @val:       first element of returned value (typically INT)
+ * @val2:      second element of returned value (typically MICRO)
+ * @mask:      what we actually want to read as per the info_mask_*
+ *             in iio_chan_spec.
+ */
+static int iio_dummy_read_raw(struct iio_dev *indio_dev,
+                             struct iio_chan_spec const *chan,
+                             int *val,
+                             int *val2,
+                             long mask)
+{
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+       int ret = -EINVAL;
+
+       mutex_lock(&st->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW: /* magic value - channel value read */
+               switch (chan->type) {
+               case IIO_VOLTAGE:
+                       if (chan->output) {
+                               /* Set integer part to cached value */
+                               *val = st->dac_val;
+                               ret = IIO_VAL_INT;
+                       } else if (chan->differential) {
+                               if (chan->channel == 1)
+                                       *val = st->differential_adc_val[0];
+                               else
+                                       *val = st->differential_adc_val[1];
+                               ret = IIO_VAL_INT;
+                       } else {
+                               *val = st->single_ended_adc_val;
+                               ret = IIO_VAL_INT;
+                       }
+                       break;
+               case IIO_ACCEL:
+                       *val = st->accel_val;
+                       ret = IIO_VAL_INT;
+                       break;
+               default:
+                       break;
+               }
+               break;
+       case IIO_CHAN_INFO_PROCESSED:
+               switch (chan->type) {
+               case IIO_STEPS:
+                       *val = st->steps;
+                       ret = IIO_VAL_INT;
+                       break;
+               case IIO_ACTIVITY:
+                       switch (chan->channel2) {
+                       case IIO_MOD_RUNNING:
+                               *val = st->activity_running;
+                               ret = IIO_VAL_INT;
+                               break;
+                       case IIO_MOD_WALKING:
+                               *val = st->activity_walking;
+                               ret = IIO_VAL_INT;
+                               break;
+                       default:
+                               break;
+                       }
+                       break;
+               default:
+                       break;
+               }
+               break;
+       case IIO_CHAN_INFO_OFFSET:
+               /* only single ended adc -> 7 */
+               *val = 7;
+               ret = IIO_VAL_INT;
+               break;
+       case IIO_CHAN_INFO_SCALE:
+               switch (chan->type) {
+               case IIO_VOLTAGE:
+                       switch (chan->differential) {
+                       case 0:
+                               /* only single ended adc -> 0.001333 */
+                               *val = 0;
+                               *val2 = 1333;
+                               ret = IIO_VAL_INT_PLUS_MICRO;
+                               break;
+                       case 1:
+                               /* all differential adc channels ->
+                                * 0.000001344 */
+                               *val = 0;
+                               *val2 = 1344;
+                               ret = IIO_VAL_INT_PLUS_NANO;
+                       }
+                       break;
+               default:
+                       break;
+               }
+               break;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               /* only the acceleration axis - read from cache */
+               *val = st->accel_calibbias;
+               ret = IIO_VAL_INT;
+               break;
+       case IIO_CHAN_INFO_CALIBSCALE:
+               *val = st->accel_calibscale->val;
+               *val2 = st->accel_calibscale->val2;
+               ret = IIO_VAL_INT_PLUS_MICRO;
+               break;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val = 3;
+               *val2 = 33;
+               ret = IIO_VAL_INT_PLUS_NANO;
+               break;
+       case IIO_CHAN_INFO_ENABLE:
+               switch (chan->type) {
+               case IIO_STEPS:
+                       *val = st->steps_enabled;
+                       ret = IIO_VAL_INT;
+                       break;
+               default:
+                       break;
+               }
+               break;
+       case IIO_CHAN_INFO_CALIBHEIGHT:
+               switch (chan->type) {
+               case IIO_STEPS:
+                       *val = st->height;
+                       ret = IIO_VAL_INT;
+                       break;
+               default:
+                       break;
+               }
+               break;
+
+       default:
+               break;
+       }
+       mutex_unlock(&st->lock);
+       return ret;
+}
+
+/**
+ * iio_dummy_write_raw() - data write function.
+ * @indio_dev: the struct iio_dev associated with this device instance
+ * @chan:      the channel whose data is to be written
+ * @val:       first element of value to set (typically INT)
+ * @val2:      second element of value to set (typically MICRO)
+ * @mask:      what we actually want to write as per the info_mask_*
+ *             in iio_chan_spec.
+ *
+ * Note that all raw writes are assumed IIO_VAL_INT and info mask elements
+ * are assumed to be IIO_INT_PLUS_MICRO unless the callback write_raw_get_fmt
+ * in struct iio_info is provided by the driver.
+ */
+static int iio_dummy_write_raw(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan,
+                              int val,
+                              int val2,
+                              long mask)
+{
+       int i;
+       int ret = 0;
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               switch (chan->type) {
+               case IIO_VOLTAGE:
+                       if (chan->output == 0)
+                               return -EINVAL;
+
+                       /* Locking not required as writing single value */
+                       mutex_lock(&st->lock);
+                       st->dac_val = val;
+                       mutex_unlock(&st->lock);
+                       return 0;
+               default:
+                       return -EINVAL;
+               }
+       case IIO_CHAN_INFO_PROCESSED:
+               switch (chan->type) {
+               case IIO_STEPS:
+                       mutex_lock(&st->lock);
+                       st->steps = val;
+                       mutex_unlock(&st->lock);
+                       return 0;
+               case IIO_ACTIVITY:
+                       if (val < 0)
+                               val = 0;
+                       if (val > 100)
+                               val = 100;
+                       switch (chan->channel2) {
+                       case IIO_MOD_RUNNING:
+                               st->activity_running = val;
+                               return 0;
+                       case IIO_MOD_WALKING:
+                               st->activity_walking = val;
+                               return 0;
+                       default:
+                               return -EINVAL;
+                       }
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       case IIO_CHAN_INFO_CALIBSCALE:
+               mutex_lock(&st->lock);
+               /* Compare against table - hard matching here */
+               for (i = 0; i < ARRAY_SIZE(dummy_scales); i++)
+                       if (val == dummy_scales[i].val &&
+                           val2 == dummy_scales[i].val2)
+                               break;
+               if (i == ARRAY_SIZE(dummy_scales))
+                       ret = -EINVAL;
+               else
+                       st->accel_calibscale = &dummy_scales[i];
+               mutex_unlock(&st->lock);
+               return ret;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               mutex_lock(&st->lock);
+               st->accel_calibbias = val;
+               mutex_unlock(&st->lock);
+               return 0;
+       case IIO_CHAN_INFO_ENABLE:
+               switch (chan->type) {
+               case IIO_STEPS:
+                       mutex_lock(&st->lock);
+                       st->steps_enabled = val;
+                       mutex_unlock(&st->lock);
+                       return 0;
+               default:
+                       return -EINVAL;
+               }
+       case IIO_CHAN_INFO_CALIBHEIGHT:
+               switch (chan->type) {
+               case IIO_STEPS:
+                       st->height = val;
+                       return 0;
+               default:
+                       return -EINVAL;
+               }
+
+       default:
+               return -EINVAL;
+       }
+}
+
+/*
+ * Device type specific information.
+ */
+static const struct iio_info iio_dummy_info = {
+       .driver_module = THIS_MODULE,
+       .read_raw = &iio_dummy_read_raw,
+       .write_raw = &iio_dummy_write_raw,
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+       .read_event_config = &iio_simple_dummy_read_event_config,
+       .write_event_config = &iio_simple_dummy_write_event_config,
+       .read_event_value = &iio_simple_dummy_read_event_value,
+       .write_event_value = &iio_simple_dummy_write_event_value,
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
+};
+
+/**
+ * iio_dummy_init_device() - device instance specific init
+ * @indio_dev: the iio device structure
+ *
+ * Most drivers have one of these to set up default values,
+ * reset the device to known state etc.
+ */
+static int iio_dummy_init_device(struct iio_dev *indio_dev)
+{
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+
+       st->dac_val = 0;
+       st->single_ended_adc_val = 73;
+       st->differential_adc_val[0] = 33;
+       st->differential_adc_val[1] = -34;
+       st->accel_val = 34;
+       st->accel_calibbias = -7;
+       st->accel_calibscale = &dummy_scales[0];
+       st->steps = 47;
+       st->activity_running = 98;
+       st->activity_walking = 4;
+
+       return 0;
+}
+
+/**
+ * iio_dummy_probe() - device instance probe
+ * @index: an id number for this instance.
+ *
+ * Arguments are bus type specific.
+ * I2C: iio_dummy_probe(struct i2c_client *client,
+ *                      const struct i2c_device_id *id)
+ * SPI: iio_dummy_probe(struct spi_device *spi)
+ */
+static int iio_dummy_probe(int index)
+{
+       int ret;
+       struct iio_dev *indio_dev;
+       struct iio_dummy_state *st;
+
+       /*
+        * Allocate an IIO device.
+        *
+        * This structure contains all generic state
+        * information about the device instance.
+        * It also has a region (accessed by iio_priv()
+        * for chip specific state information.
+        */
+       indio_dev = iio_device_alloc(sizeof(*st));
+       if (!indio_dev) {
+               ret = -ENOMEM;
+               goto error_ret;
+       }
+
+       st = iio_priv(indio_dev);
+       mutex_init(&st->lock);
+
+       iio_dummy_init_device(indio_dev);
+       /*
+        * With hardware: Set the parent device.
+        * indio_dev->dev.parent = &spi->dev;
+        * indio_dev->dev.parent = &client->dev;
+        */
+
+        /*
+        * Make the iio_dev struct available to remove function.
+        * Bus equivalents
+        * i2c_set_clientdata(client, indio_dev);
+        * spi_set_drvdata(spi, indio_dev);
+        */
+       iio_dummy_devs[index] = indio_dev;
+
+       /*
+        * Set the device name.
+        *
+        * This is typically a part number and obtained from the module
+        * id table.
+        * e.g. for i2c and spi:
+        *    indio_dev->name = id->name;
+        *    indio_dev->name = spi_get_device_id(spi)->name;
+        */
+       indio_dev->name = iio_dummy_part_number;
+
+       /* Provide description of available channels */
+       indio_dev->channels = iio_dummy_channels;
+       indio_dev->num_channels = ARRAY_SIZE(iio_dummy_channels);
+
+       /*
+        * Provide device type specific interface functions and
+        * constant data.
+        */
+       indio_dev->info = &iio_dummy_info;
+
+       /* Specify that device provides sysfs type interfaces */
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       ret = iio_simple_dummy_events_register(indio_dev);
+       if (ret < 0)
+               goto error_free_device;
+
+       ret = iio_simple_dummy_configure_buffer(indio_dev);
+       if (ret < 0)
+               goto error_unregister_events;
+
+       ret = iio_device_register(indio_dev);
+       if (ret < 0)
+               goto error_unconfigure_buffer;
+
+       return 0;
+error_unconfigure_buffer:
+       iio_simple_dummy_unconfigure_buffer(indio_dev);
+error_unregister_events:
+       iio_simple_dummy_events_unregister(indio_dev);
+error_free_device:
+       iio_device_free(indio_dev);
+error_ret:
+       return ret;
+}
+
+/**
+ * iio_dummy_remove() - device instance removal function
+ * @index: device index.
+ *
+ * Parameters follow those of iio_dummy_probe for buses.
+ */
+static void iio_dummy_remove(int index)
+{
+       /*
+        * Get a pointer to the device instance iio_dev structure
+        * from the bus subsystem. E.g.
+        * struct iio_dev *indio_dev = i2c_get_clientdata(client);
+        * struct iio_dev *indio_dev = spi_get_drvdata(spi);
+        */
+       struct iio_dev *indio_dev = iio_dummy_devs[index];
+
+       /* Unregister the device */
+       iio_device_unregister(indio_dev);
+
+       /* Device specific code to power down etc */
+
+       /* Buffered capture related cleanup */
+       iio_simple_dummy_unconfigure_buffer(indio_dev);
+
+       iio_simple_dummy_events_unregister(indio_dev);
+
+       /* Free all structures */
+       iio_device_free(indio_dev);
+}
+
+/**
+ * iio_dummy_init() -  device driver registration
+ *
+ * Varies depending on bus type of the device. As there is no device
+ * here, call probe directly. For information on device registration
+ * i2c:
+ * Documentation/i2c/writing-clients
+ * spi:
+ * Documentation/spi/spi-summary
+ */
+static __init int iio_dummy_init(void)
+{
+       int i, ret;
+
+       if (instances > 10) {
+               instances = 1;
+               return -EINVAL;
+       }
+
+       /* Fake a bus */
+       iio_dummy_devs = kcalloc(instances, sizeof(*iio_dummy_devs),
+                                GFP_KERNEL);
+       /* Here we have no actual device so call probe */
+       for (i = 0; i < instances; i++) {
+               ret = iio_dummy_probe(i);
+               if (ret < 0)
+                       goto error_remove_devs;
+       }
+       return 0;
+
+error_remove_devs:
+       while (i--)
+               iio_dummy_remove(i);
+
+       kfree(iio_dummy_devs);
+       return ret;
+}
+module_init(iio_dummy_init);
+
+/**
+ * iio_dummy_exit() - device driver removal
+ *
+ * Varies depending on bus type of the device.
+ * As there is no device here, call remove directly.
+ */
+static __exit void iio_dummy_exit(void)
+{
+       int i;
+
+       for (i = 0; i < instances; i++)
+               iio_dummy_remove(i);
+       kfree(iio_dummy_devs);
+}
+module_exit(iio_dummy_exit);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
+MODULE_DESCRIPTION("IIO dummy driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dummy/iio_simple_dummy.h b/drivers/iio/dummy/iio_simple_dummy.h
new file mode 100644 (file)
index 0000000..5c2f4d0
--- /dev/null
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2011 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * Join together the various functionality of iio_simple_dummy driver
+ */
+
+#ifndef _IIO_SIMPLE_DUMMY_H_
+#define _IIO_SIMPLE_DUMMY_H_
+#include <linux/kernel.h>
+
+struct iio_dummy_accel_calibscale;
+struct iio_dummy_regs;
+
+/**
+ * struct iio_dummy_state - device instance specific state.
+ * @dac_val:                   cache for dac value
+ * @single_ended_adc_val:      cache for single ended adc value
+ * @differential_adc_val:      cache for differential adc value
+ * @accel_val:                 cache for acceleration value
+ * @accel_calibbias:           cache for acceleration calibbias
+ * @accel_calibscale:          cache for acceleration calibscale
+ * @lock:                      lock to ensure state is consistent
+ * @event_irq:                 irq number for event line (faked)
+ * @event_val:                 cache for event threshold value
+ * @event_en:                  cache of whether event is enabled
+ */
+struct iio_dummy_state {
+       int dac_val;
+       int single_ended_adc_val;
+       int differential_adc_val[2];
+       int accel_val;
+       int accel_calibbias;
+       int activity_running;
+       int activity_walking;
+       const struct iio_dummy_accel_calibscale *accel_calibscale;
+       struct mutex lock;
+       struct iio_dummy_regs *regs;
+       int steps_enabled;
+       int steps;
+       int height;
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+       int event_irq;
+       int event_val;
+       bool event_en;
+       s64 event_timestamp;
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
+};
+
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+
+struct iio_dev;
+
+int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir);
+
+int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
+                                       const struct iio_chan_spec *chan,
+                                       enum iio_event_type type,
+                                       enum iio_event_direction dir,
+                                       int state);
+
+int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
+                                     const struct iio_chan_spec *chan,
+                                     enum iio_event_type type,
+                                     enum iio_event_direction dir,
+                                     enum iio_event_info info, int *val,
+                                     int *val2);
+
+int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir,
+                                      enum iio_event_info info, int val,
+                                      int val2);
+
+int iio_simple_dummy_events_register(struct iio_dev *indio_dev);
+void iio_simple_dummy_events_unregister(struct iio_dev *indio_dev);
+
+#else /* Stubs for when events are disabled at compile time */
+
+static inline int
+iio_simple_dummy_events_register(struct iio_dev *indio_dev)
+{
+       return 0;
+};
+
+static inline void
+iio_simple_dummy_events_unregister(struct iio_dev *indio_dev)
+{ };
+
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS*/
+
+/**
+ * enum iio_simple_dummy_scan_elements - scan index enum
+ * @voltage0:          the single ended voltage channel
+ * @diffvoltage1m2:    first differential channel
+ * @diffvoltage3m4:    second differenial channel
+ * @accelx:            acceleration channel
+ *
+ * Enum provides convenient numbering for the scan index.
+ */
+enum iio_simple_dummy_scan_elements {
+       voltage0,
+       diffvoltage1m2,
+       diffvoltage3m4,
+       accelx,
+};
+
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_BUFFER
+int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev);
+void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev);
+#else
+static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
+{
+       return 0;
+};
+
+static inline
+void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
+{};
+
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_BUFFER */
+#endif /* _IIO_SIMPLE_DUMMY_H_ */
diff --git a/drivers/iio/dummy/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c
new file mode 100644 (file)
index 0000000..00ed774
--- /dev/null
@@ -0,0 +1,192 @@
+/**
+ * Copyright (c) 2011 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * Buffer handling elements of industrial I/O reference driver.
+ * Uses the kfifo buffer.
+ *
+ * To test without hardware use the sysfs trigger.
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/bitmap.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/kfifo_buf.h>
+
+#include "iio_simple_dummy.h"
+
+/* Some fake data */
+
+static const s16 fakedata[] = {
+       [voltage0] = 7,
+       [diffvoltage1m2] = -33,
+       [diffvoltage3m4] = -2,
+       [accelx] = 344,
+};
+
+/**
+ * iio_simple_dummy_trigger_h() - the trigger handler function
+ * @irq: the interrupt number
+ * @p: private data - always a pointer to the poll func.
+ *
+ * This is the guts of buffered capture. On a trigger event occurring,
+ * if the pollfunc is attached then this handler is called as a threaded
+ * interrupt (and hence may sleep). It is responsible for grabbing data
+ * from the device and pushing it into the associated buffer.
+ */
+static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       int len = 0;
+       u16 *data;
+
+       data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+       if (!data)
+               goto done;
+
+       if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) {
+               /*
+                * Three common options here:
+                * hardware scans: certain combinations of channels make
+                *   up a fast read.  The capture will consist of all of them.
+                *   Hence we just call the grab data function and fill the
+                *   buffer without processing.
+                * software scans: can be considered to be random access
+                *   so efficient reading is just a case of minimal bus
+                *   transactions.
+                * software culled hardware scans:
+                *   occasionally a driver may process the nearest hardware
+                *   scan to avoid storing elements that are not desired. This
+                *   is the fiddliest option by far.
+                * Here let's pretend we have random access. And the values are
+                * in the constant table fakedata.
+                */
+               int i, j;
+
+               for (i = 0, j = 0;
+                    i < bitmap_weight(indio_dev->active_scan_mask,
+                                      indio_dev->masklength);
+                    i++, j++) {
+                       j = find_next_bit(indio_dev->active_scan_mask,
+                                         indio_dev->masklength, j);
+                       /* random access read from the 'device' */
+                       data[i] = fakedata[j];
+                       len += 2;
+               }
+       }
+
+       iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns());
+
+       kfree(data);
+
+done:
+       /*
+        * Tell the core we are done with this trigger and ready for the
+        * next one.
+        */
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
+       /*
+        * iio_triggered_buffer_postenable:
+        * Generic function that simply attaches the pollfunc to the trigger.
+        * Replace this to mess with hardware state before we attach the
+        * trigger.
+        */
+       .postenable = &iio_triggered_buffer_postenable,
+       /*
+        * iio_triggered_buffer_predisable:
+        * Generic function that simple detaches the pollfunc from the trigger.
+        * Replace this to put hardware state back again after the trigger is
+        * detached but before userspace knows we have disabled the ring.
+        */
+       .predisable = &iio_triggered_buffer_predisable,
+};
+
+int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
+{
+       int ret;
+       struct iio_buffer *buffer;
+
+       /* Allocate a buffer to use - here a kfifo */
+       buffer = iio_kfifo_allocate();
+       if (!buffer) {
+               ret = -ENOMEM;
+               goto error_ret;
+       }
+
+       iio_device_attach_buffer(indio_dev, buffer);
+
+       /* Enable timestamps by default */
+       buffer->scan_timestamp = true;
+
+       /*
+        * Tell the core what device type specific functions should
+        * be run on either side of buffer capture enable / disable.
+        */
+       indio_dev->setup_ops = &iio_simple_dummy_buffer_setup_ops;
+
+       /*
+        * Configure a polling function.
+        * When a trigger event with this polling function connected
+        * occurs, this function is run. Typically this grabs data
+        * from the device.
+        *
+        * NULL for the bottom half. This is normally implemented only if we
+        * either want to ping a capture now pin (no sleeping) or grab
+        * a timestamp as close as possible to a data ready trigger firing.
+        *
+        * IRQF_ONESHOT ensures irqs are masked such that only one instance
+        * of the handler can run at a time.
+        *
+        * "iio_simple_dummy_consumer%d" formatting string for the irq 'name'
+        * as seen under /proc/interrupts. Remaining parameters as per printk.
+        */
+       indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
+                                                &iio_simple_dummy_trigger_h,
+                                                IRQF_ONESHOT,
+                                                indio_dev,
+                                                "iio_simple_dummy_consumer%d",
+                                                indio_dev->id);
+
+       if (!indio_dev->pollfunc) {
+               ret = -ENOMEM;
+               goto error_free_buffer;
+       }
+
+       /*
+        * Notify the core that this device is capable of buffered capture
+        * driven by a trigger.
+        */
+       indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
+
+       return 0;
+
+error_free_buffer:
+       iio_kfifo_free(indio_dev->buffer);
+error_ret:
+       return ret;
+}
+
+/**
+ * iio_simple_dummy_unconfigure_buffer() - release buffer resources
+ * @indo_dev: device instance state
+ */
+void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
+{
+       iio_dealloc_pollfunc(indio_dev->pollfunc);
+       iio_kfifo_free(indio_dev->buffer);
+}
diff --git a/drivers/iio/dummy/iio_simple_dummy_events.c b/drivers/iio/dummy/iio_simple_dummy_events.c
new file mode 100644 (file)
index 0000000..bfbf1c5
--- /dev/null
@@ -0,0 +1,276 @@
+/**
+ * Copyright (c) 2011 Jonathan Cameron
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * Event handling elements of industrial I/O reference driver.
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+#include "iio_simple_dummy.h"
+
+/* Evgen 'fakes' interrupt events for this example */
+#include "iio_dummy_evgen.h"
+
+/**
+ * iio_simple_dummy_read_event_config() - is event enabled?
+ * @indio_dev: the device instance data
+ * @chan: channel for the event whose state is being queried
+ * @type: type of the event whose state is being queried
+ * @dir: direction of the vent whose state is being queried
+ *
+ * This function would normally query the relevant registers or a cache to
+ * discover if the event generation is enabled on the device.
+ */
+int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir)
+{
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+
+       return st->event_en;
+}
+
+/**
+ * iio_simple_dummy_write_event_config() - set whether event is enabled
+ * @indio_dev: the device instance data
+ * @chan: channel for the event whose state is being set
+ * @type: type of the event whose state is being set
+ * @dir: direction of the vent whose state is being set
+ * @state: whether to enable or disable the device.
+ *
+ * This function would normally set the relevant registers on the devices
+ * so that it generates the specified event. Here it just sets up a cached
+ * value.
+ */
+int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
+                                       const struct iio_chan_spec *chan,
+                                       enum iio_event_type type,
+                                       enum iio_event_direction dir,
+                                       int state)
+{
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+
+       /*
+        *  Deliberately over the top code splitting to illustrate
+        * how this is done when multiple events exist.
+        */
+       switch (chan->type) {
+       case IIO_VOLTAGE:
+               switch (type) {
+               case IIO_EV_TYPE_THRESH:
+                       if (dir == IIO_EV_DIR_RISING)
+                               st->event_en = state;
+                       else
+                               return -EINVAL;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       case IIO_ACTIVITY:
+               switch (type) {
+               case IIO_EV_TYPE_THRESH:
+                       st->event_en = state;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       case IIO_STEPS:
+               switch (type) {
+               case IIO_EV_TYPE_CHANGE:
+                       st->event_en = state;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/**
+ * iio_simple_dummy_read_event_value() - get value associated with event
+ * @indio_dev: device instance specific data
+ * @chan: channel for the event whose value is being read
+ * @type: type of the event whose value is being read
+ * @dir: direction of the vent whose value is being read
+ * @info: info type of the event whose value is being read
+ * @val: value for the event code.
+ *
+ * Many devices provide a large set of events of which only a subset may
+ * be enabled at a time, with value registers whose meaning changes depending
+ * on the event enabled. This often means that the driver must cache the values
+ * associated with each possible events so that the right value is in place when
+ * the enabled event is changed.
+ */
+int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
+                                     const struct iio_chan_spec *chan,
+                                     enum iio_event_type type,
+                                     enum iio_event_direction dir,
+                                     enum iio_event_info info,
+                                     int *val, int *val2)
+{
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+
+       *val = st->event_val;
+
+       return IIO_VAL_INT;
+}
+
+/**
+ * iio_simple_dummy_write_event_value() - set value associate with event
+ * @indio_dev: device instance specific data
+ * @chan: channel for the event whose value is being set
+ * @type: type of the event whose value is being set
+ * @dir: direction of the vent whose value is being set
+ * @info: info type of the event whose value is being set
+ * @val: the value to be set.
+ */
+int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir,
+                                      enum iio_event_info info,
+                                      int val, int val2)
+{
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+
+       st->event_val = val;
+
+       return 0;
+}
+
+static irqreturn_t iio_simple_dummy_get_timestamp(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+
+       st->event_timestamp = iio_get_time_ns();
+       return IRQ_HANDLED;
+}
+
+/**
+ * iio_simple_dummy_event_handler() - identify and pass on event
+ * @irq: irq of event line
+ * @private: pointer to device instance state.
+ *
+ * This handler is responsible for querying the device to find out what
+ * event occurred and for then pushing that event towards userspace.
+ * Here only one event occurs so we push that directly on with locally
+ * grabbed timestamp.
+ */
+static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+
+       dev_dbg(&indio_dev->dev, "id %x event %x\n",
+               st->regs->reg_id, st->regs->reg_data);
+
+       switch (st->regs->reg_data) {
+       case 0:
+               iio_push_event(indio_dev,
+                              IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
+                                             IIO_EV_DIR_RISING,
+                                             IIO_EV_TYPE_THRESH, 0, 0, 0),
+                              st->event_timestamp);
+               break;
+       case 1:
+               if (st->activity_running > st->event_val)
+                       iio_push_event(indio_dev,
+                                      IIO_EVENT_CODE(IIO_ACTIVITY, 0,
+                                                     IIO_MOD_RUNNING,
+                                                     IIO_EV_DIR_RISING,
+                                                     IIO_EV_TYPE_THRESH,
+                                                     0, 0, 0),
+                                      st->event_timestamp);
+               break;
+       case 2:
+               if (st->activity_walking < st->event_val)
+                       iio_push_event(indio_dev,
+                                      IIO_EVENT_CODE(IIO_ACTIVITY, 0,
+                                                     IIO_MOD_WALKING,
+                                                     IIO_EV_DIR_FALLING,
+                                                     IIO_EV_TYPE_THRESH,
+                                                     0, 0, 0),
+                                      st->event_timestamp);
+               break;
+       case 3:
+               iio_push_event(indio_dev,
+                              IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
+                                             IIO_EV_DIR_NONE,
+                                             IIO_EV_TYPE_CHANGE, 0, 0, 0),
+                              st->event_timestamp);
+               break;
+       default:
+               break;
+       }
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * iio_simple_dummy_events_register() - setup interrupt handling for events
+ * @indio_dev: device instance data
+ *
+ * This function requests the threaded interrupt to handle the events.
+ * Normally the irq is a hardware interrupt and the number comes
+ * from board configuration files.  Here we get it from a companion
+ * module that fakes the interrupt for us. Note that module in
+ * no way forms part of this example. Just assume that events magically
+ * appear via the provided interrupt.
+ */
+int iio_simple_dummy_events_register(struct iio_dev *indio_dev)
+{
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+       int ret;
+
+       /* Fire up event source - normally not present */
+       st->event_irq = iio_dummy_evgen_get_irq();
+       if (st->event_irq < 0) {
+               ret = st->event_irq;
+               goto error_ret;
+       }
+       st->regs = iio_dummy_evgen_get_regs(st->event_irq);
+
+       ret = request_threaded_irq(st->event_irq,
+                                  &iio_simple_dummy_get_timestamp,
+                                  &iio_simple_dummy_event_handler,
+                                  IRQF_ONESHOT,
+                                  "iio_simple_event",
+                                  indio_dev);
+       if (ret < 0)
+               goto error_free_evgen;
+       return 0;
+
+error_free_evgen:
+       iio_dummy_evgen_release_irq(st->event_irq);
+error_ret:
+       return ret;
+}
+
+/**
+ * iio_simple_dummy_events_unregister() - tidy up interrupt handling on remove
+ * @indio_dev: device instance data
+ */
+void iio_simple_dummy_events_unregister(struct iio_dev *indio_dev)
+{
+       struct iio_dummy_state *st = iio_priv(indio_dev);
+
+       free_irq(st->event_irq, indio_dev);
+       /* Not part of normal driver */
+       iio_dummy_evgen_release_irq(st->event_irq);
+}
index 6d5b38d..85de198 100644 (file)
@@ -17,32 +17,32 @@ source "drivers/staging/iio/meter/Kconfig"
 source "drivers/staging/iio/resolver/Kconfig"
 source "drivers/staging/iio/trigger/Kconfig"
 
-config IIO_DUMMY_EVGEN
-       tristate
-
-config IIO_SIMPLE_DUMMY
-       tristate "An example driver with no hardware requirements"
-       help
-        Driver intended mainly as documentation for how to write
-        a driver. May also be useful for testing userspace code
-        without hardware.
-
-if IIO_SIMPLE_DUMMY
-
-config IIO_SIMPLE_DUMMY_EVENTS
-       bool "Event generation support"
-       select IIO_DUMMY_EVGEN
-       help
-         Add some dummy events to the simple dummy driver.
-
-config IIO_SIMPLE_DUMMY_BUFFER
-       bool "Buffered capture support"
-       select IIO_BUFFER
-       select IIO_TRIGGER
-       select IIO_KFIFO_BUF
-       help
-         Add buffered data capture to the simple dummy driver.
-
-endif # IIO_SIMPLE_DUMMY
+#config IIO_DUMMY_EVGEN
+#       tristate
+#
+#config IIO_SIMPLE_DUMMY
+#       tristate "An example driver with no hardware requirements"
+#       help
+#       Driver intended mainly as documentation for how to write
+#       a driver. May also be useful for testing userspace code
+#       without hardware.
+
+#if IIO_SIMPLE_DUMMY
+
+#config IIO_SIMPLE_DUMMY_EVENTS
+#       bool "Event generation support"
+#       select IIO_DUMMY_EVGEN
+#      help
+#        Add some dummy events to the simple dummy driver.
+
+#config IIO_SIMPLE_DUMMY_BUFFER
+#      bool "Buffered capture support"
+#      select IIO_BUFFER
+# select IIO_TRIGGER
+#      select IIO_KFIFO_BUF
+#      help
+#        Add buffered data capture to the simple dummy driver.
+
+#endif # IIO_SIMPLE_DUMMY
 
 endmenu
index d871061..355824a 100644 (file)
@@ -2,12 +2,12 @@
 # Makefile for the industrial I/O core.
 #
 
-obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o
-iio_dummy-y := iio_simple_dummy.o
-iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_EVENTS) += iio_simple_dummy_events.o
-iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_BUFFER) += iio_simple_dummy_buffer.o
+#obj-$(CONFIG_IIO_SIMPLE_DUMMY) += iio_dummy.o
+#iio_dummy-y := iio_simple_dummy.o
+#iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_EVENTS) += iio_simple_dummy_events.o
+#iio_dummy-$(CONFIG_IIO_SIMPLE_DUMMY_BUFFER) += iio_simple_dummy_buffer.o
 
-obj-$(CONFIG_IIO_DUMMY_EVGEN) += iio_dummy_evgen.o
+#obj-$(CONFIG_IIO_DUMMY_EVGEN) += iio_dummy_evgen.o
 
 obj-y += accel/
 obj-y += adc/
diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c
deleted file mode 100644 (file)
index 9e83f34..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
- * Copyright (c) 2011 Jonathan Cameron
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * Companion module to the iio simple dummy example driver.
- * The purpose of this is to generate 'fake' event interrupts thus
- * allowing that driver's code to be as close as possible to that of
- * a normal driver talking to hardware.  The approach used here
- * is not intended to be general and just happens to work for this
- * particular use case.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-#include <linux/sysfs.h>
-
-#include "iio_dummy_evgen.h"
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/irq_work.h>
-
-/* Fiddly bit of faking and irq without hardware */
-#define IIO_EVENTGEN_NO 10
-
-/**
- * struct iio_dummy_handle_irq - helper struct to simulate interrupt generation
- * @work: irq_work used to run handlers from hardirq context
- * @irq: fake irq line number to trigger an interrupt
- */
-struct iio_dummy_handle_irq {
-       struct irq_work work;
-       int irq;
-};
-
-/**
- * struct iio_dummy_evgen - evgen state
- * @chip: irq chip we are faking
- * @base: base of irq range
- * @enabled: mask of which irqs are enabled
- * @inuse: mask of which irqs are connected
- * @regs: irq regs we are faking
- * @lock: protect the evgen state
- * @handler: helper for a 'hardware-like' interrupt simulation
- */
-struct iio_dummy_eventgen {
-       struct irq_chip chip;
-       int base;
-       bool enabled[IIO_EVENTGEN_NO];
-       bool inuse[IIO_EVENTGEN_NO];
-       struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
-       struct mutex lock;
-       struct iio_dummy_handle_irq handler;
-};
-
-/* We can only ever have one instance of this 'device' */
-static struct iio_dummy_eventgen *iio_evgen;
-static const char *iio_evgen_name = "iio_dummy_evgen";
-
-static void iio_dummy_event_irqmask(struct irq_data *d)
-{
-       struct irq_chip *chip = irq_data_get_irq_chip(d);
-       struct iio_dummy_eventgen *evgen =
-               container_of(chip, struct iio_dummy_eventgen, chip);
-
-       evgen->enabled[d->irq - evgen->base] = false;
-}
-
-static void iio_dummy_event_irqunmask(struct irq_data *d)
-{
-       struct irq_chip *chip = irq_data_get_irq_chip(d);
-       struct iio_dummy_eventgen *evgen =
-               container_of(chip, struct iio_dummy_eventgen, chip);
-
-       evgen->enabled[d->irq - evgen->base] = true;
-}
-
-static void iio_dummy_work_handler(struct irq_work *work)
-{
-       struct iio_dummy_handle_irq *irq_handler;
-
-       irq_handler = container_of(work, struct iio_dummy_handle_irq, work);
-       handle_simple_irq(irq_to_desc(irq_handler->irq));
-}
-
-static int iio_dummy_evgen_create(void)
-{
-       int ret, i;
-
-       iio_evgen = kzalloc(sizeof(*iio_evgen), GFP_KERNEL);
-       if (!iio_evgen)
-               return -ENOMEM;
-
-       iio_evgen->base = irq_alloc_descs(-1, 0, IIO_EVENTGEN_NO, 0);
-       if (iio_evgen->base < 0) {
-               ret = iio_evgen->base;
-               kfree(iio_evgen);
-               return ret;
-       }
-       iio_evgen->chip.name = iio_evgen_name;
-       iio_evgen->chip.irq_mask = &iio_dummy_event_irqmask;
-       iio_evgen->chip.irq_unmask = &iio_dummy_event_irqunmask;
-       for (i = 0; i < IIO_EVENTGEN_NO; i++) {
-               irq_set_chip(iio_evgen->base + i, &iio_evgen->chip);
-               irq_set_handler(iio_evgen->base + i, &handle_simple_irq);
-               irq_modify_status(iio_evgen->base + i,
-                                 IRQ_NOREQUEST | IRQ_NOAUTOEN,
-                                 IRQ_NOPROBE);
-       }
-       init_irq_work(&iio_evgen->handler.work, iio_dummy_work_handler);
-       mutex_init(&iio_evgen->lock);
-       return 0;
-}
-
-/**
- * iio_dummy_evgen_get_irq() - get an evgen provided irq for a device
- *
- * This function will give a free allocated irq to a client device.
- * That irq can then be caused to 'fire' by using the associated sysfs file.
- */
-int iio_dummy_evgen_get_irq(void)
-{
-       int i, ret = 0;
-
-       if (!iio_evgen)
-               return -ENODEV;
-
-       mutex_lock(&iio_evgen->lock);
-       for (i = 0; i < IIO_EVENTGEN_NO; i++)
-               if (!iio_evgen->inuse[i]) {
-                       ret = iio_evgen->base + i;
-                       iio_evgen->inuse[i] = true;
-                       break;
-               }
-       mutex_unlock(&iio_evgen->lock);
-       if (i == IIO_EVENTGEN_NO)
-               return -ENOMEM;
-       return ret;
-}
-EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_irq);
-
-/**
- * iio_dummy_evgen_release_irq() - give the irq back.
- * @irq: irq being returned to the pool
- *
- * Used by client driver instances to give the irqs back when they disconnect
- */
-void iio_dummy_evgen_release_irq(int irq)
-{
-       mutex_lock(&iio_evgen->lock);
-       iio_evgen->inuse[irq - iio_evgen->base] = false;
-       mutex_unlock(&iio_evgen->lock);
-}
-EXPORT_SYMBOL_GPL(iio_dummy_evgen_release_irq);
-
-struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq)
-{
-       return &iio_evgen->regs[irq - iio_evgen->base];
-}
-EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs);
-
-static void iio_dummy_evgen_free(void)
-{
-       irq_free_descs(iio_evgen->base, IIO_EVENTGEN_NO);
-       kfree(iio_evgen);
-}
-
-static void iio_evgen_release(struct device *dev)
-{
-       iio_dummy_evgen_free();
-}
-
-static ssize_t iio_evgen_poke(struct device *dev,
-                             struct device_attribute *attr,
-                             const char *buf,
-                             size_t len)
-{
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       unsigned long event;
-       int ret;
-
-       ret = kstrtoul(buf, 10, &event);
-       if (ret)
-               return ret;
-
-       iio_evgen->regs[this_attr->address].reg_id   = this_attr->address;
-       iio_evgen->regs[this_attr->address].reg_data = event;
-
-       iio_evgen->handler.irq = iio_evgen->base + this_attr->address;
-       if (iio_evgen->enabled[this_attr->address])
-               irq_work_queue(&iio_evgen->handler.work);
-
-       return len;
-}
-
-static IIO_DEVICE_ATTR(poke_ev0, S_IWUSR, NULL, &iio_evgen_poke, 0);
-static IIO_DEVICE_ATTR(poke_ev1, S_IWUSR, NULL, &iio_evgen_poke, 1);
-static IIO_DEVICE_ATTR(poke_ev2, S_IWUSR, NULL, &iio_evgen_poke, 2);
-static IIO_DEVICE_ATTR(poke_ev3, S_IWUSR, NULL, &iio_evgen_poke, 3);
-static IIO_DEVICE_ATTR(poke_ev4, S_IWUSR, NULL, &iio_evgen_poke, 4);
-static IIO_DEVICE_ATTR(poke_ev5, S_IWUSR, NULL, &iio_evgen_poke, 5);
-static IIO_DEVICE_ATTR(poke_ev6, S_IWUSR, NULL, &iio_evgen_poke, 6);
-static IIO_DEVICE_ATTR(poke_ev7, S_IWUSR, NULL, &iio_evgen_poke, 7);
-static IIO_DEVICE_ATTR(poke_ev8, S_IWUSR, NULL, &iio_evgen_poke, 8);
-static IIO_DEVICE_ATTR(poke_ev9, S_IWUSR, NULL, &iio_evgen_poke, 9);
-
-static struct attribute *iio_evgen_attrs[] = {
-       &iio_dev_attr_poke_ev0.dev_attr.attr,
-       &iio_dev_attr_poke_ev1.dev_attr.attr,
-       &iio_dev_attr_poke_ev2.dev_attr.attr,
-       &iio_dev_attr_poke_ev3.dev_attr.attr,
-       &iio_dev_attr_poke_ev4.dev_attr.attr,
-       &iio_dev_attr_poke_ev5.dev_attr.attr,
-       &iio_dev_attr_poke_ev6.dev_attr.attr,
-       &iio_dev_attr_poke_ev7.dev_attr.attr,
-       &iio_dev_attr_poke_ev8.dev_attr.attr,
-       &iio_dev_attr_poke_ev9.dev_attr.attr,
-       NULL,
-};
-
-static const struct attribute_group iio_evgen_group = {
-       .attrs = iio_evgen_attrs,
-};
-
-static const struct attribute_group *iio_evgen_groups[] = {
-       &iio_evgen_group,
-       NULL
-};
-
-static struct device iio_evgen_dev = {
-       .bus = &iio_bus_type,
-       .groups = iio_evgen_groups,
-       .release = &iio_evgen_release,
-};
-
-static __init int iio_dummy_evgen_init(void)
-{
-       int ret = iio_dummy_evgen_create();
-
-       if (ret < 0)
-               return ret;
-       device_initialize(&iio_evgen_dev);
-       dev_set_name(&iio_evgen_dev, "iio_evgen");
-       return device_add(&iio_evgen_dev);
-}
-module_init(iio_dummy_evgen_init);
-
-static __exit void iio_dummy_evgen_exit(void)
-{
-       device_unregister(&iio_evgen_dev);
-}
-module_exit(iio_dummy_evgen_exit);
-
-MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
-MODULE_DESCRIPTION("IIO dummy driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/iio_dummy_evgen.h b/drivers/staging/iio/iio_dummy_evgen.h
deleted file mode 100644 (file)
index d044b94..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _IIO_DUMMY_EVGEN_H_
-#define _IIO_DUMMY_EVGEN_H_
-
-struct iio_dummy_regs {
-       u32 reg_id;
-       u32 reg_data;
-};
-
-struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq);
-int iio_dummy_evgen_get_irq(void);
-void iio_dummy_evgen_release_irq(int irq);
-
-#endif /* _IIO_DUMMY_EVGEN_H_ */
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
deleted file mode 100644 (file)
index 381f90f..0000000
+++ /dev/null
@@ -1,748 +0,0 @@
-/**
- * Copyright (c) 2011 Jonathan Cameron
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * A reference industrial I/O driver to illustrate the functionality available.
- *
- * There are numerous real drivers to illustrate the finer points.
- * The purpose of this driver is to provide a driver with far more comments
- * and explanatory notes than any 'real' driver would have.
- * Anyone starting out writing an IIO driver should first make sure they
- * understand all of this driver except those bits specifically marked
- * as being present to allow us to 'fake' the presence of hardware.
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/events.h>
-#include <linux/iio/buffer.h>
-#include "iio_simple_dummy.h"
-
-/*
- * A few elements needed to fake a bus for this driver
- * Note instances parameter controls how many of these
- * dummy devices are registered.
- */
-static unsigned instances = 1;
-module_param(instances, uint, 0);
-
-/* Pointer array used to fake bus elements */
-static struct iio_dev **iio_dummy_devs;
-
-/* Fake a name for the part number, usually obtained from the id table */
-static const char *iio_dummy_part_number = "iio_dummy_part_no";
-
-/**
- * struct iio_dummy_accel_calibscale - realworld to register mapping
- * @val: first value in read_raw - here integer part.
- * @val2: second value in read_raw etc - here micro part.
- * @regval: register value - magic device specific numbers.
- */
-struct iio_dummy_accel_calibscale {
-       int val;
-       int val2;
-       int regval; /* what would be written to hardware */
-};
-
-static const struct iio_dummy_accel_calibscale dummy_scales[] = {
-       { 0, 100, 0x8 }, /* 0.000100 */
-       { 0, 133, 0x7 }, /* 0.000133 */
-       { 733, 13, 0x9 }, /* 733.000013 */
-};
-
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-
-/*
- * simple event - triggered when value rises above
- * a threshold
- */
-static const struct iio_event_spec iio_dummy_event = {
-       .type = IIO_EV_TYPE_THRESH,
-       .dir = IIO_EV_DIR_RISING,
-       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
-};
-
-/*
- * simple step detect event - triggered when a step is detected
- */
-static const struct iio_event_spec step_detect_event = {
-       .type = IIO_EV_TYPE_CHANGE,
-       .dir = IIO_EV_DIR_NONE,
-       .mask_separate = BIT(IIO_EV_INFO_ENABLE),
-};
-
-/*
- * simple transition event - triggered when the reported running confidence
- * value rises above a threshold value
- */
-static const struct iio_event_spec iio_running_event = {
-       .type = IIO_EV_TYPE_THRESH,
-       .dir = IIO_EV_DIR_RISING,
-       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
-};
-
-/*
- * simple transition event - triggered when the reported walking confidence
- * value falls under a threshold value
- */
-static const struct iio_event_spec iio_walking_event = {
-       .type = IIO_EV_TYPE_THRESH,
-       .dir = IIO_EV_DIR_FALLING,
-       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
-};
-#endif
-
-/*
- * iio_dummy_channels - Description of available channels
- *
- * This array of structures tells the IIO core about what the device
- * actually provides for a given channel.
- */
-static const struct iio_chan_spec iio_dummy_channels[] = {
-       /* indexed ADC channel in_voltage0_raw etc */
-       {
-               .type = IIO_VOLTAGE,
-               /* Channel has a numeric index of 0 */
-               .indexed = 1,
-               .channel = 0,
-               /* What other information is available? */
-               .info_mask_separate =
-               /*
-                * in_voltage0_raw
-                * Raw (unscaled no bias removal etc) measurement
-                * from the device.
-                */
-               BIT(IIO_CHAN_INFO_RAW) |
-               /*
-                * in_voltage0_offset
-                * Offset for userspace to apply prior to scale
-                * when converting to standard units (microvolts)
-                */
-               BIT(IIO_CHAN_INFO_OFFSET) |
-               /*
-                * in_voltage0_scale
-                * Multipler for userspace to apply post offset
-                * when converting to standard units (microvolts)
-                */
-               BIT(IIO_CHAN_INFO_SCALE),
-               /*
-                * sampling_frequency
-                * The frequency in Hz at which the channels are sampled
-                */
-               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-               /* The ordering of elements in the buffer via an enum */
-               .scan_index = voltage0,
-               .scan_type = { /* Description of storage in buffer */
-                       .sign = 'u', /* unsigned */
-                       .realbits = 13, /* 13 bits */
-                       .storagebits = 16, /* 16 bits used for storage */
-                       .shift = 0, /* zero shift */
-               },
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-               .event_spec = &iio_dummy_event,
-               .num_event_specs = 1,
-#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
-       },
-       /* Differential ADC channel in_voltage1-voltage2_raw etc*/
-       {
-               .type = IIO_VOLTAGE,
-               .differential = 1,
-               /*
-                * Indexing for differential channels uses channel
-                * for the positive part, channel2 for the negative.
-                */
-               .indexed = 1,
-               .channel = 1,
-               .channel2 = 2,
-               /*
-                * in_voltage1-voltage2_raw
-                * Raw (unscaled no bias removal etc) measurement
-                * from the device.
-                */
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-               /*
-                * in_voltage-voltage_scale
-                * Shared version of scale - shared by differential
-                * input channels of type IIO_VOLTAGE.
-                */
-               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
-               /*
-                * sampling_frequency
-                * The frequency in Hz at which the channels are sampled
-                */
-               .scan_index = diffvoltage1m2,
-               .scan_type = { /* Description of storage in buffer */
-                       .sign = 's', /* signed */
-                       .realbits = 12, /* 12 bits */
-                       .storagebits = 16, /* 16 bits used for storage */
-                       .shift = 0, /* zero shift */
-               },
-       },
-       /* Differential ADC channel in_voltage3-voltage4_raw etc*/
-       {
-               .type = IIO_VOLTAGE,
-               .differential = 1,
-               .indexed = 1,
-               .channel = 3,
-               .channel2 = 4,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
-               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-               .scan_index = diffvoltage3m4,
-               .scan_type = {
-                       .sign = 's',
-                       .realbits = 11,
-                       .storagebits = 16,
-                       .shift = 0,
-               },
-       },
-       /*
-        * 'modified' (i.e. axis specified) acceleration channel
-        * in_accel_z_raw
-        */
-       {
-               .type = IIO_ACCEL,
-               .modified = 1,
-               /* Channel 2 is use for modifiers */
-               .channel2 = IIO_MOD_X,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
-               /*
-                * Internal bias and gain correction values. Applied
-                * by the hardware or driver prior to userspace
-                * seeing the readings. Typically part of hardware
-                * calibration.
-                */
-               BIT(IIO_CHAN_INFO_CALIBSCALE) |
-               BIT(IIO_CHAN_INFO_CALIBBIAS),
-               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
-               .scan_index = accelx,
-               .scan_type = { /* Description of storage in buffer */
-                       .sign = 's', /* signed */
-                       .realbits = 16, /* 16 bits */
-                       .storagebits = 16, /* 16 bits used for storage */
-                       .shift = 0, /* zero shift */
-               },
-       },
-       /*
-        * Convenience macro for timestamps. 4 is the index in
-        * the buffer.
-        */
-       IIO_CHAN_SOFT_TIMESTAMP(4),
-       /* DAC channel out_voltage0_raw */
-       {
-               .type = IIO_VOLTAGE,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-               .scan_index = -1, /* No buffer support */
-               .output = 1,
-               .indexed = 1,
-               .channel = 0,
-       },
-       {
-               .type = IIO_STEPS,
-               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_ENABLE) |
-                       BIT(IIO_CHAN_INFO_CALIBHEIGHT),
-               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
-               .scan_index = -1, /* No buffer support */
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-               .event_spec = &step_detect_event,
-               .num_event_specs = 1,
-#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
-       },
-       {
-               .type = IIO_ACTIVITY,
-               .modified = 1,
-               .channel2 = IIO_MOD_RUNNING,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
-               .scan_index = -1, /* No buffer support */
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-               .event_spec = &iio_running_event,
-               .num_event_specs = 1,
-#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
-       },
-       {
-               .type = IIO_ACTIVITY,
-               .modified = 1,
-               .channel2 = IIO_MOD_WALKING,
-               .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
-               .scan_index = -1, /* No buffer support */
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-               .event_spec = &iio_walking_event,
-               .num_event_specs = 1,
-#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
-       },
-};
-
-/**
- * iio_dummy_read_raw() - data read function.
- * @indio_dev: the struct iio_dev associated with this device instance
- * @chan:      the channel whose data is to be read
- * @val:       first element of returned value (typically INT)
- * @val2:      second element of returned value (typically MICRO)
- * @mask:      what we actually want to read as per the info_mask_*
- *             in iio_chan_spec.
- */
-static int iio_dummy_read_raw(struct iio_dev *indio_dev,
-                             struct iio_chan_spec const *chan,
-                             int *val,
-                             int *val2,
-                             long mask)
-{
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-       int ret = -EINVAL;
-
-       mutex_lock(&st->lock);
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW: /* magic value - channel value read */
-               switch (chan->type) {
-               case IIO_VOLTAGE:
-                       if (chan->output) {
-                               /* Set integer part to cached value */
-                               *val = st->dac_val;
-                               ret = IIO_VAL_INT;
-                       } else if (chan->differential) {
-                               if (chan->channel == 1)
-                                       *val = st->differential_adc_val[0];
-                               else
-                                       *val = st->differential_adc_val[1];
-                               ret = IIO_VAL_INT;
-                       } else {
-                               *val = st->single_ended_adc_val;
-                               ret = IIO_VAL_INT;
-                       }
-                       break;
-               case IIO_ACCEL:
-                       *val = st->accel_val;
-                       ret = IIO_VAL_INT;
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case IIO_CHAN_INFO_PROCESSED:
-               switch (chan->type) {
-               case IIO_STEPS:
-                       *val = st->steps;
-                       ret = IIO_VAL_INT;
-                       break;
-               case IIO_ACTIVITY:
-                       switch (chan->channel2) {
-                       case IIO_MOD_RUNNING:
-                               *val = st->activity_running;
-                               ret = IIO_VAL_INT;
-                               break;
-                       case IIO_MOD_WALKING:
-                               *val = st->activity_walking;
-                               ret = IIO_VAL_INT;
-                               break;
-                       default:
-                               break;
-                       }
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case IIO_CHAN_INFO_OFFSET:
-               /* only single ended adc -> 7 */
-               *val = 7;
-               ret = IIO_VAL_INT;
-               break;
-       case IIO_CHAN_INFO_SCALE:
-               switch (chan->type) {
-               case IIO_VOLTAGE:
-                       switch (chan->differential) {
-                       case 0:
-                               /* only single ended adc -> 0.001333 */
-                               *val = 0;
-                               *val2 = 1333;
-                               ret = IIO_VAL_INT_PLUS_MICRO;
-                               break;
-                       case 1:
-                               /* all differential adc channels ->
-                                * 0.000001344 */
-                               *val = 0;
-                               *val2 = 1344;
-                               ret = IIO_VAL_INT_PLUS_NANO;
-                       }
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case IIO_CHAN_INFO_CALIBBIAS:
-               /* only the acceleration axis - read from cache */
-               *val = st->accel_calibbias;
-               ret = IIO_VAL_INT;
-               break;
-       case IIO_CHAN_INFO_CALIBSCALE:
-               *val = st->accel_calibscale->val;
-               *val2 = st->accel_calibscale->val2;
-               ret = IIO_VAL_INT_PLUS_MICRO;
-               break;
-       case IIO_CHAN_INFO_SAMP_FREQ:
-               *val = 3;
-               *val2 = 33;
-               ret = IIO_VAL_INT_PLUS_NANO;
-               break;
-       case IIO_CHAN_INFO_ENABLE:
-               switch (chan->type) {
-               case IIO_STEPS:
-                       *val = st->steps_enabled;
-                       ret = IIO_VAL_INT;
-                       break;
-               default:
-                       break;
-               }
-               break;
-       case IIO_CHAN_INFO_CALIBHEIGHT:
-               switch (chan->type) {
-               case IIO_STEPS:
-                       *val = st->height;
-                       ret = IIO_VAL_INT;
-                       break;
-               default:
-                       break;
-               }
-               break;
-
-       default:
-               break;
-       }
-       mutex_unlock(&st->lock);
-       return ret;
-}
-
-/**
- * iio_dummy_write_raw() - data write function.
- * @indio_dev: the struct iio_dev associated with this device instance
- * @chan:      the channel whose data is to be written
- * @val:       first element of value to set (typically INT)
- * @val2:      second element of value to set (typically MICRO)
- * @mask:      what we actually want to write as per the info_mask_*
- *             in iio_chan_spec.
- *
- * Note that all raw writes are assumed IIO_VAL_INT and info mask elements
- * are assumed to be IIO_INT_PLUS_MICRO unless the callback write_raw_get_fmt
- * in struct iio_info is provided by the driver.
- */
-static int iio_dummy_write_raw(struct iio_dev *indio_dev,
-                              struct iio_chan_spec const *chan,
-                              int val,
-                              int val2,
-                              long mask)
-{
-       int i;
-       int ret = 0;
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-
-       switch (mask) {
-       case IIO_CHAN_INFO_RAW:
-               switch (chan->type) {
-               case IIO_VOLTAGE:
-                       if (chan->output == 0)
-                               return -EINVAL;
-
-                       /* Locking not required as writing single value */
-                       mutex_lock(&st->lock);
-                       st->dac_val = val;
-                       mutex_unlock(&st->lock);
-                       return 0;
-               default:
-                       return -EINVAL;
-               }
-       case IIO_CHAN_INFO_PROCESSED:
-               switch (chan->type) {
-               case IIO_STEPS:
-                       mutex_lock(&st->lock);
-                       st->steps = val;
-                       mutex_unlock(&st->lock);
-                       return 0;
-               case IIO_ACTIVITY:
-                       if (val < 0)
-                               val = 0;
-                       if (val > 100)
-                               val = 100;
-                       switch (chan->channel2) {
-                       case IIO_MOD_RUNNING:
-                               st->activity_running = val;
-                               return 0;
-                       case IIO_MOD_WALKING:
-                               st->activity_walking = val;
-                               return 0;
-                       default:
-                               return -EINVAL;
-                       }
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       case IIO_CHAN_INFO_CALIBSCALE:
-               mutex_lock(&st->lock);
-               /* Compare against table - hard matching here */
-               for (i = 0; i < ARRAY_SIZE(dummy_scales); i++)
-                       if (val == dummy_scales[i].val &&
-                           val2 == dummy_scales[i].val2)
-                               break;
-               if (i == ARRAY_SIZE(dummy_scales))
-                       ret = -EINVAL;
-               else
-                       st->accel_calibscale = &dummy_scales[i];
-               mutex_unlock(&st->lock);
-               return ret;
-       case IIO_CHAN_INFO_CALIBBIAS:
-               mutex_lock(&st->lock);
-               st->accel_calibbias = val;
-               mutex_unlock(&st->lock);
-               return 0;
-       case IIO_CHAN_INFO_ENABLE:
-               switch (chan->type) {
-               case IIO_STEPS:
-                       mutex_lock(&st->lock);
-                       st->steps_enabled = val;
-                       mutex_unlock(&st->lock);
-                       return 0;
-               default:
-                       return -EINVAL;
-               }
-       case IIO_CHAN_INFO_CALIBHEIGHT:
-               switch (chan->type) {
-               case IIO_STEPS:
-                       st->height = val;
-                       return 0;
-               default:
-                       return -EINVAL;
-               }
-
-       default:
-               return -EINVAL;
-       }
-}
-
-/*
- * Device type specific information.
- */
-static const struct iio_info iio_dummy_info = {
-       .driver_module = THIS_MODULE,
-       .read_raw = &iio_dummy_read_raw,
-       .write_raw = &iio_dummy_write_raw,
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-       .read_event_config = &iio_simple_dummy_read_event_config,
-       .write_event_config = &iio_simple_dummy_write_event_config,
-       .read_event_value = &iio_simple_dummy_read_event_value,
-       .write_event_value = &iio_simple_dummy_write_event_value,
-#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
-};
-
-/**
- * iio_dummy_init_device() - device instance specific init
- * @indio_dev: the iio device structure
- *
- * Most drivers have one of these to set up default values,
- * reset the device to known state etc.
- */
-static int iio_dummy_init_device(struct iio_dev *indio_dev)
-{
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-
-       st->dac_val = 0;
-       st->single_ended_adc_val = 73;
-       st->differential_adc_val[0] = 33;
-       st->differential_adc_val[1] = -34;
-       st->accel_val = 34;
-       st->accel_calibbias = -7;
-       st->accel_calibscale = &dummy_scales[0];
-       st->steps = 47;
-       st->activity_running = 98;
-       st->activity_walking = 4;
-
-       return 0;
-}
-
-/**
- * iio_dummy_probe() - device instance probe
- * @index: an id number for this instance.
- *
- * Arguments are bus type specific.
- * I2C: iio_dummy_probe(struct i2c_client *client,
- *                      const struct i2c_device_id *id)
- * SPI: iio_dummy_probe(struct spi_device *spi)
- */
-static int iio_dummy_probe(int index)
-{
-       int ret;
-       struct iio_dev *indio_dev;
-       struct iio_dummy_state *st;
-
-       /*
-        * Allocate an IIO device.
-        *
-        * This structure contains all generic state
-        * information about the device instance.
-        * It also has a region (accessed by iio_priv()
-        * for chip specific state information.
-        */
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (!indio_dev) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
-
-       st = iio_priv(indio_dev);
-       mutex_init(&st->lock);
-
-       iio_dummy_init_device(indio_dev);
-       /*
-        * With hardware: Set the parent device.
-        * indio_dev->dev.parent = &spi->dev;
-        * indio_dev->dev.parent = &client->dev;
-        */
-
-        /*
-        * Make the iio_dev struct available to remove function.
-        * Bus equivalents
-        * i2c_set_clientdata(client, indio_dev);
-        * spi_set_drvdata(spi, indio_dev);
-        */
-       iio_dummy_devs[index] = indio_dev;
-
-       /*
-        * Set the device name.
-        *
-        * This is typically a part number and obtained from the module
-        * id table.
-        * e.g. for i2c and spi:
-        *    indio_dev->name = id->name;
-        *    indio_dev->name = spi_get_device_id(spi)->name;
-        */
-       indio_dev->name = iio_dummy_part_number;
-
-       /* Provide description of available channels */
-       indio_dev->channels = iio_dummy_channels;
-       indio_dev->num_channels = ARRAY_SIZE(iio_dummy_channels);
-
-       /*
-        * Provide device type specific interface functions and
-        * constant data.
-        */
-       indio_dev->info = &iio_dummy_info;
-
-       /* Specify that device provides sysfs type interfaces */
-       indio_dev->modes = INDIO_DIRECT_MODE;
-
-       ret = iio_simple_dummy_events_register(indio_dev);
-       if (ret < 0)
-               goto error_free_device;
-
-       ret = iio_simple_dummy_configure_buffer(indio_dev);
-       if (ret < 0)
-               goto error_unregister_events;
-
-       ret = iio_device_register(indio_dev);
-       if (ret < 0)
-               goto error_unconfigure_buffer;
-
-       return 0;
-error_unconfigure_buffer:
-       iio_simple_dummy_unconfigure_buffer(indio_dev);
-error_unregister_events:
-       iio_simple_dummy_events_unregister(indio_dev);
-error_free_device:
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
-}
-
-/**
- * iio_dummy_remove() - device instance removal function
- * @index: device index.
- *
- * Parameters follow those of iio_dummy_probe for buses.
- */
-static void iio_dummy_remove(int index)
-{
-       /*
-        * Get a pointer to the device instance iio_dev structure
-        * from the bus subsystem. E.g.
-        * struct iio_dev *indio_dev = i2c_get_clientdata(client);
-        * struct iio_dev *indio_dev = spi_get_drvdata(spi);
-        */
-       struct iio_dev *indio_dev = iio_dummy_devs[index];
-
-       /* Unregister the device */
-       iio_device_unregister(indio_dev);
-
-       /* Device specific code to power down etc */
-
-       /* Buffered capture related cleanup */
-       iio_simple_dummy_unconfigure_buffer(indio_dev);
-
-       iio_simple_dummy_events_unregister(indio_dev);
-
-       /* Free all structures */
-       iio_device_free(indio_dev);
-}
-
-/**
- * iio_dummy_init() -  device driver registration
- *
- * Varies depending on bus type of the device. As there is no device
- * here, call probe directly. For information on device registration
- * i2c:
- * Documentation/i2c/writing-clients
- * spi:
- * Documentation/spi/spi-summary
- */
-static __init int iio_dummy_init(void)
-{
-       int i, ret;
-
-       if (instances > 10) {
-               instances = 1;
-               return -EINVAL;
-       }
-
-       /* Fake a bus */
-       iio_dummy_devs = kcalloc(instances, sizeof(*iio_dummy_devs),
-                                GFP_KERNEL);
-       /* Here we have no actual device so call probe */
-       for (i = 0; i < instances; i++) {
-               ret = iio_dummy_probe(i);
-               if (ret < 0)
-                       goto error_remove_devs;
-       }
-       return 0;
-
-error_remove_devs:
-       while (i--)
-               iio_dummy_remove(i);
-
-       kfree(iio_dummy_devs);
-       return ret;
-}
-module_init(iio_dummy_init);
-
-/**
- * iio_dummy_exit() - device driver removal
- *
- * Varies depending on bus type of the device.
- * As there is no device here, call remove directly.
- */
-static __exit void iio_dummy_exit(void)
-{
-       int i;
-
-       for (i = 0; i < instances; i++)
-               iio_dummy_remove(i);
-       kfree(iio_dummy_devs);
-}
-module_exit(iio_dummy_exit);
-
-MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
-MODULE_DESCRIPTION("IIO dummy driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h
deleted file mode 100644 (file)
index 5c2f4d0..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * Copyright (c) 2011 Jonathan Cameron
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * Join together the various functionality of iio_simple_dummy driver
- */
-
-#ifndef _IIO_SIMPLE_DUMMY_H_
-#define _IIO_SIMPLE_DUMMY_H_
-#include <linux/kernel.h>
-
-struct iio_dummy_accel_calibscale;
-struct iio_dummy_regs;
-
-/**
- * struct iio_dummy_state - device instance specific state.
- * @dac_val:                   cache for dac value
- * @single_ended_adc_val:      cache for single ended adc value
- * @differential_adc_val:      cache for differential adc value
- * @accel_val:                 cache for acceleration value
- * @accel_calibbias:           cache for acceleration calibbias
- * @accel_calibscale:          cache for acceleration calibscale
- * @lock:                      lock to ensure state is consistent
- * @event_irq:                 irq number for event line (faked)
- * @event_val:                 cache for event threshold value
- * @event_en:                  cache of whether event is enabled
- */
-struct iio_dummy_state {
-       int dac_val;
-       int single_ended_adc_val;
-       int differential_adc_val[2];
-       int accel_val;
-       int accel_calibbias;
-       int activity_running;
-       int activity_walking;
-       const struct iio_dummy_accel_calibscale *accel_calibscale;
-       struct mutex lock;
-       struct iio_dummy_regs *regs;
-       int steps_enabled;
-       int steps;
-       int height;
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-       int event_irq;
-       int event_val;
-       bool event_en;
-       s64 event_timestamp;
-#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
-};
-
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-
-struct iio_dev;
-
-int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
-                                      const struct iio_chan_spec *chan,
-                                      enum iio_event_type type,
-                                      enum iio_event_direction dir);
-
-int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
-                                       const struct iio_chan_spec *chan,
-                                       enum iio_event_type type,
-                                       enum iio_event_direction dir,
-                                       int state);
-
-int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
-                                     const struct iio_chan_spec *chan,
-                                     enum iio_event_type type,
-                                     enum iio_event_direction dir,
-                                     enum iio_event_info info, int *val,
-                                     int *val2);
-
-int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
-                                      const struct iio_chan_spec *chan,
-                                      enum iio_event_type type,
-                                      enum iio_event_direction dir,
-                                      enum iio_event_info info, int val,
-                                      int val2);
-
-int iio_simple_dummy_events_register(struct iio_dev *indio_dev);
-void iio_simple_dummy_events_unregister(struct iio_dev *indio_dev);
-
-#else /* Stubs for when events are disabled at compile time */
-
-static inline int
-iio_simple_dummy_events_register(struct iio_dev *indio_dev)
-{
-       return 0;
-};
-
-static inline void
-iio_simple_dummy_events_unregister(struct iio_dev *indio_dev)
-{ };
-
-#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS*/
-
-/**
- * enum iio_simple_dummy_scan_elements - scan index enum
- * @voltage0:          the single ended voltage channel
- * @diffvoltage1m2:    first differential channel
- * @diffvoltage3m4:    second differenial channel
- * @accelx:            acceleration channel
- *
- * Enum provides convenient numbering for the scan index.
- */
-enum iio_simple_dummy_scan_elements {
-       voltage0,
-       diffvoltage1m2,
-       diffvoltage3m4,
-       accelx,
-};
-
-#ifdef CONFIG_IIO_SIMPLE_DUMMY_BUFFER
-int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev);
-void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev);
-#else
-static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
-{
-       return 0;
-};
-
-static inline
-void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
-{};
-
-#endif /* CONFIG_IIO_SIMPLE_DUMMY_BUFFER */
-#endif /* _IIO_SIMPLE_DUMMY_H_ */
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
deleted file mode 100644 (file)
index 00ed774..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/**
- * Copyright (c) 2011 Jonathan Cameron
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * Buffer handling elements of industrial I/O reference driver.
- * Uses the kfifo buffer.
- *
- * To test without hardware use the sysfs trigger.
- */
-
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/bitmap.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/kfifo_buf.h>
-
-#include "iio_simple_dummy.h"
-
-/* Some fake data */
-
-static const s16 fakedata[] = {
-       [voltage0] = 7,
-       [diffvoltage1m2] = -33,
-       [diffvoltage3m4] = -2,
-       [accelx] = 344,
-};
-
-/**
- * iio_simple_dummy_trigger_h() - the trigger handler function
- * @irq: the interrupt number
- * @p: private data - always a pointer to the poll func.
- *
- * This is the guts of buffered capture. On a trigger event occurring,
- * if the pollfunc is attached then this handler is called as a threaded
- * interrupt (and hence may sleep). It is responsible for grabbing data
- * from the device and pushing it into the associated buffer.
- */
-static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
-{
-       struct iio_poll_func *pf = p;
-       struct iio_dev *indio_dev = pf->indio_dev;
-       int len = 0;
-       u16 *data;
-
-       data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
-       if (!data)
-               goto done;
-
-       if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength)) {
-               /*
-                * Three common options here:
-                * hardware scans: certain combinations of channels make
-                *   up a fast read.  The capture will consist of all of them.
-                *   Hence we just call the grab data function and fill the
-                *   buffer without processing.
-                * software scans: can be considered to be random access
-                *   so efficient reading is just a case of minimal bus
-                *   transactions.
-                * software culled hardware scans:
-                *   occasionally a driver may process the nearest hardware
-                *   scan to avoid storing elements that are not desired. This
-                *   is the fiddliest option by far.
-                * Here let's pretend we have random access. And the values are
-                * in the constant table fakedata.
-                */
-               int i, j;
-
-               for (i = 0, j = 0;
-                    i < bitmap_weight(indio_dev->active_scan_mask,
-                                      indio_dev->masklength);
-                    i++, j++) {
-                       j = find_next_bit(indio_dev->active_scan_mask,
-                                         indio_dev->masklength, j);
-                       /* random access read from the 'device' */
-                       data[i] = fakedata[j];
-                       len += 2;
-               }
-       }
-
-       iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns());
-
-       kfree(data);
-
-done:
-       /*
-        * Tell the core we are done with this trigger and ready for the
-        * next one.
-        */
-       iio_trigger_notify_done(indio_dev->trig);
-
-       return IRQ_HANDLED;
-}
-
-static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
-       /*
-        * iio_triggered_buffer_postenable:
-        * Generic function that simply attaches the pollfunc to the trigger.
-        * Replace this to mess with hardware state before we attach the
-        * trigger.
-        */
-       .postenable = &iio_triggered_buffer_postenable,
-       /*
-        * iio_triggered_buffer_predisable:
-        * Generic function that simple detaches the pollfunc from the trigger.
-        * Replace this to put hardware state back again after the trigger is
-        * detached but before userspace knows we have disabled the ring.
-        */
-       .predisable = &iio_triggered_buffer_predisable,
-};
-
-int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
-{
-       int ret;
-       struct iio_buffer *buffer;
-
-       /* Allocate a buffer to use - here a kfifo */
-       buffer = iio_kfifo_allocate();
-       if (!buffer) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
-
-       iio_device_attach_buffer(indio_dev, buffer);
-
-       /* Enable timestamps by default */
-       buffer->scan_timestamp = true;
-
-       /*
-        * Tell the core what device type specific functions should
-        * be run on either side of buffer capture enable / disable.
-        */
-       indio_dev->setup_ops = &iio_simple_dummy_buffer_setup_ops;
-
-       /*
-        * Configure a polling function.
-        * When a trigger event with this polling function connected
-        * occurs, this function is run. Typically this grabs data
-        * from the device.
-        *
-        * NULL for the bottom half. This is normally implemented only if we
-        * either want to ping a capture now pin (no sleeping) or grab
-        * a timestamp as close as possible to a data ready trigger firing.
-        *
-        * IRQF_ONESHOT ensures irqs are masked such that only one instance
-        * of the handler can run at a time.
-        *
-        * "iio_simple_dummy_consumer%d" formatting string for the irq 'name'
-        * as seen under /proc/interrupts. Remaining parameters as per printk.
-        */
-       indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
-                                                &iio_simple_dummy_trigger_h,
-                                                IRQF_ONESHOT,
-                                                indio_dev,
-                                                "iio_simple_dummy_consumer%d",
-                                                indio_dev->id);
-
-       if (!indio_dev->pollfunc) {
-               ret = -ENOMEM;
-               goto error_free_buffer;
-       }
-
-       /*
-        * Notify the core that this device is capable of buffered capture
-        * driven by a trigger.
-        */
-       indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
-
-       return 0;
-
-error_free_buffer:
-       iio_kfifo_free(indio_dev->buffer);
-error_ret:
-       return ret;
-}
-
-/**
- * iio_simple_dummy_unconfigure_buffer() - release buffer resources
- * @indo_dev: device instance state
- */
-void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
-{
-       iio_dealloc_pollfunc(indio_dev->pollfunc);
-       iio_kfifo_free(indio_dev->buffer);
-}
diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c
deleted file mode 100644 (file)
index bfbf1c5..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/**
- * Copyright (c) 2011 Jonathan Cameron
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * Event handling elements of industrial I/O reference driver.
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/events.h>
-#include "iio_simple_dummy.h"
-
-/* Evgen 'fakes' interrupt events for this example */
-#include "iio_dummy_evgen.h"
-
-/**
- * iio_simple_dummy_read_event_config() - is event enabled?
- * @indio_dev: the device instance data
- * @chan: channel for the event whose state is being queried
- * @type: type of the event whose state is being queried
- * @dir: direction of the vent whose state is being queried
- *
- * This function would normally query the relevant registers or a cache to
- * discover if the event generation is enabled on the device.
- */
-int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
-                                      const struct iio_chan_spec *chan,
-                                      enum iio_event_type type,
-                                      enum iio_event_direction dir)
-{
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-
-       return st->event_en;
-}
-
-/**
- * iio_simple_dummy_write_event_config() - set whether event is enabled
- * @indio_dev: the device instance data
- * @chan: channel for the event whose state is being set
- * @type: type of the event whose state is being set
- * @dir: direction of the vent whose state is being set
- * @state: whether to enable or disable the device.
- *
- * This function would normally set the relevant registers on the devices
- * so that it generates the specified event. Here it just sets up a cached
- * value.
- */
-int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
-                                       const struct iio_chan_spec *chan,
-                                       enum iio_event_type type,
-                                       enum iio_event_direction dir,
-                                       int state)
-{
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-
-       /*
-        *  Deliberately over the top code splitting to illustrate
-        * how this is done when multiple events exist.
-        */
-       switch (chan->type) {
-       case IIO_VOLTAGE:
-               switch (type) {
-               case IIO_EV_TYPE_THRESH:
-                       if (dir == IIO_EV_DIR_RISING)
-                               st->event_en = state;
-                       else
-                               return -EINVAL;
-               default:
-                       return -EINVAL;
-               }
-               break;
-       case IIO_ACTIVITY:
-               switch (type) {
-               case IIO_EV_TYPE_THRESH:
-                       st->event_en = state;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               break;
-       case IIO_STEPS:
-               switch (type) {
-               case IIO_EV_TYPE_CHANGE:
-                       st->event_en = state;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/**
- * iio_simple_dummy_read_event_value() - get value associated with event
- * @indio_dev: device instance specific data
- * @chan: channel for the event whose value is being read
- * @type: type of the event whose value is being read
- * @dir: direction of the vent whose value is being read
- * @info: info type of the event whose value is being read
- * @val: value for the event code.
- *
- * Many devices provide a large set of events of which only a subset may
- * be enabled at a time, with value registers whose meaning changes depending
- * on the event enabled. This often means that the driver must cache the values
- * associated with each possible events so that the right value is in place when
- * the enabled event is changed.
- */
-int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
-                                     const struct iio_chan_spec *chan,
-                                     enum iio_event_type type,
-                                     enum iio_event_direction dir,
-                                     enum iio_event_info info,
-                                     int *val, int *val2)
-{
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-
-       *val = st->event_val;
-
-       return IIO_VAL_INT;
-}
-
-/**
- * iio_simple_dummy_write_event_value() - set value associate with event
- * @indio_dev: device instance specific data
- * @chan: channel for the event whose value is being set
- * @type: type of the event whose value is being set
- * @dir: direction of the vent whose value is being set
- * @info: info type of the event whose value is being set
- * @val: the value to be set.
- */
-int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
-                                      const struct iio_chan_spec *chan,
-                                      enum iio_event_type type,
-                                      enum iio_event_direction dir,
-                                      enum iio_event_info info,
-                                      int val, int val2)
-{
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-
-       st->event_val = val;
-
-       return 0;
-}
-
-static irqreturn_t iio_simple_dummy_get_timestamp(int irq, void *private)
-{
-       struct iio_dev *indio_dev = private;
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-
-       st->event_timestamp = iio_get_time_ns();
-       return IRQ_HANDLED;
-}
-
-/**
- * iio_simple_dummy_event_handler() - identify and pass on event
- * @irq: irq of event line
- * @private: pointer to device instance state.
- *
- * This handler is responsible for querying the device to find out what
- * event occurred and for then pushing that event towards userspace.
- * Here only one event occurs so we push that directly on with locally
- * grabbed timestamp.
- */
-static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private)
-{
-       struct iio_dev *indio_dev = private;
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-
-       dev_dbg(&indio_dev->dev, "id %x event %x\n",
-               st->regs->reg_id, st->regs->reg_data);
-
-       switch (st->regs->reg_data) {
-       case 0:
-               iio_push_event(indio_dev,
-                              IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
-                                             IIO_EV_DIR_RISING,
-                                             IIO_EV_TYPE_THRESH, 0, 0, 0),
-                              st->event_timestamp);
-               break;
-       case 1:
-               if (st->activity_running > st->event_val)
-                       iio_push_event(indio_dev,
-                                      IIO_EVENT_CODE(IIO_ACTIVITY, 0,
-                                                     IIO_MOD_RUNNING,
-                                                     IIO_EV_DIR_RISING,
-                                                     IIO_EV_TYPE_THRESH,
-                                                     0, 0, 0),
-                                      st->event_timestamp);
-               break;
-       case 2:
-               if (st->activity_walking < st->event_val)
-                       iio_push_event(indio_dev,
-                                      IIO_EVENT_CODE(IIO_ACTIVITY, 0,
-                                                     IIO_MOD_WALKING,
-                                                     IIO_EV_DIR_FALLING,
-                                                     IIO_EV_TYPE_THRESH,
-                                                     0, 0, 0),
-                                      st->event_timestamp);
-               break;
-       case 3:
-               iio_push_event(indio_dev,
-                              IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
-                                             IIO_EV_DIR_NONE,
-                                             IIO_EV_TYPE_CHANGE, 0, 0, 0),
-                              st->event_timestamp);
-               break;
-       default:
-               break;
-       }
-
-       return IRQ_HANDLED;
-}
-
-/**
- * iio_simple_dummy_events_register() - setup interrupt handling for events
- * @indio_dev: device instance data
- *
- * This function requests the threaded interrupt to handle the events.
- * Normally the irq is a hardware interrupt and the number comes
- * from board configuration files.  Here we get it from a companion
- * module that fakes the interrupt for us. Note that module in
- * no way forms part of this example. Just assume that events magically
- * appear via the provided interrupt.
- */
-int iio_simple_dummy_events_register(struct iio_dev *indio_dev)
-{
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-       int ret;
-
-       /* Fire up event source - normally not present */
-       st->event_irq = iio_dummy_evgen_get_irq();
-       if (st->event_irq < 0) {
-               ret = st->event_irq;
-               goto error_ret;
-       }
-       st->regs = iio_dummy_evgen_get_regs(st->event_irq);
-
-       ret = request_threaded_irq(st->event_irq,
-                                  &iio_simple_dummy_get_timestamp,
-                                  &iio_simple_dummy_event_handler,
-                                  IRQF_ONESHOT,
-                                  "iio_simple_event",
-                                  indio_dev);
-       if (ret < 0)
-               goto error_free_evgen;
-       return 0;
-
-error_free_evgen:
-       iio_dummy_evgen_release_irq(st->event_irq);
-error_ret:
-       return ret;
-}
-
-/**
- * iio_simple_dummy_events_unregister() - tidy up interrupt handling on remove
- * @indio_dev: device instance data
- */
-void iio_simple_dummy_events_unregister(struct iio_dev *indio_dev)
-{
-       struct iio_dummy_state *st = iio_priv(indio_dev);
-
-       free_irq(st->event_irq, indio_dev);
-       /* Not part of normal driver */
-       iio_dummy_evgen_release_irq(st->event_irq);
-}