Browse Source

add dummy adc

encrypt 8 years ago
parent
commit
505605068b
2 changed files with 147 additions and 0 deletions
  1. 16 0
      iio/dummy-adc/Makefile
  2. 131 0
      iio/dummy-adc/dummy-adc.c

+ 16 - 0
iio/dummy-adc/Makefile

@@ -0,0 +1,16 @@
+obj-m := dummy-adc.o
+KDIR  := /lib/modules/$(shell uname -r)/build
+PWD   := $(shell pwd)
+DEPMOD:=$(shell which depmod)
+# possible bug: maybe this will work only on debian based systems
+SYSMAP:= /boot/System.map-$(shell uname -r)
+
+default:
+	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+
+install:
+	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
+	$(DEPMOD) -ae -F $(SYSMAP)
+
+clean:
+	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean

+ 131 - 0
iio/dummy-adc/dummy-adc.c

@@ -0,0 +1,131 @@
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/driver.h>
+#include <linux/iio/machine.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct dummy_adc {
+  struct platform_device *pdev;
+  int value;
+};
+
+static const struct iio_chan_spec const dummy_adc_channels[] = {
+  {
+    .indexed = 1,
+    .type = IIO_VOLTAGE,
+    .channel = 0,
+    .datasheet_name = "DM0",
+    .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+  }, {
+    .indexed = 1,
+    .type = IIO_VOLTAGE,
+    .channel = 1,
+    .datasheet_name = "DM1",
+    .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+  }
+};
+
+static int dummy_adc_read_raw(struct iio_dev *dummy_adc_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
+{
+  int ret;
+  struct dummy_adc *adc = iio_priv(dummy_adc_dev);
+
+  mutex_lock(&dummy_adc_dev->mlock);
+  switch(mask) {
+  case IIO_CHAN_INFO_RAW:
+    if(adc->value == 13)
+      adc->value = 0;
+    *val = adc->value++;
+    ret = IIO_VAL_INT;
+    break;
+  default:
+    ret = -EINVAL;
+  }
+  mutex_unlock(&dummy_adc_dev->mlock);
+  return ret;
+}
+
+static const struct iio_info dummy_adc_iio_info = {
+  .read_raw = &dummy_adc_read_raw,
+  .driver_module = THIS_MODULE
+};
+  
+static struct iio_map dummy_adc_default_maps[] = {
+  {						
+    .adc_channel_label = "DM0",
+    .consumer_dev_name = "dummy-adc",
+    .consumer_channel  = "dummy-adc0",
+  },
+  {						
+    .adc_channel_label = "DM1",
+    .consumer_dev_name = "dummy-adc",
+    .consumer_channel  = "dummy-adc1",
+  },  
+};
+
+static int dummy_adc_probe(struct platform_device *pdev)
+{
+  struct iio_dev *dummy_adc_dev;
+  struct dummy_adc *adc;
+  int ret;
+  printk("LOL");
+  dummy_adc_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
+  if(!dummy_adc_dev)
+    return -ENOMEM;
+
+  adc = iio_priv(dummy_adc_dev);
+  adc->pdev = pdev;
+  adc->value = 0;
+  platform_set_drvdata(pdev, dummy_adc_dev);
+  dummy_adc_dev->dev.parent = &pdev->dev;
+  dummy_adc_dev->name = pdev->name;
+  dummy_adc_dev->channels = dummy_adc_channels;
+  dummy_adc_dev->num_channels = ARRAY_SIZE(dummy_adc_channels);
+  dummy_adc_dev->info = &dummy_adc_iio_info;
+  dummy_adc_dev->modes = INDIO_DIRECT_MODE;
+
+  ret = iio_map_array_register(dummy_adc_dev, dummy_adc_default_maps);
+
+  if(ret < 0) {
+    dev_err(&pdev->dev, "something went wrong");
+    return ret;
+  }
+  ret = iio_device_register(dummy_adc_dev);
+  if(ret < 0) {
+    dev_err(&pdev->dev, "unable to register iiodevice \n");
+    goto err_array_unregister;
+  }
+  return 0;
+
+ err_array_unregister:
+  iio_map_array_unregister(dummy_adc_dev);
+  return ret;
+}
+
+static int dummy_adc_remove(struct platform_device *pdev)
+{
+  struct iio_dev *dummy_adc_dev = platform_get_drvdata(pdev);
+
+  iio_device_unregister(dummy_adc_dev);
+  iio_map_array_unregister(dummy_adc_dev);
+
+  return 0;
+}
+
+static struct platform_driver dummy_adc_driver = {
+  .probe = dummy_adc_probe,
+  .remove = dummy_adc_remove,
+  .driver = {
+    .name = "dummy-adc"
+  }
+};
+
+module_platform_driver(dummy_adc_driver);
+
+MODULE_DESCRIPTION("Dummy ADC driver");
+MODULE_AUTHOR("encrypt <encrypt@labr.xyz>");
+MODULE_LICENSE("GPL");