mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [RFC] iodevice support
@ 2015-12-08  9:05 Sascha Hauer
  2015-12-08  9:05 ` [PATCH 1/4] misc: Add " Sascha Hauer
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Sascha Hauer @ 2015-12-08  9:05 UTC (permalink / raw)
  To: Barebox List

The following is something like a mixture of Linux IIO and hwmon support
for the poor. I called it iodevice, but better names are appreciated.
A iodevice has multiple channels, each providing a value like for
example a temperature or a voltage. For each iodevice we provide device
parameters to access the values from the commandline. The C API for a
consumer consists of iochannel_get() to get a iochannel, and
iochannel_get_value() to actually read a value.
As drivers we currently have a LM75 temperature driver and a MCP342x ADC
driver. Also there is a PT100 driver which itself is a consumer of
another iodevice, a MCP342x in my case. This is more meant as an example
since the voltage to temperature conversion function is board specific.

Sascha

----------------------------------------------------------------
Sascha Hauer (4):
      misc: Add iodevice support
      misc: Add basic LM75 temperature driver
      misc: Add Microchip MCP342x support
      misc: Add PT100 temperature sensor support

 drivers/misc/Kconfig    |  18 ++++
 drivers/misc/Makefile   |   5 +
 drivers/misc/iodevice.c | 109 ++++++++++++++++++++
 drivers/misc/lm75.c     | 262 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/misc/mcp342x.c  | 259 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/misc/pt100.c    | 145 +++++++++++++++++++++++++++
 include/iodevice.h      |  33 ++++++
 7 files changed, 831 insertions(+)
 create mode 100644 drivers/misc/iodevice.c
 create mode 100644 drivers/misc/lm75.c
 create mode 100644 drivers/misc/mcp342x.c
 create mode 100644 drivers/misc/pt100.c
 create mode 100644 include/iodevice.h

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

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

* [PATCH 1/4] misc: Add iodevice support
  2015-12-08  9:05 [RFC] iodevice support Sascha Hauer
@ 2015-12-08  9:05 ` Sascha Hauer
  2015-12-10 20:42   ` Trent Piepho
  2015-12-08  9:05 ` [PATCH 2/4] misc: Add basic LM75 temperature driver Sascha Hauer
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Sascha Hauer @ 2015-12-08  9:05 UTC (permalink / raw)
  To: Barebox List

This adds a poor copy of the Linux IIO framework.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/misc/Kconfig    |   3 ++
 drivers/misc/Makefile   |   1 +
 drivers/misc/iodevice.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/iodevice.h      |  33 +++++++++++++++
 4 files changed, 146 insertions(+)
 create mode 100644 drivers/misc/iodevice.c
 create mode 100644 include/iodevice.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 7a5b146..250b205 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -19,4 +19,7 @@ config STATE_DRV
 	tristate "state driver"
 	depends on STATE
 
+config IODEVICE
+	bool "IO device support"
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 487e4b8..127504e 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_JTAG)		+= jtag.o
 obj-$(CONFIG_SRAM)		+= sram.o
 obj-$(CONFIG_STATE_DRV)		+= state.o
+obj-$(CONFIG_IODEVICE)		+= iodevice.o
diff --git a/drivers/misc/iodevice.c b/drivers/misc/iodevice.c
new file mode 100644
index 0000000..6fdcd42
--- /dev/null
+++ b/drivers/misc/iodevice.c
@@ -0,0 +1,109 @@
+#include <common.h>
+#include <iodevice.h>
+#include <linux/list.h>
+#include <malloc.h>
+
+static LIST_HEAD(iodevices);
+
+struct iochannel *iochannel_get_by_name(const char *name)
+{
+	struct iodevice *iodev;
+	int i;
+
+	list_for_each_entry(iodev, &iodevices, list) {
+		for (i = 0; i < iodev->num_channels; i++)
+			if (!strcmp(name, iodev->channels[i]->name))
+				return iodev->channels[i];
+	}
+
+	return ERR_PTR(-ENOENT);
+}
+
+struct iochannel *iochannel_get(struct device_d *dev, int index)
+{
+	struct of_phandle_args spec;
+	struct iodevice *iodev;
+	int ret, chnum = 0;
+
+	if (!dev->device_node)
+		return ERR_PTR(-EINVAL);
+
+	ret = of_parse_phandle_with_args(dev->device_node, "io-channels", "#io-channel-cells", index,
+                        &spec);
+        if (ret)
+                return ERR_PTR(ret);
+
+	list_for_each_entry(iodev, &iodevices, list) {
+		if (iodev->hwdev->device_node == spec.np)
+			goto found;
+	}
+
+	return ERR_PTR(-EPROBE_DEFER);
+
+found:
+	if (spec.args_count)
+		chnum = spec.args[0];
+
+	if (chnum >= iodev->num_channels)
+		return ERR_PTR(-EINVAL);
+
+	return iodev->channels[chnum];
+}
+
+int iochannel_get_value(struct iochannel *iochan, int *value)
+{
+	struct iodevice *iodev = iochan->iodev;
+
+	return iodev->read(iochan, value);
+}
+
+static int iochannel_param_get_value(struct param_d *p, void *priv)
+{
+	struct iochannel *iochan = priv;
+
+	return iochannel_get_value(iochan, &iochan->value);
+}
+
+int iodevice_register(struct iodevice *iodev)
+{
+	const char *devname = NULL;
+	int i, ret;
+
+	if (iodev->hwdev->device_node) {
+		devname = of_alias_get(iodev->hwdev->device_node);
+		iodev->dev.id = DEVICE_ID_SINGLE;
+	}
+
+	if (!devname) {
+		devname = "io";
+		iodev->dev.id = DEVICE_ID_DYNAMIC;
+	}
+
+	strcpy(iodev->dev.name, devname);
+
+	iodev->dev.parent = iodev->hwdev;
+
+	ret = register_device(&iodev->dev);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < iodev->num_channels; i++) {
+		struct iochannel *iochan = iodev->channels[i];
+		char *name;
+
+		iochan->iodev = iodev;
+
+		name = asprintf("in_value%d_%s", i, iochan->unit);
+
+		dev_add_param_int(&iodev->dev, name, NULL,
+			iochannel_param_get_value, &iochan->value, "%d", iochan);
+
+		iochan->name = asprintf("%s.%s", devname, name);
+
+		free(name);
+	}
+
+	list_add_tail(&iodev->list, &iodevices);
+
+	return 0;
+}
diff --git a/include/iodevice.h b/include/iodevice.h
new file mode 100644
index 0000000..e0e571e
--- /dev/null
+++ b/include/iodevice.h
@@ -0,0 +1,33 @@
+#ifndef __IODEVICE_H
+#define __IODEVICE_H
+
+struct iochannel {
+	char *unit;
+	struct iodevice *iodev;
+
+	int value;
+	char *name;
+};
+
+struct iodevice {
+	int (*read)(struct iochannel *, int *val);
+	struct device_d dev;
+	struct device_d *hwdev;
+	struct iochannel **channels;
+	int num_channels;
+	struct list_head list;
+};
+
+int iodevice_register(struct iodevice *iodev);
+
+struct iochannel *iochannel_get(struct device_d *dev, int index);
+struct iochannel *iochannel_get_by_name(const char *name);
+
+int iochannel_get_value(struct iochannel *iochan, int *value);
+
+static inline const char *iochannel_get_unit(struct iochannel *iochan)
+{
+	return iochan->unit;
+}
+
+#endif
-- 
2.6.2


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

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

* [PATCH 2/4] misc: Add basic LM75 temperature driver
  2015-12-08  9:05 [RFC] iodevice support Sascha Hauer
  2015-12-08  9:05 ` [PATCH 1/4] misc: Add " Sascha Hauer
@ 2015-12-08  9:05 ` Sascha Hauer
  2015-12-08  9:05 ` [PATCH 3/4] misc: Add Microchip MCP342x support Sascha Hauer
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2015-12-08  9:05 UTC (permalink / raw)
  To: Barebox List

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/misc/Kconfig  |   5 +
 drivers/misc/Makefile |   1 +
 drivers/misc/lm75.c   | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 268 insertions(+)
 create mode 100644 drivers/misc/lm75.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 250b205..b95a7f6 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -22,4 +22,9 @@ config STATE_DRV
 config IODEVICE
 	bool "IO device support"
 
+config LM75
+	tristate "LM75 driver"
+	depends on I2C
+	depends on IODEVICE
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 127504e..a257dfb 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_JTAG)		+= jtag.o
 obj-$(CONFIG_SRAM)		+= sram.o
 obj-$(CONFIG_STATE_DRV)		+= state.o
 obj-$(CONFIG_IODEVICE)		+= iodevice.o
+obj-$(CONFIG_LM75)		+= lm75.o
diff --git a/drivers/misc/lm75.c b/drivers/misc/lm75.c
new file mode 100644
index 0000000..d9e5580
--- /dev/null
+++ b/drivers/misc/lm75.c
@@ -0,0 +1,262 @@
+/*
+ * lm75.c - Part of lm_sensors, Linux kernel modules for hardware
+ *	 monitoring
+ * Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <xfuncs.h>
+#include <i2c/i2c.h>
+#include <iodevice.h>
+
+/*
+ * This driver handles the LM75 and compatible digital temperature sensors.
+ */
+
+/* straight from the datasheet */
+#define LM75_TEMP_MIN (-55000)
+#define LM75_TEMP_MAX 125000
+#define LM75_SHUTDOWN 0x01
+
+enum lm75_type {		/* keep sorted in alphabetical order */
+	adt75,
+	ds1775,
+	ds75,
+	ds7505,
+	g751,
+	lm75,
+	lm75a,
+	lm75b,
+	max6625,
+	max6626,
+	mcp980x,
+	stds75,
+	tcn75,
+	tmp100,
+	tmp101,
+	tmp105,
+	tmp112,
+	tmp175,
+	tmp275,
+	tmp75,
+	tmp75c,
+};
+
+/* The LM75 registers */
+#define LM75_REG_CONF		0x01
+static const u8 LM75_REG_TEMP[3] = {
+	0x00,		/* input */
+	0x03,		/* max */
+	0x02,		/* hyst */
+};
+
+/* Each client has this additional data */
+struct lm75_data {
+	struct i2c_client	*client;
+	struct device_d		dev;
+	u8			resolution;	/* In bits, between 9 and 12 */
+	struct iochannel	iochan;
+	struct iodevice		iodev;
+};
+
+static int lm75_read_value(struct lm75_data *data, u8 reg)
+{
+	if (reg == LM75_REG_CONF)
+		return i2c_smbus_read_byte_data(data->client, reg);
+	else
+		return i2c_smbus_read_word_swapped(data->client, reg);
+}
+
+static int lm75_write_value(struct lm75_data *data, u8 reg, u16 value)
+{
+	if (reg == LM75_REG_CONF)
+		return i2c_smbus_write_byte_data(data->client, reg, value);
+	else
+		return i2c_smbus_write_word_swapped(data->client, reg, value);
+}
+
+static long lm75_reg_to_mc(s16 temp, u8 resolution)
+{
+	return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
+}
+
+static int lm75_get_temp(struct iochannel *iochan, int *val)
+{
+	struct lm75_data *data = container_of(iochan, struct lm75_data, iochan);
+	int status;
+
+	status = lm75_read_value(data, LM75_REG_TEMP[0]);
+	if (status < 0) {
+		dev_err(&data->client->dev,
+			"LM75: Failed to read value: reg %d, error %d\n",
+			LM75_REG_TEMP[0], status);
+		return status;
+	}
+
+	*val = lm75_reg_to_mc(status, data->resolution);
+
+	return 0;
+}
+
+static int lm75_probe(struct device_d *dev)
+{
+	struct lm75_data *data;
+	int status;
+	u8 set_mask, clr_mask;
+	int new, ret;
+	enum lm75_type kind;
+
+	ret = dev_get_drvdata(dev, (const void **)&kind);
+	if (ret)
+		return ret;
+
+	data = xzalloc(sizeof(*data));
+
+	data->client = to_i2c_client(dev);
+
+	/* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
+	 * Then tweak to be more precise when appropriate.
+	 */
+	set_mask = 0;
+	clr_mask = LM75_SHUTDOWN;		/* continuous conversions */
+
+	switch (kind) {
+	case adt75:
+		clr_mask |= 1 << 5;		/* not one-shot mode */
+		data->resolution = 12;
+		break;
+	case ds1775:
+	case ds75:
+	case stds75:
+		clr_mask |= 3 << 5;
+		set_mask |= 2 << 5;		/* 11-bit mode */
+		data->resolution = 11;
+		break;
+	case ds7505:
+		set_mask |= 3 << 5;		/* 12-bit mode */
+		data->resolution = 12;
+		break;
+	case g751:
+	case lm75:
+	case lm75a:
+		data->resolution = 9;
+		break;
+	case lm75b:
+		data->resolution = 11;
+		break;
+	case max6625:
+		data->resolution = 9;
+		break;
+	case max6626:
+		data->resolution = 12;
+		break;
+	case tcn75:
+		data->resolution = 9;
+		break;
+	case mcp980x:
+		/* fall through */
+	case tmp100:
+	case tmp101:
+		set_mask |= 3 << 5;		/* 12-bit mode */
+		data->resolution = 12;
+		clr_mask |= 1 << 7;		/* not one-shot mode */
+		break;
+	case tmp112:
+		set_mask |= 3 << 5;		/* 12-bit mode */
+		clr_mask |= 1 << 7;		/* not one-shot mode */
+		data->resolution = 12;
+		break;
+	case tmp105:
+	case tmp175:
+	case tmp275:
+	case tmp75:
+		set_mask |= 3 << 5;		/* 12-bit mode */
+		clr_mask |= 1 << 7;		/* not one-shot mode */
+		data->resolution = 12;
+		break;
+	case tmp75c:
+		clr_mask |= 1 << 5;		/* not one-shot mode */
+		data->resolution = 12;
+		break;
+	}
+
+	/* configure as specified */
+	status = lm75_read_value(data, LM75_REG_CONF);
+	if (status < 0) {
+		dev_dbg(dev, "Can't read config? %d\n", status);
+		return status;
+	}
+
+	new = status & ~clr_mask;
+	new |= set_mask;
+	if (status != new)
+		lm75_write_value(data, LM75_REG_CONF, new);
+
+	data->iodev.num_channels = 1;
+	data->iodev.hwdev = dev;
+	data->iodev.read = lm75_get_temp;
+	data->iodev.channels = xmalloc(sizeof(void *));
+	data->iodev.channels[0] = &data->iochan;
+	data->iochan.unit = "mC";
+
+	ret = iodevice_register(&data->iodev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct platform_device_id lm75_ids[] = {
+	{ .name = "adt75", .driver_data = adt75, },
+	{ .name = "ds1775", .driver_data = ds1775, },
+	{ .name = "ds75", .driver_data = ds75, },
+	{ .name = "ds7505", .driver_data = ds7505, },
+	{ .name = "g751", .driver_data = g751, },
+	{ .name = "lm75", .driver_data = lm75, },
+	{ .name = "lm75a", .driver_data = lm75a, },
+	{ .name = "lm75b", .driver_data = lm75b, },
+	{ .name = "max6625", .driver_data = max6625, },
+	{ .name = "max6626", .driver_data = max6626, },
+	{ .name = "mcp980x", .driver_data = mcp980x, },
+	{ .name = "stds75", .driver_data = stds75, },
+	{ .name = "tcn75", .driver_data = tcn75, },
+	{ .name = "tmp100", .driver_data = tmp100, },
+	{ .name = "tmp101", .driver_data = tmp101, },
+	{ .name = "tmp105", .driver_data = tmp105, },
+	{ .name = "tmp112", .driver_data = tmp112, },
+	{ .name = "tmp175", .driver_data = tmp175, },
+	{ .name = "tmp275", .driver_data = tmp275, },
+	{ .name = "tmp75", .driver_data = tmp75, },
+	{ .name = "tmp75c", .driver_data = tmp75c, },
+	{ /* LIST END */ }
+};
+
+static struct driver_d lm75_driver = {
+	.name  = "lm75",
+	.probe = lm75_probe,
+	.id_table = lm75_ids,
+};
+
+static int lm75_init(void)
+{
+	i2c_driver_register(&lm75_driver);
+	return 0;
+}
+
+device_initcall(lm75_init);
\ No newline at end of file
-- 
2.6.2


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

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

* [PATCH 3/4] misc: Add Microchip MCP342x support
  2015-12-08  9:05 [RFC] iodevice support Sascha Hauer
  2015-12-08  9:05 ` [PATCH 1/4] misc: Add " Sascha Hauer
  2015-12-08  9:05 ` [PATCH 2/4] misc: Add basic LM75 temperature driver Sascha Hauer
@ 2015-12-08  9:05 ` Sascha Hauer
  2015-12-08  9:05 ` [PATCH 4/4] misc: Add PT100 temperature sensor support Sascha Hauer
  2015-12-10  6:24 ` [RFC] iodevice support Andrey Smirnov
  4 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2015-12-08  9:05 UTC (permalink / raw)
  To: Barebox List

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/misc/Kconfig   |   5 +
 drivers/misc/Makefile  |   2 +
 drivers/misc/mcp342x.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 266 insertions(+)
 create mode 100644 drivers/misc/mcp342x.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b95a7f6..8d44a5c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -27,4 +27,9 @@ config LM75
 	depends on I2C
 	depends on IODEVICE
 
+config MCP342X
+	tristate "Microchip MCP342x ADC driver"
+	depends on I2C
+	depends on IODEVICE
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a257dfb..6680334 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,3 +7,5 @@ obj-$(CONFIG_SRAM)		+= sram.o
 obj-$(CONFIG_STATE_DRV)		+= state.o
 obj-$(CONFIG_IODEVICE)		+= iodevice.o
 obj-$(CONFIG_LM75)		+= lm75.o
+obj-$(CONFIG_IODEVICE)		+= iodevice.o
+obj-$(CONFIG_MCP342X)		+= mcp342x.o
diff --git a/drivers/misc/mcp342x.c b/drivers/misc/mcp342x.c
new file mode 100644
index 0000000..e498078
--- /dev/null
+++ b/drivers/misc/mcp342x.c
@@ -0,0 +1,259 @@
+/*
+ * mcp3422.c - driver for the Microchip mcp3422/3/4/6/7/8 chip family
+ *
+ * Copyright (C) 2013, Angelo Compagnucci
+ * Author: Angelo Compagnucci <angelo.compagnucci@gmail.com>
+ *
+ * Datasheet: http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf
+ *            http://ww1.microchip.com/downloads/en/DeviceDoc/22226a.pdf
+ *
+ * This driver exports the value of analog input voltage to sysfs, the
+ * voltage unit is nV.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <iodevice.h>
+#include <malloc.h>
+#include <driver.h>
+#include <xfuncs.h>
+#include <i2c/i2c.h>
+
+/* Masks */
+#define MCP3422_CHANNEL_MASK	0x60
+#define MCP3422_PGA_MASK	0x03
+#define MCP3422_SRATE_MASK	0x0C
+#define MCP3422_SRATE_240	0x0
+#define MCP3422_SRATE_60	0x1
+#define MCP3422_SRATE_15	0x2
+#define MCP3422_SRATE_3		0x3
+#define MCP3422_PGA_1	0
+#define MCP3422_PGA_2	1
+#define MCP3422_PGA_4	2
+#define MCP3422_PGA_8	3
+#define MCP3422_CONT_SAMPLING	0x10
+
+#define MCP3422_CHANNEL(config)	(((config) & MCP3422_CHANNEL_MASK) >> 5)
+#define MCP3422_PGA(config)	((config) & MCP3422_PGA_MASK)
+#define MCP3422_SAMPLE_RATE(config)	(((config) & MCP3422_SRATE_MASK) >> 2)
+
+#define MCP3422_CHANNEL_VALUE(value) (((value) << 5) & MCP3422_CHANNEL_MASK)
+#define MCP3422_PGA_VALUE(value) ((value) & MCP3422_PGA_MASK)
+#define MCP3422_SAMPLE_RATE_VALUE(value) ((value << 2) & MCP3422_SRATE_MASK)
+
+/* Constant msleep times for data acquisitions */
+static const int mcp3422_read_times[4] = {
+	[MCP3422_SRATE_240] = 1000 / 240,
+	[MCP3422_SRATE_60] = 1000 / 60,
+	[MCP3422_SRATE_15] = 1000 / 15,
+	[MCP3422_SRATE_3] = 1000 / 3 };
+
+static const int mcp3422_sample_rate_scales[4] = {
+	[MCP3422_SRATE_240] = 8000,
+	[MCP3422_SRATE_60] = 2000,
+	[MCP3422_SRATE_15] = 500,
+	[MCP3422_SRATE_3] =  125};
+
+static const char *mcp342x_sample_rate_str[] = {
+	"240", "60", "15", "3"
+};
+
+static const char *mcp342x_gain_str[] = {
+	"1", "2", "4", "8"
+};
+
+/* sample rates to sign extension table */
+static const int mcp3422_sign_extend[4] = {
+	[MCP3422_SRATE_240] = 11,
+	[MCP3422_SRATE_60] = 13,
+	[MCP3422_SRATE_15] = 15,
+	[MCP3422_SRATE_3] = 17 };
+
+struct mcp342x_channel {
+	int num;
+	int voltage;
+	int temp;
+	struct mcp342x *mcp342x;
+	struct iochannel iochan;
+	unsigned int gain;
+};
+
+struct mcp342x {
+	struct i2c_client *i2c;
+	struct iodevice iodev;
+	unsigned int sps;
+	u8 id;
+	u8 config;
+	u8 pga[4];
+	int num_channels;
+	struct mcp342x_channel *channel[4];
+	char *unit;
+};
+
+static int mcp3422_update_config(struct mcp342x *adc, u8 newconfig)
+{
+	int ret;
+
+	ret = i2c_master_send(adc->i2c, &newconfig, 1);
+	if (ret > 0) {
+		adc->config = newconfig;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int mcp3422_read(struct mcp342x_channel *channel)
+{
+	struct mcp342x *adc = channel->mcp342x;
+	int ret = 0;
+	u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
+	u8 buf[4] = {0, 0, 0, 0};
+	u32 temp;
+
+	if (sample_rate == MCP3422_SRATE_3) {
+		ret = i2c_master_recv(adc->i2c, buf, 4);
+		temp = buf[0] << 16 | buf[1] << 8 | buf[2];
+	} else {
+		ret = i2c_master_recv(adc->i2c, buf, 3);
+		temp = buf[0] << 8 | buf[1];
+	}
+
+	channel->voltage = sign_extend32(temp, mcp3422_sign_extend[sample_rate]) *
+			mcp3422_sample_rate_scales[sample_rate] / (1 << channel->gain) / 8;
+
+	return ret;
+}
+
+static int mcp342x_get_voltage(struct iochannel *iochan, int *value)
+{
+	struct mcp342x_channel *channel = container_of(iochan, struct mcp342x_channel, iochan);
+	struct mcp342x *adc = channel->mcp342x;
+	u8 config;
+	int ret;
+
+	config = MCP3422_CONT_SAMPLING |
+		MCP3422_CHANNEL_VALUE(channel->num) |
+		MCP3422_PGA_VALUE(channel->gain) |
+		MCP3422_SAMPLE_RATE_VALUE(adc->sps);
+
+	if (config != adc->config) {
+		ret = mcp3422_update_config(adc, config);
+		if (ret < 0)
+			return ret;
+
+		mdelay(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]);
+	}
+
+	mcp3422_read(channel);
+
+	*value = channel->voltage;
+
+	return 0;
+}
+
+static int mcp342x_probe(struct device_d *dev)
+{
+	struct mcp342x *adc;
+	int id , ret, i, num_channels;
+
+	ret = dev_get_drvdata(dev, (const void **)&id);
+	if (ret)
+		return ret;
+
+	adc = xzalloc(sizeof(*adc));
+
+	adc->i2c = to_i2c_client(dev);
+	adc->id = id;
+	adc->unit = "uV";
+
+	switch (id) {
+	case 1:
+		num_channels = 1;
+		break;
+	case 2:
+	case 3:
+	case 6:
+	case 7:
+		num_channels = 2;
+		break;
+	case 4:
+	case 8:
+		num_channels = 4;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	adc->num_channels = num_channels;
+
+	adc->sps = MCP3422_SRATE_15;
+
+	adc->iodev.hwdev = dev;
+
+	adc->iodev.channels = xmalloc(sizeof(void *) * num_channels);
+	adc->iodev.num_channels = num_channels;
+	adc->iodev.read = mcp342x_get_voltage;
+
+	for (i = 0; i < num_channels; i++) {
+		struct mcp342x_channel *channel;
+
+		channel = xzalloc(sizeof(*channel));
+		adc->iodev.channels[i] = &channel->iochan;
+		channel->iochan.unit = "uV";
+		adc->channel[i] = channel;
+		channel->num = i;
+		channel->mcp342x = adc;
+	}
+
+	ret = iodevice_register(&adc->iodev);
+	if (ret)
+		return ret;
+
+	dev_add_param_enum(&adc->iodev.dev, "in_sps", NULL, NULL, &adc->sps,
+			   mcp342x_sample_rate_str,
+			   ARRAY_SIZE(mcp342x_sample_rate_str), NULL);
+
+	for (i = 0; i < num_channels; i++) {
+		struct mcp342x_channel *channel = adc->channel[i];
+		char *name;
+
+		name = asprintf("in_gain%d", i);
+		dev_add_param_enum(&adc->iodev.dev, name, NULL, NULL, &channel->gain,
+			   mcp342x_gain_str,
+			   ARRAY_SIZE(mcp342x_gain_str), NULL);
+		free(name);
+	}
+
+	return 0;
+}
+
+static const struct platform_device_id mcp342x_ids[] = {
+	{ "mcp3421", 1 },
+	{ "mcp3422", 2 },
+	{ "mcp3423", 3 },
+	{ "mcp3424", 4 },
+	{ "mcp3426", 6 },
+	{ "mcp3427", 7 },
+	{ "mcp3428", 8 },
+	{ }
+};
+
+static struct driver_d mcp342x_driver = {
+	.name  = "mcp342x",
+	.probe = mcp342x_probe,
+	.id_table = mcp342x_ids,
+};
+
+static int mcp342x_init(void)
+{
+	i2c_driver_register(&mcp342x_driver);
+	return 0;
+}
+
+device_initcall(mcp342x_init);
-- 
2.6.2


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

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

* [PATCH 4/4] misc: Add PT100 temperature sensor support
  2015-12-08  9:05 [RFC] iodevice support Sascha Hauer
                   ` (2 preceding siblings ...)
  2015-12-08  9:05 ` [PATCH 3/4] misc: Add Microchip MCP342x support Sascha Hauer
@ 2015-12-08  9:05 ` Sascha Hauer
  2015-12-10  6:24 ` [RFC] iodevice support Andrey Smirnov
  4 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2015-12-08  9:05 UTC (permalink / raw)
  To: Barebox List

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/misc/Kconfig  |   5 ++
 drivers/misc/Makefile |   1 +
 drivers/misc/pt100.c  | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 151 insertions(+)
 create mode 100644 drivers/misc/pt100.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 8d44a5c..32e8bea 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -32,4 +32,9 @@ config MCP342X
 	depends on I2C
 	depends on IODEVICE
 
+
+config PT100
+	tristate "PT100 driver"
+	depends on IODEVICE
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 6680334..01b5597 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_IODEVICE)		+= iodevice.o
 obj-$(CONFIG_LM75)		+= lm75.o
 obj-$(CONFIG_IODEVICE)		+= iodevice.o
 obj-$(CONFIG_MCP342X)		+= mcp342x.o
+obj-$(CONFIG_PT100)		+= pt100.o
diff --git a/drivers/misc/pt100.c b/drivers/misc/pt100.c
new file mode 100644
index 0000000..f9d8c6a
--- /dev/null
+++ b/drivers/misc/pt100.c
@@ -0,0 +1,145 @@
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <iodevice.h>
+
+unsigned int pt100[] = {
+	18950, 19380, 19820, 20250, 20680, 21110, 21540, 21970, 22400, 22830, /* -200 - -191 */
+	23250, 23680, 24110, 24540, 24970, 25390, 25820, 26240, 26670, 27100, /* -190 - -181 */
+	27520, 27950, 28370, 28800, 29220, 29640, 30070, 30490, 30910, 31340, /* -180 - -171 */
+	31760, 32180, 32600, 33020, 33440, 33860, 34280, 34700, 35120, 35540, /* -170 - -161 */
+	35960, 36380, 36800, 37220, 37640, 38050, 38470, 38890, 39310, 39720, /* -160 - -151 */
+	40140, 40560, 40970, 41390, 41800, 42220, 42630, 43050, 43460, 43880, /* -150 - -141 */
+	44290, 44700, 45120, 45530, 45940, 46360, 46770, 47180, 47590, 48000, /* -140 - -131 */
+	48420, 48830, 49240, 49650, 50060, 50470, 50880, 51290, 51700, 52110, /* -130 - -121 */
+	52520, 52930, 53340, 53750, 54150, 54560, 54970, 55380, 55790, 56190, /* -120 - -111 */
+	56600, 57010, 57410, 57820, 58230, 58630, 59040, 59440, 59850, 60260, /* -110 - -101 */
+	60660, 61070, 61470, 61880, 62280, 62680, 63090, 63490, 63900, 64300, /* -100 - -91 */
+	64700, 65110, 65510, 65910, 66310, 66720, 67120, 67520, 67920, 68330, /* -90 - -81 */
+	68730, 69130, 69530, 69930, 70330, 70730, 71130, 71530, 71930, 72330, /* -80 - -71 */
+	72730, 73130, 73530, 73930, 74330, 74730, 75130, 75530, 75930, 76330, /* -70 - -61 */
+	76730, 77120, 77520, 77920, 78320, 78720, 79110, 79510, 79910, 80310, /* -60 - -51 */
+	80700, 81100, 81500, 81890, 82290, 82690, 83080, 83480, 83870, 84270, /* -50 - -41 */
+	84670, 85060, 85460, 85850, 86250, 86640, 87040, 87430, 87830, 88220, /* -40 - -31 */
+	88620, 89010, 89400, 89800, 90190, 90590, 90980, 91370, 91770, 92160, /* -30 - -21 */
+	92550, 92950, 93340, 93730, 94120, 94520, 94910, 95300, 95690, 96090, /* -20 - -11 */
+	96480, 96870, 97260, 97650, 98040, 98440, 98830, 99220, 99610, 100000, /* -10 - -1 */
+	100000, 100390, 100780, 101170, 101560, 101950, 102340, 102730, 103120, 103510, /* 0 - 9 */
+	103900, 104290, 104680, 105070, 105460, 105850, 106240, 106630, 107020, 107400, /* 10 - 19 */
+	107790, 108180, 108570, 108960, 109350, 109730, 110120, 110510, 110900, 111290, /* 20 - 29 */
+	111670, 112060, 112450, 112830, 113220, 113610, 114000, 114380, 114770, 115150, /* 30 - 39 */
+	115540, 115930, 116310, 116700, 117080, 117470, 117860, 118240, 118630, 119010, /* 40 - 49 */
+	119400, 119780, 120170, 120550, 120940, 121320, 121710, 122090, 122470, 122860, /* 50 - 59 */
+	123240, 123630, 124010, 124390, 124780, 125160, 125540, 125930, 126310, 126690, /* 60 - 69 */
+	127080, 127460, 127840, 128220, 128610, 128990, 129370, 129750, 130130, 130520, /* 70 - 79 */
+	130900, 131280, 131660, 132040, 132420, 132800, 133180, 133570, 133950, 134330, /* 80 - 89 */
+	134710, 135090, 135470, 135850, 136230, 136610, 136990, 137370, 137750, 138130, /* 90 - 99 */
+	138510, 138880, 139260, 139640, 140020, 140400, 140780, 141160, 141540, 141910, /* 100 - 109 */
+	142290, 142670, 143050, 143430, 143800, 144180, 144560, 144940, 145310, 145690, /* 110 - 119 */
+	146070, 146440, 146820, 147200, 147570, 147950, 148330, 148700, 149080, 149460, /* 120 - 129 */
+	149830, 150210, 150580, 150960, 151330, 151710, 152080, 152460, 152830, 153210, /* 130 - 139 */
+	153580, 153960, 154330, 154710, 155080, 155460, 155830, 156200, 156580, 156950, /* 140 - 149 */
+	157330, 157700, 158070, 158450, 158820, 159190, 159560, 159940, 160310, 160680, /* 150 - 159 */
+	161050, 161430, 161800, 162170, 162540, 162910, 163290, 163660, 164030, 164400, /* 160 - 169 */
+	164770, 165140, 165510, 165890, 166260, 166630, 167000, 167370, 167740, 168110, /* 170 - 179 */
+	168480, 168850, 169220, 169590, 169960, 170330, 170700, 171070, 171430, 171800, /* 180 - 189 */
+	172170, 172540, 172910, 173280, 173650, 174020, 174380, 174750, 175120, 175490, /* 190 - 199 */
+	175860, 176220, 176590, 176960, 177330, 177690, 178060, 178430, 178790, 179160, /* 200 - 209 */
+	179530, 179890, 180260, 180630, 180990, 181360, 181720, 182090, 182460, 182820, /* 210 - 219 */
+	183190, 183550, 183920, 184280, 184650, 185010, 185380, 185740, 186110, 186470, /* 220 - 229 */
+	186840, 187200, 187560, 187930, 188290, 188660, 189020, 189380, 189750, 190110, /* 230 - 239 */
+	190470, 190840, 191200, 191560, 191920, 192290, 192650, 193010, 193370, 193740, /* 240 - 249 */
+	194100, 194460, 194820, 195180, 195550, 195910, 196270, 196630, 196990, 197350, /* 250 - 259 */
+	197710, 198070, 198430, 198790, 199150, 199510, 199870, 200230, 200590, 200950, /* 260 - 269 */
+	201310, 201670, 202030, 202390, 202750, 203110, 203470, 203830, 204190, 204550, /* 270 - 279 */
+	204900, 205260, 205620, 205980, 206340, 206700, 207050, 207410, 207770, 208130, /* 280 - 289 */
+	208480, 208840, 209200, 209560, 209910, 210270, 210630, 210980, 211340, 211700, /* 290 - 299 */
+	212050, 212410, 212760, 213120, 213480, 213830, 214190, 214540, 214900, 215250, /* 300 - 309 */
+	215610, 215960, 216320, 216670, 217030, 217380, 217740, 218090, 218440, 218800, /* 310 - 319 */
+	219150, 219510, 219860, 220210, 220570, 220920, 221270, 221630, 221980, 222330, /* 320 - 329 */
+	222680, 223040, 223390, 223740, 224090, 224450, 224800, 225150, 225500, 225850, /* 330 - 339 */
+	226210, 226560, 226910, 227260, 227610, 227960, 228310, 228660, 229020, 229370, /* 340 - 349 */
+};
+
+struct pt100_priv {
+	struct iodevice iodev;
+	struct iochannel iochan;
+	struct iochannel *input;
+};
+
+static int pt100_get_value(struct iochannel *iochan, int *value)
+{
+	struct pt100_priv *priv = container_of(iochan, struct pt100_priv, iochan);
+	int U_Rx_uV, Rx_mOhm, i, ret;
+
+	ret = iochannel_get_value(priv->input, &U_Rx_uV);
+
+	if (U_Rx_uV > 460000) {
+		dev_err(priv->iodev.hwdev, "Input voltage too high. Sensor broken?");
+		return -EIO;
+	}
+
+	if (U_Rx_uV < 5000) {
+		dev_err(priv->iodev.hwdev, "Input voltage too low. Sensor short circuited?");
+		return -EIO;
+	}
+
+	Rx_mOhm = U_Rx_uV * 7800 / (2048000 - U_Rx_uV) * 1000;
+
+	/* Out of range for PT100. Assume PT1000 */
+	if (Rx_mOhm > 229370)
+		Rx_mOhm /= 10;
+
+	for (i = 0; i < ARRAY_SIZE(pt100) - 1; i++) {
+		if (Rx_mOhm >= pt100[i] && Rx_mOhm < pt100[i + 1]) {
+			*value = i - 200;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int pt100_probe(struct device_d *dev)
+{
+	struct pt100_priv *priv;
+	struct iochannel *iochan;
+	int ret;
+
+	if (!dev->device_node)
+		return -EINVAL;
+
+	iochan = iochannel_get(dev, 0);
+	if (!iochan)
+		return -ENOENT;
+
+	priv = xzalloc(sizeof(*priv));
+
+	priv->input = iochan;
+
+	priv->iodev.num_channels = 1;
+	priv->iodev.hwdev = dev;
+	priv->iodev.read = pt100_get_value;
+	priv->iodev.channels = xmalloc(sizeof(void *));
+	priv->iodev.channels[0] = &priv->iochan;
+	priv->iochan.unit = "C";
+
+	ret = iodevice_register(&priv->iodev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static __maybe_unused struct of_device_id pt100_dt_ids[] = {
+	{
+		.compatible = "zuehlke,pt100",
+	},
+};
+
+static struct driver_d pt100_driver = {
+	.name   = "pt100",
+	.probe  = pt100_probe,
+	.of_compatible = DRV_OF_COMPAT(pt100_dt_ids),
+};
+device_platform_driver(pt100_driver);
-- 
2.6.2


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

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

* Re: [RFC] iodevice support
  2015-12-08  9:05 [RFC] iodevice support Sascha Hauer
                   ` (3 preceding siblings ...)
  2015-12-08  9:05 ` [PATCH 4/4] misc: Add PT100 temperature sensor support Sascha Hauer
@ 2015-12-10  6:24 ` Andrey Smirnov
  2015-12-10 10:25   ` Sascha Hauer
  4 siblings, 1 reply; 9+ messages in thread
From: Andrey Smirnov @ 2015-12-10  6:24 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

On Tue, Dec 8, 2015 at 1:05 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> The following is something like a mixture of Linux IIO and hwmon support
> for the poor. I called it iodevice, but better names are appreciated.
> A iodevice has multiple channels, each providing a value like for
> example a temperature or a voltage. For each iodevice we provide device
> parameters to access the values from the commandline. The C API for a
> consumer consists of iochannel_get() to get a iochannel, and
> iochannel_get_value() to actually read a value.
> As drivers we currently have a LM75 temperature driver and a MCP342x ADC
> driver. Also there is a PT100 driver which itself is a consumer of
> another iodevice, a MCP342x in my case. This is more meant as an example
> since the voltage to temperature conversion function is board specific.


One feature that I would like to suggest/request in this API is
ability to give custom names to individual channels via DT. AFAIU, as
of right now, that the names are hard coded and assigned automatically
by the subsystem.

The reason why I am asking is because a fair number of use-cases for
Barebox that I see is as a board verification tool and as such it is
often used by people who may not be as familiar (if at all) with
Barebox, it's code and how "in_value%d_%s" relates to the actual
parameter reading they are trying to verify.

Thanks,
Andrey

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

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

* Re: [RFC] iodevice support
  2015-12-10  6:24 ` [RFC] iodevice support Andrey Smirnov
@ 2015-12-10 10:25   ` Sascha Hauer
  0 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2015-12-10 10:25 UTC (permalink / raw)
  To: Andrey Smirnov; +Cc: Barebox List

On Wed, Dec 09, 2015 at 10:24:37PM -0800, Andrey Smirnov wrote:
> On Tue, Dec 8, 2015 at 1:05 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > The following is something like a mixture of Linux IIO and hwmon support
> > for the poor. I called it iodevice, but better names are appreciated.
> > A iodevice has multiple channels, each providing a value like for
> > example a temperature or a voltage. For each iodevice we provide device
> > parameters to access the values from the commandline. The C API for a
> > consumer consists of iochannel_get() to get a iochannel, and
> > iochannel_get_value() to actually read a value.
> > As drivers we currently have a LM75 temperature driver and a MCP342x ADC
> > driver. Also there is a PT100 driver which itself is a consumer of
> > another iodevice, a MCP342x in my case. This is more meant as an example
> > since the voltage to temperature conversion function is board specific.
> 
> 
> One feature that I would like to suggest/request in this API is
> ability to give custom names to individual channels via DT. AFAIU, as
> of right now, that the names are hard coded and assigned automatically
> by the subsystem.
> 
> The reason why I am asking is because a fair number of use-cases for
> Barebox that I see is as a board verification tool and as such it is
> often used by people who may not be as familiar (if at all) with
> Barebox, it's code and how "in_value%d_%s" relates to the actual
> parameter reading they are trying to verify.

Note the device name is already configurable in device tree using
aliases, Adding an foo_temperature = &lm75 will result in the device
being named foo_temperature, so echo $foo_temperature.in_value0_mC will
give you the temperature. Ok, that alone doesn't solve the problem. We
still can only name devices and not individual channels.

I'm just thinking about registering a single device named 'sensors' or
similar and register all parameters under that device instead of their
individual devices.

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] 9+ messages in thread

* Re: [PATCH 1/4] misc: Add iodevice support
  2015-12-08  9:05 ` [PATCH 1/4] misc: Add " Sascha Hauer
@ 2015-12-10 20:42   ` Trent Piepho
  2015-12-11  7:37     ` Sascha Hauer
  0 siblings, 1 reply; 9+ messages in thread
From: Trent Piepho @ 2015-12-10 20:42 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

On Tue, 2015-12-08 at 10:05 +0100, Sascha Hauer wrote:
> +int iodevice_register(struct iodevice *iodev)
> +{
> +	const char *devname = NULL;
> +	int i, ret;
> +
> +	if (iodev->hwdev->device_node) {
> +		devname = of_alias_get(iodev->hwdev->device_node);
> +		iodev->dev.id = DEVICE_ID_SINGLE;
> +	}
> +
> +	if (!devname) {
> +		devname = "io";
> +		iodev->dev.id = DEVICE_ID_DYNAMIC;
> +	}
> +
> +	strcpy(iodev->dev.name, devname);
> +
> +	iodev->dev.parent = iodev->hwdev;
> +
> +	ret = register_device(&iodev->dev);

Why does every driver/subsystem need to implement its own alias
support?  

Since register_device() has access to
(&iodev->dev)->parent->device_node, couldn't it do the alias lookup
instead, so that each driver doesn't need to?

Then one could write:

iodev->dev.parent = iodev->hwdev;
strcpy(iodev->dev.name, "io");
iodev->dev.id = DEVICE_ID_DYNAMIC;
ret = register_device(&iodev->dev);

I guess this doesn't work exactly for net drivers, since they want to do
s/ethernet(\d+)/eth\1/ on the alias name.

And some drivers create a cdev the alias should be applied to instead of
a dev.  Though I supposed devfs_create() could do the same thing.
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* Re: [PATCH 1/4] misc: Add iodevice support
  2015-12-10 20:42   ` Trent Piepho
@ 2015-12-11  7:37     ` Sascha Hauer
  0 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2015-12-11  7:37 UTC (permalink / raw)
  To: Trent Piepho; +Cc: Barebox List

On Thu, Dec 10, 2015 at 08:42:42PM +0000, Trent Piepho wrote:
> On Tue, 2015-12-08 at 10:05 +0100, Sascha Hauer wrote:
> > +int iodevice_register(struct iodevice *iodev)
> > +{
> > +	const char *devname = NULL;
> > +	int i, ret;
> > +
> > +	if (iodev->hwdev->device_node) {
> > +		devname = of_alias_get(iodev->hwdev->device_node);
> > +		iodev->dev.id = DEVICE_ID_SINGLE;
> > +	}
> > +
> > +	if (!devname) {
> > +		devname = "io";
> > +		iodev->dev.id = DEVICE_ID_DYNAMIC;
> > +	}
> > +
> > +	strcpy(iodev->dev.name, devname);
> > +
> > +	iodev->dev.parent = iodev->hwdev;
> > +
> > +	ret = register_device(&iodev->dev);
> 
> Why does every driver/subsystem need to implement its own alias
> support?

I think that has historic reasons. When beginning with device tree we
didn't want to change the behaviours of all unrelated drivers. Now that
we are more familiar with device tree and adopt the aliases approach to
more and more drivers you are right: We can push the alias resolving
out of the drivers and more to the framework level.

> 
> Since register_device() has access to
> (&iodev->dev)->parent->device_node, couldn't it do the alias lookup
> instead, so that each driver doesn't need to?
> 
> Then one could write:
> 
> iodev->dev.parent = iodev->hwdev;
> strcpy(iodev->dev.name, "io");
> iodev->dev.id = DEVICE_ID_DYNAMIC;
> ret = register_device(&iodev->dev);
> 
> I guess this doesn't work exactly for net drivers, since they want to do
> s/ethernet(\d+)/eth\1/ on the alias name.

The network drivers already do something similar. They pick only the
number from the "ethernetx" alias, see net/eth.c:

	edev->dev.id = of_alias_get_id(edev->dev.parent->device_node, "ethernet");

> 
> And some drivers create a cdev the alias should be applied to instead of
> a dev.  Though I supposed devfs_create() could do the same thing.

I'm not sure if we should handle aliases in devfs_create(), but at least
we should handle it in the subsystem so that the individual drivers no
longer have to care about it.

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] 9+ messages in thread

end of thread, other threads:[~2015-12-11  7:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-08  9:05 [RFC] iodevice support Sascha Hauer
2015-12-08  9:05 ` [PATCH 1/4] misc: Add " Sascha Hauer
2015-12-10 20:42   ` Trent Piepho
2015-12-11  7:37     ` Sascha Hauer
2015-12-08  9:05 ` [PATCH 2/4] misc: Add basic LM75 temperature driver Sascha Hauer
2015-12-08  9:05 ` [PATCH 3/4] misc: Add Microchip MCP342x support Sascha Hauer
2015-12-08  9:05 ` [PATCH 4/4] misc: Add PT100 temperature sensor support Sascha Hauer
2015-12-10  6:24 ` [RFC] iodevice support Andrey Smirnov
2015-12-10 10:25   ` Sascha Hauer

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