mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 3/6] drivers: Introduce AIODEV subsystem
@ 2016-04-29 17:31 Andrey Smirnov
  0 siblings, 0 replies; 5+ messages in thread
From: Andrey Smirnov @ 2016-04-29 17:31 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

From: Andrey Smirnov <andrew.smrinov@gmail.com>

AIODEV/Aiodevice is a analog I/O framework that can be thought of as a
simplified hybrid between 'hwmon' and 'IIO' subsystems of Linux kernel

This commit is very heavily based on 'iodevice' framework proposal
written by Sascha Hauer.

Signed-off-by: Andrey Smirnov <andrew.smrinov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/Kconfig         |   1 +
 drivers/Makefile        |   1 +
 drivers/aiodev/Kconfig  |   8 +++
 drivers/aiodev/Makefile |   2 +
 drivers/aiodev/core.c   | 135 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/aiodev.h        |  39 ++++++++++++++
 6 files changed, 186 insertions(+)
 create mode 100644 drivers/aiodev/Kconfig
 create mode 100644 drivers/aiodev/Makefile
 create mode 100644 drivers/aiodev/core.c
 create mode 100644 include/aiodev.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 90ab7c1..eef68f6 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -1,6 +1,7 @@
 menu "Drivers"
 
 source "drivers/of/Kconfig"
+source "drivers/aiodev/Kconfig"
 source "drivers/amba/Kconfig"
 source "drivers/serial/Kconfig"
 source "drivers/net/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 551b9a0..03bbc81 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -33,4 +33,5 @@ obj-$(CONFIG_GENERIC_PHY) += phy/
 obj-$(CONFIG_HAB) += hab/
 obj-$(CONFIG_CRYPTO_HW) += crypto/
 obj-$(CONFIG_NVMEM) += nvmem/
+obj-$(CONFIG_AIODEV) += aiodev/
 
diff --git a/drivers/aiodev/Kconfig b/drivers/aiodev/Kconfig
new file mode 100644
index 0000000..d6d4ac0
--- /dev/null
+++ b/drivers/aiodev/Kconfig
@@ -0,0 +1,8 @@
+#
+# Misc strange devices
+#
+menuconfig AIODEV
+	bool "Analog I/O drivers"
+
+if AIODEV
+endif
diff --git a/drivers/aiodev/Makefile b/drivers/aiodev/Makefile
new file mode 100644
index 0000000..806464e
--- /dev/null
+++ b/drivers/aiodev/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_AIODEV) += core.o
diff --git a/drivers/aiodev/core.c b/drivers/aiodev/core.c
new file mode 100644
index 0000000..6dcb917
--- /dev/null
+++ b/drivers/aiodev/core.c
@@ -0,0 +1,135 @@
+#include <common.h>
+#include <aiodev.h>
+#include <linux/list.h>
+#include <malloc.h>
+
+LIST_HEAD(aiodevices);
+EXPORT_SYMBOL(aiodevices);
+
+struct aiochannel *aiochannel_get_by_name(const char *name)
+{
+	struct aiodevice *aiodev;
+	int i;
+
+	list_for_each_entry(aiodev, &aiodevices, list) {
+		for (i = 0; i < aiodev->num_channels; i++)
+			if (!strcmp(name, aiodev->channels[i]->name))
+				return aiodev->channels[i];
+	}
+
+	return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(aiochannel_get_by_name);
+
+struct aiochannel *aiochannel_get(struct device_d *dev, int index)
+{
+	struct of_phandle_args spec;
+	struct aiodevice *aiodev;
+	int ret, chnum = 0;
+
+	if (!dev->device_node)
+		return ERR_PTR(-EINVAL);
+
+	ret = of_parse_phandle_with_args(dev->device_node,
+					 "aio-channels",
+					 "#aio-channel-cells",
+					 index, &spec);
+        if (ret)
+                return ERR_PTR(ret);
+
+	list_for_each_entry(aiodev, &aiodevices, list) {
+		if (aiodev->hwdev->device_node == spec.np)
+			goto found;
+	}
+
+	return ERR_PTR(-EPROBE_DEFER);
+
+found:
+	if (spec.args_count)
+		chnum = spec.args[0];
+
+	if (chnum >= aiodev->num_channels)
+		return ERR_PTR(-EINVAL);
+
+	return aiodev->channels[chnum];
+}
+EXPORT_SYMBOL(aiochannel_get);
+
+int aiochannel_get_value(struct aiochannel *aiochan, int *value)
+{
+	struct aiodevice *aiodev = aiochan->aiodev;
+
+	return aiodev->read(aiochan, value);
+}
+EXPORT_SYMBOL(aiochannel_get_value);
+
+int aiochannel_get_index(struct aiochannel *aiochan)
+{
+	int i;
+	struct aiodevice *aiodev = aiochan->aiodev;
+
+	for (i = 0; i < aiodev->num_channels; i++)
+		if (aiodev->channels[i] == aiochan)
+			return i;
+
+	return -ENOENT;
+}
+EXPORT_SYMBOL(aiochannel_get_index);
+
+static int aiochannel_param_get_value(struct param_d *p, void *priv)
+{
+	struct aiochannel *aiochan = priv;
+
+	return aiochannel_get_value(aiochan, &aiochan->value);
+}
+
+int aiodevice_register(struct aiodevice *aiodev)
+{
+	int i, ret;
+
+	if (!aiodev->name) {
+		if (aiodev->hwdev &&
+		    aiodev->hwdev->device_node) {
+			aiodev->dev.id = DEVICE_ID_SINGLE;
+
+			aiodev->name = of_alias_get(aiodev->hwdev->device_node);
+			if (!aiodev->name)
+				aiodev->name = aiodev->hwdev->device_node->name;
+		}
+	}
+
+	if (!aiodev->name) {
+		aiodev->name = "aiodev";
+		aiodev->dev.id = DEVICE_ID_DYNAMIC;
+	}
+
+	strcpy(aiodev->dev.name, aiodev->name);
+
+	aiodev->dev.parent = aiodev->hwdev;
+
+	ret = register_device(&aiodev->dev);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < aiodev->num_channels; i++) {
+		struct aiochannel *aiochan = aiodev->channels[i];
+		char *name;
+
+		aiochan->aiodev = aiodev;
+
+		name = xasprintf("in_value%d_%s", i, aiochan->unit);
+
+		dev_add_param_int(&aiodev->dev, name, NULL,
+				  aiochannel_param_get_value,
+				  &aiochan->value, "%d", aiochan);
+
+		aiochan->name = xasprintf("%s.%s", aiodev->name, name);
+
+		free(name);
+	}
+
+	list_add_tail(&aiodev->list, &aiodevices);
+
+	return 0;
+}
+EXPORT_SYMBOL(aiodevice_register);
diff --git a/include/aiodev.h b/include/aiodev.h
new file mode 100644
index 0000000..21d8568
--- /dev/null
+++ b/include/aiodev.h
@@ -0,0 +1,39 @@
+#ifndef __AIODEVICE_H
+#define __AIODEVICE_H
+
+struct aiodevice;
+struct aiochannel {
+	char *unit;
+	struct aiodevice *aiodev;
+
+	int value;
+	char *name;
+};
+
+struct aiodevice {
+	const char *name;
+	int (*read)(struct aiochannel *, int *val);
+	struct device_d dev;
+	struct device_d *hwdev;
+	struct aiochannel **channels;
+	int num_channels;
+	struct list_head list;
+};
+
+int aiodevice_register(struct aiodevice *aiodev);
+
+struct aiochannel *aiochannel_get(struct device_d *dev, int index);
+struct aiochannel *aiochannel_get_by_name(const char *name);
+
+int aiochannel_get_value(struct aiochannel *aiochan, int *value);
+int aiochannel_get_index(struct aiochannel *aiochan);
+
+static inline const char *aiochannel_get_unit(struct aiochannel *aiochan)
+{
+	return aiochan->unit;
+}
+
+extern struct list_head aiodevices;
+#define for_each_aiodevice(aiodevice) list_for_each_entry(aiodevice, &aiodevices, list)
+
+#endif
-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 5+ messages in thread
* [PATCH 0/6] AIODEV subsystem
@ 2016-04-29 17:24 Andrey Smirnov
  2016-04-29 17:24 ` [PATCH 3/6] drivers: Introduce " Andrey Smirnov
  0 siblings, 1 reply; 5+ messages in thread
From: Andrey Smirnov @ 2016-04-29 17:24 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Hello everone,

This series of patches is a combined version of "hwmon" and "iodev"
proposals, submitted several months ago by me and Sascha respectively.

The main purpose of this subsystem is to provde means of exposing
different analog sensors(temperature, voltage, etc.) or, potentially,
"actuators"(e.g. DACs) in a uniformed fashion.

This series introduces the subsystem itself, a helper command to
display values of all registersd sensors ("hwmon"), and a two drivers
leveraging the AIODEV subsystem API (LM75 and TEMPMON).

Additionaly, due to TEMPMON driver's need to obtain calibraion
information from OCOTP, this patchset adds Steffen Trumtrar's port of
NVMEM subsytem from Linux kernel.

Sascha, you didn't like "iodev" as a name, so I changed it and I hope
you like this one better :-)

Andrey Smirnov (2):
  commands: Add 'hwmon' command
  aiodev: Add TEMPMON driver

Sascha Hauer (3):
  ocotp: Register OCOTP with 'nvmem'
  drivers: Introduce AIODEV subsystem
  aiodev: Add basic LM75 temperature driver

Steffen Trumtrar (1):
  drivers: add nvmem framework from kernel

 arch/arm/dts/imx6qdl.dtsi      |  14 +
 arch/arm/dts/imx6sx.dtsi       |  14 +
 arch/arm/mach-imx/ocotp.c      |   8 +
 commands/Kconfig               |   8 +
 commands/Makefile              |   1 +
 commands/hwmon.c               |  35 ++
 drivers/Kconfig                |   3 +-
 drivers/Makefile               |   3 +
 drivers/aiodev/Kconfig         |  22 ++
 drivers/aiodev/Makefile        |   4 +
 drivers/aiodev/core.c          | 135 ++++++++
 drivers/aiodev/imx_thermal.c   | 215 ++++++++++++
 drivers/aiodev/lm75.c          | 262 ++++++++++++++
 drivers/nvmem/Kconfig          |   7 +
 drivers/nvmem/Makefile         |   6 +
 drivers/nvmem/core.c           | 749 +++++++++++++++++++++++++++++++++++++++++
 include/aiodev.h               |  39 +++
 include/linux/nvmem-consumer.h | 157 +++++++++
 include/linux/nvmem-provider.h |  49 +++
 19 files changed, 1730 insertions(+), 1 deletion(-)
 create mode 100644 commands/hwmon.c
 create mode 100644 drivers/aiodev/Kconfig
 create mode 100644 drivers/aiodev/Makefile
 create mode 100644 drivers/aiodev/core.c
 create mode 100644 drivers/aiodev/imx_thermal.c
 create mode 100644 drivers/aiodev/lm75.c
 create mode 100644 drivers/nvmem/Kconfig
 create mode 100644 drivers/nvmem/Makefile
 create mode 100644 drivers/nvmem/core.c
 create mode 100644 include/aiodev.h
 create mode 100644 include/linux/nvmem-consumer.h
 create mode 100644 include/linux/nvmem-provider.h

-- 
2.5.5


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

end of thread, other threads:[~2016-05-04 15:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-29 17:31 [PATCH 3/6] drivers: Introduce AIODEV subsystem Andrey Smirnov
  -- strict thread matches above, loose matches on Subject: below --
2016-04-29 17:24 [PATCH 0/6] " Andrey Smirnov
2016-04-29 17:24 ` [PATCH 3/6] drivers: Introduce " Andrey Smirnov
2016-05-03  6:13   ` Sascha Hauer
2016-05-04 15:47     ` Andrey Smirnov
2016-05-03  6:21   ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox