* [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
* [PATCH 3/6] drivers: Introduce AIODEV subsystem
2016-04-29 17:24 [PATCH 0/6] " Andrey Smirnov
@ 2016-04-29 17:24 ` Andrey Smirnov
2016-05-03 6:13 ` Sascha Hauer
2016-05-03 6:21 ` Sascha Hauer
0 siblings, 2 replies; 5+ messages in thread
From: Andrey Smirnov @ 2016-04-29 17:24 UTC (permalink / raw)
To: barebox; +Cc: Andrey Smirnov
From: Sascha Hauer <s.hauer@pengutronix.de>
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
* Re: [PATCH 3/6] drivers: Introduce AIODEV subsystem
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
1 sibling, 1 reply; 5+ messages in thread
From: Sascha Hauer @ 2016-05-03 6:13 UTC (permalink / raw)
To: Andrey Smirnov; +Cc: barebox, Andrey Smirnov
On Fri, Apr 29, 2016 at 10:24:03AM -0700, Andrey Smirnov wrote:
> From: Sascha Hauer <s.hauer@pengutronix.de>
>
> 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/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>
GPL Header missing.
> +
> +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);
#io-channel-cells is part of the official binding in
/dts/Bindings/iio/iio-bindings.txt. We should work with this existing
binding.
> + 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;
This function is unused in your patches. If the information this
function provides is needed, maybe better add a index member to struct
aiochannel to get rid of this loop?
> +
> + 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) {
if (!aiodev->name && aiodev->hwdev &&
aiodev->hwdev->device_node)
?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 3/6] drivers: Introduce AIODEV subsystem
2016-05-03 6:13 ` Sascha Hauer
@ 2016-05-04 15:47 ` Andrey Smirnov
0 siblings, 0 replies; 5+ messages in thread
From: Andrey Smirnov @ 2016-05-04 15:47 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox, Andrey Smirnov
On Mon, May 2, 2016 at 11:13 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> On Fri, Apr 29, 2016 at 10:24:03AM -0700, Andrey Smirnov wrote:
>> From: Sascha Hauer <s.hauer@pengutronix.de>
>>
>> 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/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>
>
> GPL Header missing.
OK, will fix in v2.
>
>> +
>> +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);
>
> #io-channel-cells is part of the official binding in
> /dts/Bindings/iio/iio-bindings.txt. We should work with this existing
> binding.
Oh, I didn't realize that it was original IIO DT binding. Will fix in v2.
>
>> + 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;
>
> This function is unused in your patches. If the information this
> function provides is needed, maybe better add a index member to struct
> aiochannel to get rid of this loop?
>
It's used in one of the custom drivers I have in my tree. And yeah, I
think it's a good idea to store index and get rid of the loop. Will do
that in v2.
>> +
>> + 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) {
>
> if (!aiodev->name && aiodev->hwdev &&
> aiodev->hwdev->device_node)
>
> ?
Agreed, there's no need to have a standalone if. Will fix in v2.
Thank you for reviewing my pathes!
Andrey
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 3/6] drivers: Introduce AIODEV subsystem
2016-04-29 17:24 ` [PATCH 3/6] drivers: Introduce " Andrey Smirnov
2016-05-03 6:13 ` Sascha Hauer
@ 2016-05-03 6:21 ` Sascha Hauer
1 sibling, 0 replies; 5+ messages in thread
From: Sascha Hauer @ 2016-05-03 6:21 UTC (permalink / raw)
To: Andrey Smirnov; +Cc: barebox
On Fri, Apr 29, 2016 at 10:24:03AM -0700, Andrey Smirnov wrote:
> From: Sascha Hauer <s.hauer@pengutronix.de>
>
> 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>
^^^^
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
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