iio: dummy: Add virtual registers for dummy device
authorDaniel Baluta <daniel.baluta@intel.com>
Mon, 10 Nov 2014 12:45:29 +0000 (14:45 +0200)
committerJonathan Cameron <jic23@kernel.org>
Sat, 22 Nov 2014 11:05:44 +0000 (11:05 +0000)
We need a way to store events generated by iio_dummy_evgen module,
in order to correctly process IRQs in iio_simple_dummy_events.

For the moment, we add two registers:

* id_reg  - ID register, stores the source of the event
* id_data - DATA register, stores the type of the event

e.g echo 4 > /sys/bus/iio/devices/iio_evgen/poke2

id_reg 0x02, id_data 0x04

This means, event of type 4 was generated by fake device 2.

We currently use a hardcoded mapping of virtual events to IIO events.

Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Signed-off-by: Daniel Baluta <daniel.baluta@intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/staging/iio/iio_dummy_evgen.c
drivers/staging/iio/iio_dummy_evgen.h
drivers/staging/iio/iio_simple_dummy.h
drivers/staging/iio/iio_simple_dummy_events.c

index 5a804f16ec2fbef2732387d0a8f2564ae272c4ad..59ad5a3efe9cb3cf1a7a1f2e8fcab693421d64c4 100644 (file)
@@ -33,6 +33,7 @@
  * @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
  */
 struct iio_dummy_eventgen {
@@ -40,6 +41,7 @@ struct iio_dummy_eventgen {
        int base;
        bool enabled[IIO_EVENTGEN_NO];
        bool inuse[IIO_EVENTGEN_NO];
+       struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
        struct mutex lock;
 };
 
@@ -136,6 +138,12 @@ int iio_dummy_evgen_release_irq(int irq)
 }
 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);
@@ -153,6 +161,15 @@ static ssize_t iio_evgen_poke(struct device *dev,
                              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;
 
        if (iio_evgen->enabled[this_attr->address])
                handle_nested_irq(iio_evgen->base + this_attr->address);
index 3a180811b315df7728717bd499c9eecd732d8797..2ac293ab7c8fbdbe6f0393bbd3a9784d82ea0ca7 100644 (file)
@@ -1,6 +1,12 @@
 #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);
 int iio_dummy_evgen_release_irq(int irq);
 
index 3027aed7909373c9b69c0f3479dfa214aaef25d9..ad898424d9bdc752ee6b5aba68d68e54c00c1393 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 
 struct iio_dummy_accel_calibscale;
+struct iio_dummy_regs;
 
 /**
  * struct iio_dummy_state - device instance specific state.
@@ -35,6 +36,7 @@ struct iio_dummy_state {
        int accel_calibbias;
        const struct iio_dummy_accel_calibscale *accel_calibscale;
        struct mutex lock;
+       struct iio_dummy_regs *regs;
 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
        int event_irq;
        int event_val;
index 64b45b0775494269a3d19d8d6ebc0f17d16c30ad..719dfa5ae7dfb5037290322d1d4777ef7e15eedd 100644 (file)
@@ -148,12 +148,23 @@ int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
 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),
+                              iio_get_time_ns());
+               break;
+       default:
+               break;
+       }
 
-       iio_push_event(indio_dev,
-                      IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
-                                     IIO_EV_DIR_RISING,
-                                     IIO_EV_TYPE_THRESH, 0, 0, 0),
-                      iio_get_time_ns());
        return IRQ_HANDLED;
 }
 
@@ -179,6 +190,8 @@ int iio_simple_dummy_events_register(struct iio_dev *indio_dev)
                ret = st->event_irq;
                goto error_ret;
        }
+       st->regs = iio_dummy_evgen_get_regs(st->event_irq);
+
        ret = request_threaded_irq(st->event_irq,
                                   NULL,
                                   &iio_simple_dummy_event_handler,