mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Daniel Schultz <d.schultz@phytec.de>
To: barebox@lists.infradead.org
Subject: [PATCH 1/3] common: Add autoenable for components
Date: Fri, 27 Oct 2017 16:37:39 +0200	[thread overview]
Message-ID: <1509115061-4385-1-git-send-email-d.schultz@phytec.de> (raw)

This patch adds an API to automatically enable either hardware components
with existing device drivers or i2c clients. All functions take a device
tree path to find the hardware and will fix up the node status in the
kernel device tree, if it's accessible.

Signed-off-by: Daniel Schultz <d.schultz@phytec.de>
---
 common/Kconfig       |   9 +++++
 common/Makefile      |   1 +
 common/autoenable.c  | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/autoenable.h |  21 ++++++++++
 4 files changed, 140 insertions(+)
 create mode 100644 common/autoenable.c
 create mode 100644 include/autoenable.h

diff --git a/common/Kconfig b/common/Kconfig
index 57418ca..8d2a3e6 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -712,6 +712,15 @@ config CONSOLE_NONE
 
 endchoice
 
+config KERNEL_AUTOENABLE
+	bool
+	prompt "Autoenable of components"
+	help
+	  Say Y to unlock an API for automatically enable either hardware
+	  components with existing device drivers or i2c clients. All functions
+	  take a device tree path to find the hardware and will fix up the node
+	  status in the kernel device tree, if it's accessible.
+
 choice
 	prompt "Console activation strategy"
 	depends on CONSOLE_FULL
diff --git a/common/Makefile b/common/Makefile
index 8cd0ab3..4d7b0f9 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_FLEXIBLE_BOOTARGS)	+= bootargs.o
 obj-$(CONFIG_GLOBALVAR)		+= globalvar.o
 obj-$(CONFIG_GREGORIAN_CALENDER) += date.o
 obj-$(CONFIG_KALLSYMS)		+= kallsyms.o
+obj-$(CONFIG_KERNEL_AUTOENABLE) += autoenable.o
 obj-$(CONFIG_MALLOC_DLMALLOC)	+= dlmalloc.o
 obj-$(CONFIG_MALLOC_TLSF)	+= tlsf_malloc.o tlsf.o
 obj-$(CONFIG_MALLOC_DUMMY)	+= dummy_malloc.o
diff --git a/common/autoenable.c b/common/autoenable.c
new file mode 100644
index 0000000..be76942
--- /dev/null
+++ b/common/autoenable.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2017 PHYTEC Messtechnik GmbH,
+ * Author: Daniel Schultz <d.schultz@phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <linux/err.h>
+#include <of.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <i2c/i2c.h>
+
+/**
+ * autoenable_device_by_path() - Autoenable a device by a device tree path
+ * @param path Device tree path up from the root to the device
+ * @return 0 on success, -enodev on failure. If no device found in the device
+ * tree.
+ *
+ * This function will search for a device and will enable it in the kernel
+ * device tree, if it exists and is loaded.
+ */
+int autoenable_device_by_path(char *path)
+{
+	struct device_d *device;
+	struct device_node *node;
+	int ret;
+
+	node = of_find_node_by_name(NULL, path);
+	if (!node)
+		node = of_find_node_by_path(path);
+
+	if (!node)
+		return -ENODEV;
+
+	device = of_find_device_by_node(node);
+	if (!device)
+		return -ENODEV;
+
+	ret = of_register_set_status_fixup(path, 1);
+	if (!ret)
+		printf("autoenabled %s\n", device->name);
+	return ret;
+}
+
+/**
+ * autoenable_i2c_by_path - Autoenable a i2c client by a device tree path
+ * @param path Device tree path up from the root to the i2c client
+ * @return 0 on success, -enodev on failure. If no i2c client found in the i2c
+ * device tree.
+ *
+ * This function will search for a i2c client, tries to write to the client and
+ * will enable it in the kernel device tree, if it exists and is accessible.
+ */
+int autoenable_i2c_by_path(char *path)
+{
+	struct device_node *node;
+	struct i2c_adapter *i2c_adapter;
+	struct i2c_msg msg;
+	char data[1] = {0x0};
+	int addr;
+	const __be32 *ip;
+	int ret;
+
+	node = of_find_node_by_name(NULL, path);
+	if (!node)
+		node = of_find_node_by_path(path);
+	if (!node)
+		return -ENODEV;
+	if (!node->parent)
+		return -ENODEV;
+
+	ip = of_get_property(node, "reg", NULL);
+	if (!ip)
+		return -ENODEV;
+	addr = be32_to_cpup(ip);
+
+	i2c_adapter = of_find_i2c_adapter_by_node(node->parent);
+	if (!i2c_adapter)
+		return -ENODEV;
+
+	msg.buf = data;
+	msg.addr = addr;
+	msg.len = 1;
+
+	/* Try to communicate with the i2c client */
+	ret = i2c_transfer(i2c_adapter, &msg, 1);
+	if (ret == -EREMOTEIO) {
+		return -ENODEV;
+	}
+	if (ret < 1) {
+		printf("failed to autoenable i2c device on address 0x%x with %i\n",
+								addr, ret);
+		return ret;
+	}
+
+	ret = of_register_set_status_fixup(path, 1);
+	if (!ret)
+		printf("autoenabled i2c device %s\n", node->name);
+
+	return ret;
+}
diff --git a/include/autoenable.h b/include/autoenable.h
new file mode 100644
index 0000000..26811b0
--- /dev/null
+++ b/include/autoenable.h
@@ -0,0 +1,21 @@
+#ifndef __AUTOENABLE_H
+#define __AUTOENABLE_H
+
+#include <linux/err.h>
+
+#ifdef CONFIG_KERNEL_AUTOENABLE
+int autoenable_device_by_path(char *path);
+int autoenable_i2c_by_path(char *path);
+#else
+inline int autoenable_device_by_path(char *path)
+{
+	return -EINVAL;
+}
+
+inline int autoenable_i2c_by_path(char *path)
+{
+	return -EINVAL;
+}
+#endif /* CONFIG_KERNEL_AUTOENABLE */
+
+#endif /* __AUTOENABLE_H */
-- 
2.7.4


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

             reply	other threads:[~2017-10-27 14:38 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-27 14:37 Daniel Schultz [this message]
2017-10-27 14:37 ` [PATCH 2/3] ARM: dts: AM335x: Add dummy i2c nodes Daniel Schultz
2017-10-27 14:37 ` [PATCH 3/3] ARM: phytec-som-am335x: Add autoenable Daniel Schultz
2017-11-01  8:44 ` [PATCH 1/3] common: Add autoenable for components Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1509115061-4385-1-git-send-email-d.schultz@phytec.de \
    --to=d.schultz@phytec.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox