linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/3] mikroBUS driver for add-on boards
@ 2020-08-18 12:48 Vaishnav M A
  2020-08-18 12:48 ` [RFC PATCH v2 1/3] add mikrobus descriptors to greybus_manifest Vaishnav M A
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: Vaishnav M A @ 2020-08-18 12:48 UTC (permalink / raw)
  To: greybus-dev, linux-kernel, gregkh, arnd, johan, elder
  Cc: Vaishnav M A, robh, mchehab+huawei, davem, jkridner, drew,
	robertcnelson, rajkovic, chrisfriedt, zoran.stojsavljevic

Hi,

This Patch series is an update to the mikroBUS driver
RFC v1 Patch : https://lkml.org/lkml/2020/7/24/518 .
The mikrobus driver is updated to add mikrobus ports from device-tree
overlays, the debug interfaces for adding mikrobus ports through sysFS
is removed, and the driver considers the extended usage of mikrobus
port pins from their standard purposes.

change log:
        v2: support for adding mikroBUS ports from DT overlays,
        remove debug sysFS interface for adding mikrobus ports,
        consider extended pin usage/deviations from mikrobus standard
        specifications,
        use greybus CPort protocol enum instead of new protcol enums
        Fix cases of wrong indendation, ignoring return values, freeing
        allocated resources in case of errors and other style suggestions
        in v1 review.

Vaishnav M A (3):
  add mikrobus descriptors to greybus_manifest
  mikroBUS driver for add-on boards on mikrobus ports
  Add Device Tree Bindings for mikroBUS port

 .../bindings/misc/linux,mikrobus.txt          |  81 ++
 MAINTAINERS                                   |   6 +
 drivers/misc/Kconfig                          |   1 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/mikrobus/Kconfig                 |  16 +
 drivers/misc/mikrobus/Makefile                |   7 +
 drivers/misc/mikrobus/mikrobus_core.c         | 692 ++++++++++++++++++
 drivers/misc/mikrobus/mikrobus_core.h         | 191 +++++
 drivers/misc/mikrobus/mikrobus_manifest.c     | 444 +++++++++++
 drivers/misc/mikrobus/mikrobus_manifest.h     |  21 +
 drivers/misc/mikrobus/mikrobus_port.c         | 171 +++++
 include/linux/greybus/greybus_manifest.h      |  47 ++
 12 files changed, 1678 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/linux,mikrobus.txt
 create mode 100644 drivers/misc/mikrobus/Kconfig
 create mode 100644 drivers/misc/mikrobus/Makefile
 create mode 100644 drivers/misc/mikrobus/mikrobus_core.c
 create mode 100644 drivers/misc/mikrobus/mikrobus_core.h
 create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.c
 create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.h
 create mode 100644 drivers/misc/mikrobus/mikrobus_port.c

-- 
2.25.1


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

* [RFC PATCH v2 1/3] add mikrobus descriptors to greybus_manifest
  2020-08-18 12:48 [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Vaishnav M A
@ 2020-08-18 12:48 ` Vaishnav M A
  2020-08-20  0:49   ` Vaishnav M A
  2020-08-18 12:48 ` [RFC PATCH v2 2/3] mikroBUS driver for add-on boards on mikrobus ports Vaishnav M A
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 16+ messages in thread
From: Vaishnav M A @ 2020-08-18 12:48 UTC (permalink / raw)
  To: greybus-dev, linux-kernel, gregkh, arnd, johan, elder
  Cc: Vaishnav M A, robh, mchehab+huawei, davem, jkridner, drew,
	robertcnelson, rajkovic, chrisfriedt, zoran.stojsavljevic

This patch adds new descriptors used in the manifest parsing inside
the mikrobus driver, the device descriptor help to describe the
devices on a mikroBUS port, mikrobus descriptor is used to set up
the mikrobus port pinmux and GPIO states and property descriptor
to pass named properties to device drivers through the Unified
Properties API under linux/property.h

The corresponding pull request for manifesto is updated
at : https://github.com/projectara/manifesto/pull/2

Signed-off-by: Vaishnav M A <vaishnav@beagleboard.org>
---
 include/linux/greybus/greybus_manifest.h | 47 ++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/include/linux/greybus/greybus_manifest.h b/include/linux/greybus/greybus_manifest.h
index 6e62fe478712..821661ea7f01 100644
--- a/include/linux/greybus/greybus_manifest.h
+++ b/include/linux/greybus/greybus_manifest.h
@@ -23,6 +23,9 @@ enum greybus_descriptor_type {
 	GREYBUS_TYPE_STRING		= 0x02,
 	GREYBUS_TYPE_BUNDLE		= 0x03,
 	GREYBUS_TYPE_CPORT		= 0x04,
+	GREYBUS_TYPE_MIKROBUS		= 0x05,
+	GREYBUS_TYPE_PROPERTY		= 0x06,
+	GREYBUS_TYPE_DEVICE		= 0x07,
 };
 
 enum greybus_protocol {
@@ -151,6 +154,47 @@ struct greybus_descriptor_cport {
 	__u8	protocol_id;	/* enum greybus_protocol */
 } __packed;
 
+/*
+ * A mikrobus descriptor is used to describe the details
+ * about the bus ocnfiguration for the add-on board
+ * connected to the mikrobus port.
+ */
+struct greybus_descriptor_mikrobus {
+	__u8 pin_state[12];
+} __packed;
+
+/*
+ * A property descriptor is used to pass named properties
+ * to device drivers through the unified device properties
+ * interface under linux/property.h
+ */
+struct greybus_descriptor_property {
+	__u8 length;
+	__u8 id;
+	__u8 propname_stringid;
+	__u8 type;
+	__u8 value[0];
+} __packed;
+
+/*
+ * A device descriptor is used to describe the
+ * details required by a add-on board device
+ * driver.
+ */
+struct greybus_descriptor_device {
+	__u8 id;
+	__u8 driver_stringid;
+	__u8 protocol;
+	__u8 reg;
+	__le32 max_speed_hz;
+	__u8 irq;
+	__u8 irq_type;
+	__u8 mode;
+	__u8 prop_link;
+	__u8 gpio_link;
+	__u8 pad[3];
+} __packed;
+
 struct greybus_descriptor_header {
 	__le16	size;
 	__u8	type;		/* enum greybus_descriptor_type */
@@ -164,6 +208,9 @@ struct greybus_descriptor {
 		struct greybus_descriptor_interface	interface;
 		struct greybus_descriptor_bundle	bundle;
 		struct greybus_descriptor_cport		cport;
+		struct greybus_descriptor_mikrobus	mikrobus;
+		struct greybus_descriptor_property	property;
+		struct greybus_descriptor_device	device;
 	};
 } __packed;
 
-- 
2.25.1


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

* [RFC PATCH v2 2/3] mikroBUS driver for add-on boards on mikrobus ports
  2020-08-18 12:48 [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Vaishnav M A
  2020-08-18 12:48 ` [RFC PATCH v2 1/3] add mikrobus descriptors to greybus_manifest Vaishnav M A
@ 2020-08-18 12:48 ` Vaishnav M A
  2020-08-18 12:48 ` [RFC PATCH v2 3/3] Add Device Tree Bindings for mikroBUS port Vaishnav M A
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 16+ messages in thread
From: Vaishnav M A @ 2020-08-18 12:48 UTC (permalink / raw)
  To: greybus-dev, linux-kernel, gregkh, arnd, johan, elder
  Cc: Vaishnav M A, robh, mchehab+huawei, davem, jkridner, drew,
	robertcnelson, rajkovic, chrisfriedt, zoran.stojsavljevic

The mikrobus driver is updated to add mikrobus ports from device-tree
overlays, the debug interfaces for adding mikrobus ports through sysFS
is removed, and the driver considers the extended usage of mikrobus
port pins from their standard purpose, for example an SHT15 add-on
board will need the I2C pins to be configured as GPIOs for the
corresponding driver(drivers/hwmon/sht15.c) to work correctly
to consider cases like these the mikrobus driver supports setting
the pinmux states and can consider each Pin of the mikrobus port
as GPIO if required.

 The manifests for supported 110 add-on boards are available here:
 https://github.com/vaishnav98/manifesto/tree/mikrobusv3

Signed-off-by: Vaishnav M A <vaishnav@beagleboard.org>
---
 MAINTAINERS                               |   6 +
 drivers/misc/Kconfig                      |   1 +
 drivers/misc/Makefile                     |   1 +
 drivers/misc/mikrobus/Kconfig             |  16 +
 drivers/misc/mikrobus/Makefile            |   7 +
 drivers/misc/mikrobus/mikrobus_core.c     | 692 ++++++++++++++++++++++
 drivers/misc/mikrobus/mikrobus_core.h     | 191 ++++++
 drivers/misc/mikrobus/mikrobus_manifest.c | 444 ++++++++++++++
 drivers/misc/mikrobus/mikrobus_manifest.h |  21 +
 drivers/misc/mikrobus/mikrobus_port.c     | 171 ++++++
 10 files changed, 1550 insertions(+)
 create mode 100644 drivers/misc/mikrobus/Kconfig
 create mode 100644 drivers/misc/mikrobus/Makefile
 create mode 100644 drivers/misc/mikrobus/mikrobus_core.c
 create mode 100644 drivers/misc/mikrobus/mikrobus_core.h
 create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.c
 create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.h
 create mode 100644 drivers/misc/mikrobus/mikrobus_port.c

diff --git a/MAINTAINERS b/MAINTAINERS
index deaafb617361..ffd0eb688618 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11543,6 +11543,12 @@ M:	Oliver Neukum <oliver@neukum.org>
 S:	Maintained
 F:	drivers/usb/image/microtek.*
 
+MIKROBUS ADDON BOARD DRIVER
+M:	Vaishnav M A <vaishnav@beagleboard.org>
+S:	Maintained
+W:	https://elinux.org/Mikrobus
+F:	drivers/misc/mikrobus/
+
 MIPS
 M:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 L:	linux-mips@vger.kernel.org
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index ce136d685d14..cb1539f39b30 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -472,4 +472,5 @@ source "drivers/misc/ocxl/Kconfig"
 source "drivers/misc/cardreader/Kconfig"
 source "drivers/misc/habanalabs/Kconfig"
 source "drivers/misc/uacce/Kconfig"
+source "drivers/misc/mikrobus/Kconfig"
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c7bd01ac6291..45486dd77da5 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_VMWARE_BALLOON)	+= vmw_balloon.o
 obj-$(CONFIG_PCH_PHUB)		+= pch_phub.o
 obj-y				+= ti-st/
 obj-y				+= lis3lv02d/
+obj-y				+= mikrobus/
 obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
 obj-$(CONFIG_INTEL_MEI)		+= mei/
 obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
diff --git a/drivers/misc/mikrobus/Kconfig b/drivers/misc/mikrobus/Kconfig
new file mode 100644
index 000000000000..5f42bc4e9410
--- /dev/null
+++ b/drivers/misc/mikrobus/Kconfig
@@ -0,0 +1,16 @@
+menuconfig MIKROBUS
+	tristate "Module for instantiating devices on mikroBUS ports"
+	help
+	  This option enables the mikroBUS driver. mikroBUS is an add-on
+	  board socket standard that offers maximum expandability with
+	  the smallest number of pins. The mikroBUS driver instantiates
+	  devices on a mikroBUS port described by identifying data present
+	  in an add-on board resident EEPROM, more details on the mikroBUS
+	  driver support and discussion can be found in this eLinux wiki :
+	  elinux.org/Mikrobus
+
+
+	  Say Y here to enable support for this driver.
+
+	  To compile this code as a module, chose M here: the module
+	  will be called mikrobus.ko
diff --git a/drivers/misc/mikrobus/Makefile b/drivers/misc/mikrobus/Makefile
new file mode 100644
index 000000000000..af7256510310
--- /dev/null
+++ b/drivers/misc/mikrobus/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+# mikroBUS Core
+
+mikrobus-y :=	mikrobus_core.o	mikrobus_manifest.o
+mikrobus_port-y :=	mikrobus_port.o
+obj-$(CONFIG_MIKROBUS) += mikrobus.o
+obj-$(CONFIG_MIKROBUS) += mikrobus_port.o
\ No newline at end of file
diff --git a/drivers/misc/mikrobus/mikrobus_core.c b/drivers/misc/mikrobus/mikrobus_core.c
new file mode 100644
index 000000000000..312e2d0d634c
--- /dev/null
+++ b/drivers/misc/mikrobus/mikrobus_core.c
@@ -0,0 +1,692 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mikroBUS driver for instantiating add-on
+ * board devices with an identifier EEPROM
+ *
+ * Copyright 2020 Vaishnav M A, BeagleBoard.org Foundation.
+ */
+
+#define pr_fmt(fmt) "mikrobus:%s: " fmt, __func__
+
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/nvmem-provider.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+#include <linux/serdev.h>
+#include <linux/property.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/greybus/greybus_manifest.h>
+
+#include "mikrobus_core.h"
+#include "mikrobus_manifest.h"
+
+static DEFINE_MUTEX(core_lock);
+static DEFINE_IDR(mikrobus_port_idr);
+static struct class_compat *mikrobus_port_compat_class;
+int	__mikrobus_first_dynamic_bus_num;
+static bool is_registered;
+
+const char *MIKROBUS_PINCTRL_STR[] = {"pwm", "uart", "i2c", "spi"};
+
+struct bus_type mikrobus_bus_type = {
+	.name = "mikrobus",
+};
+EXPORT_SYMBOL_GPL(mikrobus_bus_type);
+
+static int mikrobus_port_scan_eeprom(struct mikrobus_port *port)
+{
+	struct addon_board_info *board;
+	int manifest_size;
+	char header[12];
+	int retval;
+	char *buf;
+
+	retval = nvmem_device_read(port->eeprom, 0, 12, header);
+	if (retval != 12) {
+		dev_err(&port->dev, "failed to fetch manifest header %d\n",
+			retval);
+		return -EINVAL;
+	}
+	manifest_size = mikrobus_manifest_header_validate(header, 12);
+	if (manifest_size < 0) {
+		dev_err(&port->dev, "invalid manifest size %d\n",
+			manifest_size);
+		return -EINVAL;
+	}
+	buf = kzalloc(manifest_size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	retval = nvmem_device_read(port->eeprom, 0, manifest_size, buf);
+	if (retval != manifest_size) {
+		dev_err(&port->dev, "failed to fetch manifest %d\n", retval);
+		retval = -EINVAL;
+		goto err_free_buf;
+	}
+	board = kzalloc(sizeof(*board), GFP_KERNEL);
+	if (!board) {
+		retval = -ENOMEM;
+		goto err_free_buf;
+	}
+	INIT_LIST_HEAD(&board->manifest_descs);
+	INIT_LIST_HEAD(&board->devices);
+	retval = mikrobus_manifest_parse(board, buf, manifest_size);
+	if (retval) {
+		dev_err(&port->dev, "failed to parse manifest, size %d\n",
+			manifest_size);
+		goto err_free_board;
+	}
+	retval = mikrobus_board_register(port, board);
+	if (retval) {
+		dev_err(&port->dev, "failed to register board %s\n",
+			board->name);
+		goto err_free_board;
+	}
+	kfree(buf);
+	return 0;
+err_free_board:
+	kfree(board);
+err_free_buf:
+	kfree(buf);
+	return retval;
+}
+
+static ssize_t name_show(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	return sprintf(buf, "%s\n", to_mikrobus_port(dev)->name);
+}
+static DEVICE_ATTR_RO(name);
+
+static ssize_t new_device_store(struct device *dev, struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct mikrobus_port *port = to_mikrobus_port(dev);
+	struct addon_board_info *board;
+	int retval;
+
+	if (port->board) {
+		dev_err(dev, "already has board registered\n");
+		return -EBUSY;
+	}
+
+	board = kzalloc(sizeof(*board), GFP_KERNEL);
+	if (!board)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&board->manifest_descs);
+	INIT_LIST_HEAD(&board->devices);
+	retval = mikrobus_manifest_parse(board, (void *)buf, count);
+	if (retval) {
+		dev_err(dev, "failed to parse manifest\n");
+		goto err_free_board;
+	}
+	retval = mikrobus_board_register(port, board);
+	if (retval) {
+		dev_err(dev, "failed to register board %s\n", board->name);
+		goto err_free_board;
+	}
+	return count;
+err_free_board:
+	kfree(board);
+	return retval;
+}
+static DEVICE_ATTR_WO(new_device);
+
+static ssize_t rescan_store(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct mikrobus_port *port = to_mikrobus_port(dev);
+	unsigned long id;
+	int retval;
+
+	if (kstrtoul(buf, 0, &id)) {
+		dev_err(dev, "cannot parse trigger\n");
+		return -EINVAL;
+	}
+	if (port->board) {
+		dev_err(dev, "already has board registered\n");
+		return -EBUSY;
+	}
+	retval = mikrobus_port_scan_eeprom(port);
+	if (retval) {
+		dev_err(dev, "board register from manifest failed\n");
+		return -EINVAL;
+	}
+	return count;
+}
+static DEVICE_ATTR_WO(rescan);
+
+static ssize_t delete_device_store(struct device *dev, struct device_attribute *attr,
+				   const char *buf, size_t count)
+{
+	struct mikrobus_port *port = to_mikrobus_port(dev);
+	unsigned long id;
+
+	if (kstrtoul(buf, 0, &id)) {
+		dev_err(dev, "cannot parse board id");
+		return -EINVAL;
+	}
+	if (!port->board) {
+		dev_err(dev, "does not have registered boards");
+		return -ENODEV;
+	}
+	mikrobus_board_unregister(port, port->board);
+	return count;
+}
+static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, 0200, NULL, delete_device_store);
+
+static struct attribute *mikrobus_port_attrs[] = {
+	&dev_attr_new_device.attr, &dev_attr_rescan.attr,
+	&dev_attr_delete_device.attr, &dev_attr_name.attr, NULL};
+ATTRIBUTE_GROUPS(mikrobus_port);
+
+static void mikrobus_port_release(struct device *dev)
+{
+	struct mikrobus_port *port = to_mikrobus_port(dev);
+
+	mutex_lock(&core_lock);
+	idr_remove(&mikrobus_port_idr, port->id);
+	mutex_unlock(&core_lock);
+	kfree(port);
+}
+
+struct device_type mikrobus_port_type = {
+	.groups = mikrobus_port_groups,
+	.release = mikrobus_port_release,
+};
+EXPORT_SYMBOL_GPL(mikrobus_port_type);
+
+int mikrobus_port_pinctrl_select(struct mikrobus_port *port)
+{
+	struct pinctrl_state *state;
+	int retval;
+	int i;
+
+	for (i = 0; i < MIKROBUS_NUM_PINCTRL_STATE; i++) {
+		state = pinctrl_lookup_state(port->pinctrl,
+					     port->pinctrl_selected[i]);
+		if (!IS_ERR(state)) {
+			retval = pinctrl_select_state(port->pinctrl, state);
+			pr_info("setting pinctrl %s\n",
+				port->pinctrl_selected[i]);
+			if (retval != 0) {
+				dev_err(&port->dev, "failed to select state %s\n",
+					port->pinctrl_selected[i]);
+				return retval;
+			}
+		} else {
+			dev_err(&port->dev, "failed to find state %s\n",
+				port->pinctrl_selected[i]);
+			return PTR_ERR(state);
+		}
+	}
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(mikrobus_port_pinctrl_select);
+
+static int mikrobus_port_pinctrl_setup(struct mikrobus_port *port, struct addon_board_info *board)
+{
+	int retval;
+	int i;
+
+	for (i = 0; i < MIKROBUS_NUM_PINCTRL_STATE; i++) {
+		switch (i) {
+		case MIKROBUS_PINCTRL_PWM:
+			if (board->pin_state[MIKROBUS_PIN_PWM] == MIKROBUS_STATE_PWM)
+				sprintf(port->pinctrl_selected[i], "%s_%s",
+					MIKROBUS_PINCTRL_STR[i], PINCTRL_STATE_DEFAULT);
+			else
+				sprintf(port->pinctrl_selected[i], "%s_%s",
+					MIKROBUS_PINCTRL_STR[i], MIKROBUS_PINCTRL_STATE_GPIO);
+			break;
+		case MIKROBUS_PINCTRL_UART:
+			if (board->pin_state[MIKROBUS_PIN_RX] == MIKROBUS_STATE_UART)
+				sprintf(port->pinctrl_selected[i], "%s_%s",
+					MIKROBUS_PINCTRL_STR[i], PINCTRL_STATE_DEFAULT);
+			else
+				sprintf(port->pinctrl_selected[i], "%s_%s",
+					MIKROBUS_PINCTRL_STR[i], MIKROBUS_PINCTRL_STATE_GPIO);
+			break;
+		case MIKROBUS_PINCTRL_I2C:
+			if (board->pin_state[MIKROBUS_PIN_SCL] == MIKROBUS_STATE_I2C)
+				sprintf(port->pinctrl_selected[i], "%s_%s",
+					MIKROBUS_PINCTRL_STR[i], PINCTRL_STATE_DEFAULT);
+			else
+				sprintf(port->pinctrl_selected[i], "%s_%s",
+					MIKROBUS_PINCTRL_STR[i], MIKROBUS_PINCTRL_STATE_GPIO);
+			break;
+		case MIKROBUS_PINCTRL_SPI:
+			if (board->pin_state[MIKROBUS_PIN_MOSI] == MIKROBUS_STATE_SPI)
+				sprintf(port->pinctrl_selected[i], "%s_%s",
+					MIKROBUS_PINCTRL_STR[i], PINCTRL_STATE_DEFAULT);
+			else
+				sprintf(port->pinctrl_selected[i], "%s_%s",
+					MIKROBUS_PINCTRL_STR[i], MIKROBUS_PINCTRL_STATE_GPIO);
+			break;
+		}
+	}
+
+	retval = mikrobus_port_pinctrl_select(port);
+	if (retval)
+		dev_err(&port->dev, "failed to select pinctrl states [%d]", retval);
+	return retval;
+}
+
+static int mikrobus_irq_get(struct mikrobus_port *port, int irqno,
+			    int irq_type)
+{
+	int irq;
+
+	if (irqno > port->gpios->ndescs - 1) {
+		dev_err(&port->dev, "GPIO %d does not exist", irqno);
+		return -ENODEV;
+	}
+
+	irq = gpiod_to_irq(port->gpios->desc[irqno]);
+	if (irq < 0) {
+		dev_err(&port->dev, "could not get irq %d", irqno);
+		return -EINVAL;
+	}
+	irq_set_irq_type(irq, irq_type);
+	return irq;
+}
+
+static int mikrobus_gpio_setup(struct gpio_desc *gpio, int gpio_state)
+{
+	int retval;
+
+	switch (gpio_state) {
+	case MIKROBUS_STATE_INPUT:
+		retval = gpiod_direction_input(gpio);
+		break;
+	case MIKROBUS_STATE_OUTPUT_HIGH:
+		retval = gpiod_direction_output(gpio, 1);
+		break;
+	case MIKROBUS_STATE_OUTPUT_LOW:
+		retval = gpiod_direction_output(gpio, 0);
+		break;
+	case MIKROBUS_STATE_PWM:
+	case MIKROBUS_STATE_SPI:
+	case MIKROBUS_STATE_I2C:
+	default:
+		return 0;
+	}
+	return retval;
+}
+
+static char *mikrobus_gpio_chip_name_get(struct mikrobus_port *port, int gpio)
+{
+	char *name;
+	struct gpio_chip *gpiochip;
+
+	if (gpio > port->gpios->ndescs - 1)
+		return NULL;
+
+	gpiochip = gpiod_to_chip(port->gpios->desc[gpio]);
+	name = kmemdup(gpiochip->label, MIKROBUS_NAME_SIZE, GFP_KERNEL);
+	return name;
+}
+
+static int mikrobus_gpio_hwnum_get(struct mikrobus_port *port, int gpio)
+{
+	int hwnum;
+	struct gpio_chip *gpiochip;
+
+	if (gpio > port->gpios->ndescs - 1)
+		return -ENODEV;
+
+	gpiochip = gpiod_to_chip(port->gpios->desc[gpio]);
+	hwnum = desc_to_gpio(port->gpios->desc[gpio]) - gpiochip->base;
+	return hwnum;
+}
+
+static void mikrobus_board_device_release_all(struct addon_board_info *info)
+{
+	struct board_device_info *dev;
+	struct board_device_info *next;
+
+	list_for_each_entry_safe(dev, next, &info->devices, links) {
+		list_del(&dev->links);
+		kfree(dev);
+	}
+}
+
+static int mikrobus_device_register(struct mikrobus_port *port,
+				    struct board_device_info *dev, char *board_name)
+{
+	struct i2c_board_info *i2c;
+	struct spi_board_info *spi;
+	struct platform_device *pdev;
+	struct gpiod_lookup_table *lookup;
+	char devname[MIKROBUS_NAME_SIZE];
+	int i;
+
+	dev_info(&port->dev, "registering device : %s", dev->drv_name);
+
+	if (dev->gpio_lookup) {
+		lookup = dev->gpio_lookup;
+		if (dev->protocol == GREYBUS_PROTOCOL_SPI) {
+			snprintf(devname, sizeof(devname), "%s.%u",
+				 dev_name(&port->spi_mstr->dev),
+				port->chip_select[dev->reg]);
+			lookup->dev_id = kmemdup(devname, MIKROBUS_NAME_SIZE, GFP_KERNEL);
+		} else if (dev->protocol == GREYBUS_PROTOCOL_RAW) {
+			snprintf(devname, sizeof(devname), "%s.%u",
+				 dev->drv_name, dev->reg);
+			lookup->dev_id = kmemdup(devname, MIKROBUS_NAME_SIZE, GFP_KERNEL);
+		} else {
+			lookup->dev_id = dev->drv_name;
+		}
+		dev_info(&port->dev, " adding lookup table : %s\n",
+			 lookup->dev_id);
+		for (i = 0; i < dev->num_gpio_resources; i++) {
+			lookup->table[i].key =
+			mikrobus_gpio_chip_name_get(port,
+						    lookup->table[i].chip_hwnum);
+			lookup->table[i].chip_hwnum =
+			mikrobus_gpio_hwnum_get(port,
+						lookup->table[i].chip_hwnum);
+			lookup->table[i].flags = GPIO_ACTIVE_HIGH;
+		}
+		gpiod_add_lookup_table(lookup);
+	}
+	switch (dev->protocol) {
+	case GREYBUS_PROTOCOL_SPI:
+		spi = kzalloc(sizeof(*spi), GFP_KERNEL);
+		if (!spi)
+			return -ENOMEM;
+		strncpy(spi->modalias, dev->drv_name, sizeof(spi->modalias) - 1);
+		if (dev->irq)
+			spi->irq = mikrobus_irq_get(port, dev->irq, dev->irq_type);
+		if (dev->properties)
+			spi->properties = dev->properties;
+		spi->chip_select = port->chip_select[dev->reg];
+		spi->max_speed_hz = dev->max_speed_hz;
+		spi->mode = dev->mode;
+		dev->dev_client = (void *)spi_new_device(port->spi_mstr, spi);
+		break;
+	case GREYBUS_PROTOCOL_I2C:
+		i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
+		if (!i2c)
+			return -ENOMEM;
+		strncpy(i2c->type, dev->drv_name, sizeof(i2c->type) - 1);
+		if (dev->irq)
+			i2c->irq = mikrobus_irq_get(port, dev->irq, dev->irq_type);
+		if (dev->properties)
+			i2c->properties = dev->properties;
+		i2c->addr = dev->reg;
+		dev->dev_client = (void *)i2c_new_client_device(port->i2c_adap, i2c);
+		break;
+	case GREYBUS_PROTOCOL_RAW:
+		pdev = platform_device_alloc(dev->drv_name, 0);
+		if (!pdev)
+			return -ENOMEM;
+		if (dev->properties)
+			platform_device_add_properties(pdev, dev->properties);
+		dev->dev_client = pdev;
+		platform_device_add(dev->dev_client);
+		break;
+	case GREYBUS_PROTOCOL_UART:
+		dev_info(&port->dev, "serdev devices support not yet added");
+	break;
+	default:
+	return -EINVAL;
+	}
+	return 0;
+}
+
+static void mikrobus_device_unregister(struct mikrobus_port *port,
+				       struct board_device_info *dev, char *board_name)
+{
+	dev_info(&port->dev, "removing device %s\n", dev->drv_name);
+	if (dev->gpio_lookup) {
+		gpiod_remove_lookup_table(dev->gpio_lookup);
+		kfree(dev->gpio_lookup);
+	}
+	kfree(dev->properties);
+	switch (dev->protocol) {
+	case GREYBUS_PROTOCOL_SPI:
+		spi_unregister_device((struct spi_device *)dev->dev_client);
+		break;
+	case GREYBUS_PROTOCOL_I2C:
+		i2c_unregister_device((struct i2c_client *)dev->dev_client);
+		break;
+	case GREYBUS_PROTOCOL_RAW:
+		platform_device_unregister((struct platform_device  *)dev->dev_client);
+		break;
+	case GREYBUS_PROTOCOL_UART:
+		dev_err(&port->dev, "serdev devices support not yet added");
+		break;
+	}
+}
+
+int mikrobus_board_register(struct mikrobus_port *port,	struct addon_board_info *board)
+{
+	struct board_device_info *devinfo;
+	struct board_device_info *next;
+	int retval;
+	int i;
+
+	if (WARN_ON(list_empty(&board->devices)))
+		return -ENODEV;
+	if (port->pinctrl) {
+		retval = mikrobus_port_pinctrl_setup(port, board);
+		if (retval)
+			dev_err(&port->dev, "failed to setup pinctrl state [%d]", retval);
+	}
+	if (port->gpios) {
+		for (i = 0; i < port->gpios->ndescs; i++) {
+			retval = mikrobus_gpio_setup(port->gpios->desc[i], board->pin_state[i]);
+			if (retval)
+				dev_err(&port->dev, "failed to setup gpio %d, state %d",
+					i, board->pin_state[i]);
+		}
+	}
+	list_for_each_entry_safe(devinfo, next, &board->devices, links)
+		mikrobus_device_register(port, devinfo, board->name);
+	port->board = board;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mikrobus_board_register);
+
+void mikrobus_board_unregister(struct mikrobus_port *port, struct addon_board_info *board)
+{
+	struct board_device_info *devinfo;
+	struct board_device_info *next;
+
+	if (WARN_ON(list_empty(&board->devices)))
+		return;
+	port->board = NULL;
+	list_for_each_entry_safe(devinfo, next, &board->devices, links)
+		mikrobus_device_unregister(port, devinfo, board->name);
+	mikrobus_board_device_release_all(board);
+	kfree(board);
+	port->board = NULL;
+}
+EXPORT_SYMBOL_GPL(mikrobus_board_unregister);
+
+/*
+ * temporary setup for Atmel AT24C32 I2C EEPROM on 0x57
+ * will be removed once the mikrobusv3 standard in finalized.
+ */
+static struct i2c_board_info mikrobus_eeprom_info = {
+	I2C_BOARD_INFO("24c32", 0x57),
+};
+
+static int mikrobus_port_eeprom_probe(struct mikrobus_port *port)
+{
+	struct i2c_client *eeprom_client;
+	struct nvmem_device *eeprom;
+	char dev_name[MIKROBUS_NAME_SIZE];
+
+	eeprom_client = i2c_new_client_device(port->i2c_adap, &mikrobus_eeprom_info);
+	if (!IS_ERR(eeprom_client)) {
+		pr_info(" mikrobus port %d default eeprom is probed at %02x\n", port->id,
+			eeprom_client->addr);
+		snprintf(dev_name, sizeof(dev_name), "%d-%04x0", port->i2c_adap->nr,
+			 eeprom_client->addr);
+		eeprom = nvmem_device_get(&eeprom_client->dev, dev_name);
+		if (IS_ERR(eeprom)) {
+			pr_err("mikrobus port %d eeprom nvmem device probe failed\n", port->id);
+			i2c_unregister_device(eeprom_client);
+			port->eeprom = NULL;
+			return 0;
+		}
+	} else {
+		pr_info("mikrobus port %d default eeprom probe failed\n", port->id);
+		return 0;
+	}
+	port->eeprom = eeprom;
+	port->eeprom_client = eeprom_client;
+	return 0;
+}
+
+int mikrobus_port_register(struct mikrobus_port *port)
+{
+	struct device *dev = &port->dev;
+	int retval;
+	int id;
+
+	if (WARN_ON(!is_registered))
+		return -EAGAIN;
+
+	if (dev->of_node) {
+		id = of_alias_get_id(dev->of_node, "mikrobus");
+		if (id >= 0) {
+			port->id = id;
+			mutex_lock(&core_lock);
+			id = idr_alloc(&mikrobus_port_idr, port, port->id, port->id + 1,
+				       GFP_KERNEL);
+			mutex_unlock(&core_lock);
+			if (WARN(id < 0, "couldn't get idr"))
+				return id == -ENOSPC ? -EBUSY : id;
+		}
+	} else {
+		mutex_lock(&core_lock);
+		id = idr_alloc(&mikrobus_port_idr, port, __mikrobus_first_dynamic_bus_num, 0,
+			       GFP_KERNEL);
+		mutex_unlock(&core_lock);
+		if (id < 0)
+			return id;
+		port->id = id;
+	}
+	port->dev.bus = &mikrobus_bus_type;
+	port->dev.type = &mikrobus_port_type;
+	strncpy(port->name, "mikrobus-port", sizeof(port->name) - 1);
+	dev_set_name(&port->dev, "mikrobus-%d", port->id);
+	pr_info("registering port mikrobus-%d ", port->id);
+	retval = device_register(&port->dev);
+	if (retval) {
+		pr_err("port '%d': can't register device (%d)", port->id, retval);
+		put_device(&port->dev);
+		return retval;
+	}
+	retval = class_compat_create_link(mikrobus_port_compat_class, &port->dev,
+					  port->dev.parent);
+	if (retval)
+		dev_warn(&port->dev, "failed to create compatibility class link\n");
+	if (!port->eeprom) {
+		dev_info(&port->dev, "mikrobus port %d eeprom empty probing default eeprom\n",
+			 port->id);
+		retval = mikrobus_port_eeprom_probe(port);
+	}
+	if (port->eeprom) {
+		retval = mikrobus_port_scan_eeprom(port);
+		if (retval) {
+			dev_warn(&port->dev, "failed to register board from manifest\n");
+			return 0;
+		}
+	}
+	return retval;
+}
+EXPORT_SYMBOL_GPL(mikrobus_port_register);
+
+void mikrobus_port_delete(struct mikrobus_port *port)
+{
+	struct mikrobus_port *found;
+
+	mutex_lock(&core_lock);
+	found = idr_find(&mikrobus_port_idr, port->id);
+	mutex_unlock(&core_lock);
+	if (found != port) {
+		pr_err("port [%s] not registered", port->name);
+		return;
+	}
+	if (port->board) {
+		dev_err(&port->dev, "attempting to delete port with registered boards, port [%s]\n",
+			port->name);
+		return;
+	}
+
+	if (port->eeprom) {
+		nvmem_device_put(port->eeprom);
+		i2c_unregister_device(port->eeprom_client);
+	}
+
+	class_compat_remove_link(mikrobus_port_compat_class, &port->dev,
+				 port->dev.parent);
+	device_unregister(&port->dev);
+	mutex_lock(&core_lock);
+	idr_remove(&mikrobus_port_idr, port->id);
+	mutex_unlock(&core_lock);
+	memset(&port->dev, 0, sizeof(port->dev));
+}
+EXPORT_SYMBOL_GPL(mikrobus_port_delete);
+
+static int __init mikrobus_init(void)
+{
+	int retval;
+
+	retval = bus_register(&mikrobus_bus_type);
+	if (retval) {
+		pr_err("bus_register failed (%d)\n", retval);
+		return retval;
+	}
+	mikrobus_port_compat_class = class_compat_register("mikrobus-port");
+	if (!mikrobus_port_compat_class) {
+		pr_err("class_compat register failed (%d)\n", retval);
+		retval = -ENOMEM;
+		goto class_err;
+	}
+	retval = of_alias_get_highest_id("mikrobus");
+	if (retval >= __mikrobus_first_dynamic_bus_num)
+		__mikrobus_first_dynamic_bus_num = retval + 1;
+
+	is_registered = true;
+	return 0;
+
+class_err:
+	bus_unregister(&mikrobus_bus_type);
+	idr_destroy(&mikrobus_port_idr);
+	is_registered = false;
+	return retval;
+}
+subsys_initcall(mikrobus_init);
+
+static void __exit mikrobus_exit(void)
+{
+	bus_unregister(&mikrobus_bus_type);
+	class_compat_unregister(mikrobus_port_compat_class);
+	idr_destroy(&mikrobus_port_idr);
+}
+module_exit(mikrobus_exit);
+
+MODULE_AUTHOR("Vaishnav M A <vaishnav@beagleboard.org>");
+MODULE_DESCRIPTION("mikroBUS main module");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mikrobus/mikrobus_core.h b/drivers/misc/mikrobus/mikrobus_core.h
new file mode 100644
index 000000000000..b5da4225bc6c
--- /dev/null
+++ b/drivers/misc/mikrobus/mikrobus_core.h
@@ -0,0 +1,191 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mikroBUS Driver for instantiating add-on
+ * board devices with an identifier EEPROM
+ *
+ * Copyright 2020 Vaishnav M A, BeagleBoard.org Foundation.
+ */
+
+#ifndef __MIKROBUS_H
+#define __MIKROBUS_H
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
+#include <linux/spi/spi.h>
+#include <linux/serdev.h>
+#include <linux/property.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/nvmem-provider.h>
+
+#define MIKROBUS_VERSION_MAJOR 0x00
+#define MIKROBUS_VERSION_MINOR 0x03
+
+#define MIKROBUS_NAME_SIZE		40
+#define MIKROBUS_PINCTRL_NAME_SIZE	20
+
+#define MIKROBUS_NUM_PINCTRL_STATE	4
+#define MIKROBUS_NUM_CS			2
+
+#define MIKROBUS_PINCTRL_PWM		0
+#define MIKROBUS_PINCTRL_UART		1
+#define MIKROBUS_PINCTRL_I2C		2
+#define MIKROBUS_PINCTRL_SPI		3
+
+#define MIKROBUS_PINCTRL_STATE_GPIO	"gpio"
+
+extern struct bus_type mikrobus_bus_type;
+extern struct device_type mikrobus_port_type;
+extern const char *MIKROBUS_PINCTRL_STR[];
+
+enum mikrobus_property_type {
+	MIKROBUS_PROPERTY_TYPE_MIKROBUS = 0x00,
+	MIKROBUS_PROPERTY_TYPE_LINK	= 0x01,
+	MIKROBUS_PROPERTY_TYPE_GPIO	= 0x02,
+	MIKROBUS_PROPERTY_TYPE_U8	= 0x03,
+	MIKROBUS_PROPERTY_TYPE_U16	= 0x04,
+	MIKROBUS_PROPERTY_TYPE_U32	= 0x05,
+	MIKROBUS_PROPERTY_TYPE_U64	= 0x06,
+};
+
+enum mikrobus_pin {
+	MIKROBUS_PIN_PWM	= 0x00,
+	MIKROBUS_PIN_INT	= 0x01,
+	MIKROBUS_PIN_RX		= 0x02,
+	MIKROBUS_PIN_TX		= 0x03,
+	MIKROBUS_PIN_SCL	= 0x04,
+	MIKROBUS_PIN_SDA	= 0x05,
+	MIKROBUS_PIN_MOSI	= 0x06,
+	MIKROBUS_PIN_MISO	= 0x07,
+	MIKROBUS_PIN_SCK	= 0x08,
+	MIKROBUS_PIN_CS		= 0x09,
+	MIKROBUS_PIN_RST	= 0x0A,
+	MIKROBUS_PIN_AN		= 0x0B,
+	MIKROBUS_PORT_PIN_COUNT = 0x0C,
+};
+
+enum mikrobus_pin_state {
+	MIKROBUS_STATE_INPUT		= 0x01,
+	MIKROBUS_STATE_OUTPUT_HIGH	= 0x02,
+	MIKROBUS_STATE_OUTPUT_LOW	= 0x03,
+	MIKROBUS_STATE_PWM		= 0x04,
+	MIKROBUS_STATE_SPI		= 0x05,
+	MIKROBUS_STATE_I2C		= 0x06,
+	MIKROBUS_STATE_UART		= 0x07,
+};
+
+/*
+ * board_device_info describes a single device on a mikrobus add-on
+ * board, an add-on board can present one or more device to the host
+ *
+ * @gpio_lookup: used to provide the GPIO lookup table for
+ * passing the named GPIOs to device drivers.
+ * @properties: used to provide the property_entry to pass named
+ * properties to device drivers, applicable only when driver uses
+ * device_property_read_* calls to fetch the properties.
+ * @num_gpio_resources: number of named gpio resources for the device,
+ * used mainly for gpiod_lookup_table memory allocation.
+ * @num_properties: number of custom properties for the device,
+ * used mainly for property_entry memory allocation.
+ * @protocol: used to know the type of the device and it should
+ * contain one of the values defined under 'enum greybus_class_type'
+ * under linux/greybus/greybus_manifest.h
+ * @reg: I2C address for the device, for devices on the SPI bus
+ * this field is the chip select address relative to the mikrobus
+ * port:0->device chip select connected to CS pin on mikroBUS port
+ *	1->device chip select connected to RST Pin on mikroBUS port
+ * @mode: SPI mode
+ * @max_speed_hz: SPI max speed(Hz)
+ * @drv_name: device_id to match with the driver
+ * @irq_type: type of IRQ trigger , match with defines in linux/interrupt.h
+ * @irq: irq number relative to the mikrobus port should contain one of the
+ * values defined under 'enum mikrobus_pin'
+ * @id: device id starting from 1
+ */
+struct board_device_info {
+	struct gpiod_lookup_table *gpio_lookup;
+	struct property_entry *properties;
+	struct list_head links;
+	unsigned short num_gpio_resources;
+	unsigned short num_properties;
+	unsigned short protocol;
+	unsigned short reg;
+	unsigned int mode;
+	void *dev_client;
+	u32 max_speed_hz;
+	char *drv_name;
+	int irq_type;
+	int irq;
+	int id;
+};
+
+/*
+ * addon_board_info describes a mikrobus add-on device the add-on
+ * board, an add-on board can present one or more device to the host
+ *
+ * @manifest_descs: list of manifest descriptors
+ * @devices: list of devices on the board
+ * @pin_state: the state of each pin on the mikrobus port required
+ * for the add-on board should contain one of the values defined under
+ * 'enum mikrobus_pin_state' restrictions are as per mikrobus standard
+ * specifications.
+ * @name: add-on board name
+ */
+struct addon_board_info {
+	struct list_head manifest_descs;
+	struct list_head devices;
+	u8 pin_state[MIKROBUS_PORT_PIN_COUNT];
+	char *name;
+};
+
+/*
+ * mikrobus_port describes the peripherals mapped to a
+ * mikrobus port.
+ *
+ * @eeprom_client: i2c_client corresponding to the eeprom
+ * on the add-on board.
+ * @board: pointer to the attached add-on board.
+ * @i2c_adap: I2C adapter attached to the mikrobus port.
+ * @spi_mstr: SPI master attached to the mikrobus port.
+ * @eeprom: nvmem_device for the eeprom on the add-on board.
+ * @pwm: pwm_device attached to the mikrobus port PWM pin.
+ * @pinctrl_selected: current pinctrl_selected state.
+ * @chip_select: chip select number mapped to the SPI
+ * CS pin on the mikrobus port and the RST pin on the mikrobus
+ * port
+ * @id: port id starting from 1
+ */
+struct mikrobus_port {
+	struct i2c_client *eeprom_client;
+	struct addon_board_info *board;
+	struct i2c_adapter *i2c_adap;
+	struct spi_master *spi_mstr;
+	struct nvmem_device *eeprom;
+	struct gpio_descs *gpios;
+	struct pwm_device *pwm;
+	struct pinctrl *pinctrl;
+	struct module *owner;
+	struct device dev;
+	char name[MIKROBUS_NAME_SIZE];
+	char *pinctrl_selected[MIKROBUS_NUM_PINCTRL_STATE];
+	unsigned int chip_select[MIKROBUS_NUM_CS];
+	int id;
+};
+
+#define to_mikrobus_port(d) container_of(d, struct mikrobus_port, dev)
+
+void mikrobus_board_unregister(struct mikrobus_port *port,
+			       struct addon_board_info *board);
+int mikrobus_board_register(struct mikrobus_port *port,
+			    struct addon_board_info *board);
+int mikrobus_port_register(struct mikrobus_port *port);
+int mikrobus_port_pinctrl_select(struct mikrobus_port *port);
+void mikrobus_port_delete(struct mikrobus_port *port);
+
+#endif /* __MIKROBUS_H */
diff --git a/drivers/misc/mikrobus/mikrobus_manifest.c b/drivers/misc/mikrobus/mikrobus_manifest.c
new file mode 100644
index 000000000000..952a68c6d8d1
--- /dev/null
+++ b/drivers/misc/mikrobus/mikrobus_manifest.c
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mikroBUS manifest parsing, an
+ * extension to Greybus Manifest Parsing
+ * under drivers/greybus/manifest.c
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ */
+
+#define pr_fmt(fmt) "mikrobus_manifest:%s: " fmt, __func__
+
+#include <linux/bits.h>
+#include <linux/types.h>
+#include <linux/property.h>
+#include <linux/greybus/greybus_manifest.h>
+
+#include "mikrobus_manifest.h"
+
+struct manifest_desc {
+	struct list_head links;
+	size_t size;
+	void *data;
+	enum greybus_descriptor_type type;
+};
+
+static void manifest_descriptor_release_all(struct addon_board_info *board)
+{
+	struct manifest_desc *descriptor;
+	struct manifest_desc *next;
+
+	list_for_each_entry_safe(descriptor, next, &board->manifest_descs,
+				 links) {
+		list_del(&descriptor->links);
+		kfree(descriptor);
+	}
+}
+
+static int board_descriptor_add(struct addon_board_info *board,
+				struct greybus_descriptor *desc, size_t size)
+{
+	struct greybus_descriptor_header *desc_header = &desc->header;
+	struct manifest_desc *descriptor;
+	size_t desc_size;
+	size_t expected_size;
+
+	if (size < sizeof(*desc_header)) {
+		pr_err("short descriptor (%zu < %zu)", size,
+		       sizeof(*desc_header));
+		return -EINVAL;
+	}
+	desc_size = le16_to_cpu(desc_header->size);
+	if (desc_size > size) {
+		pr_err("incorrect descriptor size (%zu != %zu)", size,
+		       desc_size);
+		return -EINVAL;
+	}
+	expected_size = sizeof(*desc_header);
+	switch (desc_header->type) {
+	case GREYBUS_TYPE_STRING:
+		expected_size += sizeof(struct greybus_descriptor_string);
+		expected_size += desc->string.length;
+		expected_size = ALIGN(expected_size, 4);
+		break;
+	case GREYBUS_TYPE_PROPERTY:
+		expected_size += sizeof(struct greybus_descriptor_property);
+		expected_size += desc->property.length;
+		expected_size = ALIGN(expected_size, 4);
+		break;
+	case GREYBUS_TYPE_DEVICE:
+		expected_size += sizeof(struct greybus_descriptor_device);
+		break;
+	case GREYBUS_TYPE_MIKROBUS:
+		expected_size += sizeof(struct greybus_descriptor_mikrobus);
+		break;
+	case GREYBUS_TYPE_INTERFACE:
+		expected_size += sizeof(struct greybus_descriptor_interface);
+		break;
+	case GREYBUS_TYPE_CPORT:
+		expected_size += sizeof(struct greybus_descriptor_cport);
+		break;
+	case GREYBUS_TYPE_BUNDLE:
+		expected_size += sizeof(struct greybus_descriptor_bundle);
+		break;
+	case GREYBUS_TYPE_INVALID:
+	default:
+		pr_err("invalid descriptor type %d", desc_header->type);
+		return -EINVAL;
+	}
+
+	descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL);
+	if (!descriptor)
+		return -ENOMEM;
+	descriptor->size = desc_size;
+	descriptor->data = (char *)desc + sizeof(*desc_header);
+	descriptor->type = desc_header->type;
+	list_add_tail(&descriptor->links, &board->manifest_descs);
+	return desc_size;
+}
+
+static char *mikrobus_string_get(struct addon_board_info *board, u8 string_id)
+{
+	struct greybus_descriptor_string *desc_string;
+	struct manifest_desc *descriptor;
+	bool found = false;
+	char *string;
+
+	if (!string_id)
+		return NULL;
+
+	list_for_each_entry(descriptor, &board->manifest_descs, links) {
+		if (descriptor->type != GREYBUS_TYPE_STRING)
+			continue;
+		desc_string = descriptor->data;
+		if (desc_string->id == string_id) {
+			found = true;
+			break;
+		}
+	}
+	if (!found)
+		return ERR_PTR(-ENOENT);
+	string = kmemdup(&desc_string->string, desc_string->length + 1,
+			 GFP_KERNEL);
+	if (!string)
+		return ERR_PTR(-ENOMEM);
+	string[desc_string->length] = '\0';
+	return string;
+}
+
+static void mikrobus_state_get(struct addon_board_info *board)
+{
+	struct greybus_descriptor_mikrobus *mikrobus;
+	struct greybus_descriptor_interface *interface;
+	struct manifest_desc *descriptor;
+	bool found = false;
+	int i;
+
+	list_for_each_entry(descriptor, &board->manifest_descs, links) {
+		if (descriptor->type == GREYBUS_TYPE_MIKROBUS) {
+			mikrobus = descriptor->data;
+			found = true;
+			break;
+		}
+	}
+	if (!found) {
+		pr_err("mikrobus descriptor not found");
+		return;
+	}
+	for (i = 0; i < MIKROBUS_PORT_PIN_COUNT; i++)
+		board->pin_state[i] =  mikrobus->pin_state[i];
+
+	found = false;
+	list_for_each_entry(descriptor, &board->manifest_descs, links) {
+		if (descriptor->type == GREYBUS_TYPE_INTERFACE) {
+			interface = descriptor->data;
+			found = true;
+			break;
+		}
+	}
+	if (!found) {
+		pr_err("interface descriptor not found");
+		return;
+	}
+	board->name = mikrobus_string_get(board, interface->product_stringid);
+}
+
+static struct property_entry *
+mikrobus_property_entry_get(struct addon_board_info *board, u8 *prop_link,
+			    int num_properties)
+{
+	struct greybus_descriptor_property *desc_property;
+	struct manifest_desc *descriptor;
+	struct property_entry *properties;
+	bool found = false;
+	char *prop_name;
+	u64 *val_u64;
+	u32 *val_u32;
+	u16 *val_u16;
+	u8 *val_u8;
+	int i;
+
+	properties = kcalloc(num_properties, sizeof(*properties), GFP_KERNEL);
+	if (!properties)
+		return ERR_PTR(-ENOMEM);
+	for (i = 0; i < num_properties; i++) {
+		list_for_each_entry(descriptor, &board->manifest_descs, links) {
+			if (descriptor->type != GREYBUS_TYPE_PROPERTY)
+				continue;
+			desc_property = descriptor->data;
+			if (desc_property->id == prop_link[i]) {
+				found = true;
+				break;
+			}
+		}
+		if (!found) {
+			kfree(properties);
+			return ERR_PTR(-ENOENT);
+		}
+		prop_name = mikrobus_string_get(board,
+						desc_property->propname_stringid);
+		if (!prop_name) {
+			kfree(properties);
+			return ERR_PTR(-ENOENT);
+		}
+		switch (desc_property->type) {
+		case MIKROBUS_PROPERTY_TYPE_U8:
+			val_u8 = kmemdup(&desc_property->value,
+					 (desc_property->length) * sizeof(u8), GFP_KERNEL);
+			if (desc_property->length == 1)
+				properties[i] = PROPERTY_ENTRY_U8(prop_name, *val_u8);
+			else
+				properties[i] = PROPERTY_ENTRY_U8_ARRAY_LEN(prop_name,
+					(void *)desc_property->value, desc_property->length);
+			break;
+		case MIKROBUS_PROPERTY_TYPE_U16:
+			val_u16 = kmemdup(&desc_property->value,
+					  (desc_property->length) * sizeof(u16), GFP_KERNEL);
+			if (desc_property->length == 1)
+				properties[i] = PROPERTY_ENTRY_U16(prop_name, *val_u16);
+			else
+				properties[i] = PROPERTY_ENTRY_U16_ARRAY_LEN(prop_name,
+					(void *)desc_property->value, desc_property->length);
+			break;
+		case MIKROBUS_PROPERTY_TYPE_U32:
+			val_u32 = kmemdup(&desc_property->value,
+					  (desc_property->length) * sizeof(u32), GFP_KERNEL);
+			if (desc_property->length == 1)
+				properties[i] = PROPERTY_ENTRY_U32(prop_name, *val_u32);
+			else
+				properties[i] = PROPERTY_ENTRY_U32_ARRAY_LEN(prop_name,
+					(void *)desc_property->value, desc_property->length);
+			break;
+		case MIKROBUS_PROPERTY_TYPE_U64:
+			val_u64 = kmemdup(&desc_property->value,
+					  (desc_property->length) * sizeof(u64), GFP_KERNEL);
+			if (desc_property->length == 1)
+				properties[i] = PROPERTY_ENTRY_U64(prop_name, *val_u64);
+			else
+				properties[i] = PROPERTY_ENTRY_U64_ARRAY_LEN(prop_name,
+					(void *)desc_property->value, desc_property->length);
+			break;
+		default:
+			kfree(properties);
+			return ERR_PTR(-EINVAL);
+		}
+	}
+	return properties;
+}
+
+static u8 *mikrobus_property_link_get(struct addon_board_info *board, u8 prop_id,
+				      struct board_device_info *board_dev,  u8 prop_type)
+{
+	struct greybus_descriptor_property *desc_property;
+	struct manifest_desc *descriptor;
+	bool found = false;
+	u8 *val_u8;
+
+	if (!prop_id)
+		return NULL;
+	list_for_each_entry(descriptor, &board->manifest_descs, links) {
+		if (descriptor->type != GREYBUS_TYPE_PROPERTY)
+			continue;
+		desc_property = descriptor->data;
+		if (desc_property->id == prop_id && desc_property->type == prop_type) {
+			found = true;
+			break;
+		}
+	}
+	if (!found)
+		return ERR_PTR(-ENOENT);
+	val_u8 = kmemdup(&desc_property->value, desc_property->length, GFP_KERNEL);
+	if (prop_type == MIKROBUS_PROPERTY_TYPE_GPIO)
+		board_dev->num_gpio_resources = desc_property->length;
+	else if (prop_type == MIKROBUS_PROPERTY_TYPE_LINK)
+		board_dev->num_properties = desc_property->length;
+	return val_u8;
+}
+
+static int mikrobus_manifest_attach_device(struct addon_board_info *board,
+					   struct greybus_descriptor_device *dev_desc)
+{
+	struct board_device_info *board_dev;
+	struct gpiod_lookup_table *lookup;
+	struct greybus_descriptor_property *desc_property;
+	struct manifest_desc *descriptor;
+	u8 *gpio_desc_link;
+	u8 *prop_link;
+	int retval;
+	int i;
+
+	board_dev = kzalloc(sizeof(*board_dev), GFP_KERNEL);
+	if (!board_dev)
+		return -ENOMEM;
+	board_dev->id = dev_desc->id;
+	board_dev->drv_name = mikrobus_string_get(board, dev_desc->driver_stringid);
+	if (!board_dev->drv_name) {
+		retval = -ENOENT;
+		goto err_free_board_dev;
+	}
+	board_dev->protocol = dev_desc->protocol;
+	board_dev->reg = dev_desc->reg;
+	board_dev->irq = dev_desc->irq;
+	board_dev->irq_type = dev_desc->irq_type;
+	board_dev->max_speed_hz = le32_to_cpu(dev_desc->max_speed_hz);
+	board_dev->mode = dev_desc->mode;
+	pr_info("parsed device %d, driver=%s", board_dev->id, board_dev->drv_name);
+
+	if (dev_desc->prop_link > 0) {
+		prop_link = mikrobus_property_link_get(board, dev_desc->prop_link,
+						       board_dev, MIKROBUS_PROPERTY_TYPE_LINK);
+		if (!prop_link) {
+			retval = -ENOENT;
+			goto err_free_board_dev;
+		}
+		pr_info("device %d, number of properties=%d", board_dev->id,
+			board_dev->num_properties);
+		board_dev->properties = mikrobus_property_entry_get(board, prop_link,
+								    board_dev->num_properties);
+	}
+
+	if (dev_desc->gpio_link > 0) {
+		gpio_desc_link = mikrobus_property_link_get(board, dev_desc->gpio_link, board_dev,
+							    MIKROBUS_PROPERTY_TYPE_GPIO);
+		if (!gpio_desc_link) {
+			retval = -ENOENT;
+			goto err_free_board_dev;
+		}
+		pr_info("device %d, number of gpio resource=%d", board_dev->id,
+			board_dev->num_gpio_resources);
+		lookup = kzalloc(struct_size(lookup, table, board_dev->num_gpio_resources),
+				 GFP_KERNEL);
+		if (!lookup) {
+			retval = -ENOMEM;
+			goto err_free_board_dev;
+		}
+		for (i = 0; i < board_dev->num_gpio_resources; i++) {
+			list_for_each_entry(descriptor, &board->manifest_descs, links) {
+				if (descriptor->type != GREYBUS_TYPE_PROPERTY)
+					continue;
+				desc_property = descriptor->data;
+				if (desc_property->id == gpio_desc_link[i]) {
+					lookup->table[i].chip_hwnum = *desc_property->value;
+					lookup->table[i].con_id =
+					mikrobus_string_get(board,
+							    desc_property->propname_stringid);
+					break;
+				}
+			}
+		}
+		board_dev->gpio_lookup = lookup;
+	}
+	list_add_tail(&board_dev->links, &board->devices);
+	return 0;
+err_free_board_dev:
+	kfree(board_dev);
+	return retval;
+}
+
+static int mikrobus_manifest_parse_devices(struct addon_board_info *board)
+{
+	struct greybus_descriptor_device *desc_device;
+	struct manifest_desc *desc, *next;
+	int retval;
+	int devcount = 0;
+
+	list_for_each_entry_safe(desc, next, &board->manifest_descs, links) {
+		if (desc->type != GREYBUS_TYPE_DEVICE)
+			continue;
+		desc_device = desc->data;
+		retval = mikrobus_manifest_attach_device(board, desc_device);
+		devcount++;
+	}
+	return devcount;
+}
+
+int mikrobus_manifest_parse(struct addon_board_info *board, void *data,
+			    size_t size)
+{
+	struct greybus_manifest_header *header;
+	struct greybus_manifest *manifest;
+	struct greybus_descriptor *desc;
+	u16 manifest_size;
+	int dev_count;
+	int desc_size;
+
+	if (size < sizeof(*header)) {
+		pr_err("short manifest (%zu < %zu)", size, sizeof(*header));
+		return -EINVAL;
+	}
+
+	manifest = data;
+	header = &manifest->header;
+	manifest_size = le16_to_cpu(header->size);
+
+	if (manifest_size != size) {
+		pr_err("invalid manifest size(%zu < %zu)", size, manifest_size);
+		return -EINVAL;
+	}
+
+	if (header->version_major > MIKROBUS_VERSION_MAJOR) {
+		pr_err("manifest version too new (%u.%u > %u.%u)",
+		       header->version_major, header->version_minor,
+		       MIKROBUS_VERSION_MAJOR, MIKROBUS_VERSION_MINOR);
+		return -EINVAL;
+	}
+
+	desc = manifest->descriptors;
+	size -= sizeof(*header);
+	while (size) {
+		desc_size = board_descriptor_add(board, desc, size);
+		if (desc_size < 0) {
+			pr_err("invalid manifest descriptor, size: %zu", desc_size);
+			return -EINVAL;
+		}
+		desc = (void *)desc + desc_size;
+		size -= desc_size;
+	}
+	mikrobus_state_get(board);
+	dev_count = mikrobus_manifest_parse_devices(board);
+	pr_info(" %s manifest parsed with %d devices", board->name, dev_count);
+	manifest_descriptor_release_all(board);
+	return 0;
+}
+
+size_t mikrobus_manifest_header_validate(void *data, size_t size)
+{
+	struct greybus_manifest_header *header;
+	u16 manifest_size;
+
+	if (size < sizeof(*header)) {
+		pr_err("short manifest (%zu < %zu)", size, sizeof(*header));
+		return -EINVAL;
+	}
+	header = data;
+	manifest_size = le16_to_cpu(header->size);
+	if (header->version_major > MIKROBUS_VERSION_MAJOR) {
+		pr_err("manifest version too new (%u.%u > %u.%u)",
+		       header->version_major, header->version_minor,
+		       MIKROBUS_VERSION_MAJOR, MIKROBUS_VERSION_MINOR);
+		return -EINVAL;
+	}
+	return manifest_size;
+}
+
diff --git a/drivers/misc/mikrobus/mikrobus_manifest.h b/drivers/misc/mikrobus/mikrobus_manifest.h
new file mode 100644
index 000000000000..20cbc6465927
--- /dev/null
+++ b/drivers/misc/mikrobus/mikrobus_manifest.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mikroBUS manifest definition
+ * extension to Greybus Manifest Definition
+ *
+ * Copyright 2014-2015 Google Inc.
+ * Copyright 2014-2015 Linaro Ltd.
+ *
+ * Released under the GPLv2 and BSD licenses.
+ */
+
+#ifndef __MIKROBUS_MANIFEST_H
+#define __MIKROBUS_MANIFEST_H
+
+#include "mikrobus_core.h"
+
+int mikrobus_manifest_parse(struct addon_board_info *info, void *data,
+			    size_t size);
+size_t mikrobus_manifest_header_validate(void *data, size_t size);
+
+#endif /* __MIKROBUS_MANIFEST_H */
diff --git a/drivers/misc/mikrobus/mikrobus_port.c b/drivers/misc/mikrobus/mikrobus_port.c
new file mode 100644
index 000000000000..a5a1cbc04f30
--- /dev/null
+++ b/drivers/misc/mikrobus/mikrobus_port.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mikroBUS driver for adding mikrobus port from device tree
+ *
+ * Copyright 2020 Vaishnav M A, BeagleBoard.org Foundation.
+ */
+#define pr_fmt(fmt) "mikrobus_port:%s: " fmt, __func__
+
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/pwm.h>
+#include <linux/spi/spi.h>
+#include <linux/serdev.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
+
+#include "mikrobus_core.h"
+
+static int mikrobus_port_probe_pinctrl_setup(struct mikrobus_port *port)
+{
+	struct pinctrl_state *state;
+	struct device *dev = port->dev.parent;
+	int retval, i;
+
+	state = pinctrl_lookup_state(port->pinctrl, PINCTRL_STATE_DEFAULT);
+	if (!IS_ERR(state)) {
+		retval = pinctrl_select_state(port->pinctrl, state);
+		if (retval != 0) {
+			dev_err(dev, "Failed to select state %s\n",
+				PINCTRL_STATE_DEFAULT);
+			return retval;
+		}
+	} else {
+		dev_err(dev, "failed to find state %s\n",
+			PINCTRL_STATE_DEFAULT);
+		return PTR_ERR(state);
+	}
+
+	for (i = 0; i < MIKROBUS_NUM_PINCTRL_STATE; i++) {
+		port->pinctrl_selected[i] =
+				kmalloc(MIKROBUS_PINCTRL_NAME_SIZE, GFP_KERNEL);
+		sprintf(port->pinctrl_selected[i], "%s_%s",
+			MIKROBUS_PINCTRL_STR[i], PINCTRL_STATE_DEFAULT);
+	}
+
+	retval = mikrobus_port_pinctrl_select(port);
+	if (retval)
+		dev_err(dev, "failed to select pinctrl states [%d]", retval);
+	return retval;
+}
+
+static int mikrobus_port_probe(struct platform_device *pdev)
+{
+	struct mikrobus_port *port;
+	struct device *dev = &pdev->dev;
+	struct device_node *i2c_adap_np;
+	int retval;
+	u32 val;
+
+	port = kzalloc(sizeof(*port), GFP_KERNEL);
+	if (!port)
+		return -ENOMEM;
+
+	i2c_adap_np = of_parse_phandle(dev->of_node, "i2c-adapter", 0);
+	if (!i2c_adap_np) {
+		dev_err(dev, "cannot parse i2c-adapter\n");
+		retval = -ENODEV;
+		goto err_port;
+	}
+	port->i2c_adap = of_find_i2c_adapter_by_node(i2c_adap_np);
+	of_node_put(i2c_adap_np);
+	retval = device_property_read_u32(dev, "spi-master", &val);
+	if (retval) {
+		dev_err(dev, "failed to get spi-master [%d]\n", retval);
+		goto err_port;
+	}
+	port->spi_mstr = spi_busnum_to_master(val);
+	retval = device_property_read_u32_array(dev, "spi-cs",
+						port->chip_select, 2);
+	if (retval) {
+		dev_err(dev, "failed to get spi-cs [%d]\n", retval);
+		goto err_port;
+	}
+	port->gpios = gpiod_get_array(dev, "mikrobus", GPIOD_OUT_LOW);
+	if (IS_ERR(port->gpios)) {
+		retval = PTR_ERR(port->gpios);
+		dev_err(dev, "failed to get gpio array [%d]\n", retval);
+		goto err_port;
+	}
+	port->pinctrl = devm_pinctrl_get(dev);
+	if (IS_ERR(port->pinctrl)) {
+		retval = PTR_ERR(port->pinctrl);
+		dev_err(dev, "failed to get pinctrl [%d]\n", retval);
+		goto err_port;
+	}
+	port->dev.parent = dev;
+	port->dev.of_node = pdev->dev.of_node;
+
+	retval = mikrobus_port_probe_pinctrl_setup(port);
+	if (retval) {
+		dev_err(dev, "failed to setup pinctrl [%d]\n", retval);
+		goto err_port;
+	}
+
+	retval = mikrobus_port_register(port);
+	if (retval) {
+		pr_err("port : can't register port [%d]\n", retval);
+		goto err_port;
+	}
+	platform_set_drvdata(pdev, port);
+	return 0;
+err_port:
+	kfree(port);
+	return retval;
+}
+
+static int mikrobus_port_remove(struct platform_device *pdev)
+{
+	struct mikrobus_port	*port = platform_get_drvdata(pdev);
+
+	mikrobus_port_delete(port);
+	return 0;
+}
+
+static const struct of_device_id mikrobus_port_of_match[] = {
+	{.compatible = "linux,mikrobus"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mikrobus_port_of_match);
+
+static struct platform_driver mikrobus_port_driver = {
+	.probe = mikrobus_port_probe,
+	.remove = mikrobus_port_remove,
+	.driver = {
+		.name = "mikrobus",
+		.of_match_table = of_match_ptr(mikrobus_port_of_match),
+	},
+};
+
+static int __init
+mikrobus_port_init_driver(void)
+{
+	int retval;
+
+	retval = platform_driver_register(&mikrobus_port_driver);
+	if (retval)
+		pr_err("driver register failed [%d]\n", retval);
+	return retval;
+}
+subsys_initcall(mikrobus_port_init_driver);
+
+static void __exit mikrobus_port_exit_driver(void)
+{
+	platform_driver_unregister(&mikrobus_port_driver);
+}
+module_exit(mikrobus_port_exit_driver);
+
+MODULE_AUTHOR("Vaishnav M A <vaishnav@beagleboard.org>");
+MODULE_DESCRIPTION("mikroBUS port module");
+MODULE_LICENSE("GPL");
-- 
2.25.1


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

* [RFC PATCH v2 3/3] Add Device Tree Bindings for mikroBUS port
  2020-08-18 12:48 [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Vaishnav M A
  2020-08-18 12:48 ` [RFC PATCH v2 1/3] add mikrobus descriptors to greybus_manifest Vaishnav M A
  2020-08-18 12:48 ` [RFC PATCH v2 2/3] mikroBUS driver for add-on boards on mikrobus ports Vaishnav M A
@ 2020-08-18 12:48 ` Vaishnav M A
  2020-08-18 13:35   ` [greybus-dev] " Laurent Pinchart
  2020-08-27 15:45   ` Rob Herring
  2020-08-18 15:24 ` [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Greg KH
  2020-08-18 20:38 ` Frank Rowand
  4 siblings, 2 replies; 16+ messages in thread
From: Vaishnav M A @ 2020-08-18 12:48 UTC (permalink / raw)
  To: greybus-dev, linux-kernel, gregkh, arnd, johan, elder
  Cc: Vaishnav M A, robh, mchehab+huawei, davem, jkridner, drew,
	robertcnelson, rajkovic, chrisfriedt, zoran.stojsavljevic

This patch adds device tree bindings for the mikroBUS port,
device tree overlays for the mikrobus Port on the BeagleBoard.org
PocketBeagle is available here :
github.com/beagleboard/bb.org-overlays/blob/master/src/arm/PB-MIKROBUS-0.dts

Signed-off-by: Vaishnav M A <vaishnav@beagleboard.org>
---
 .../bindings/misc/linux,mikrobus.txt          | 81 +++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/linux,mikrobus.txt

diff --git a/Documentation/devicetree/bindings/misc/linux,mikrobus.txt b/Documentation/devicetree/bindings/misc/linux,mikrobus.txt
new file mode 100644
index 000000000000..99f75caf5f35
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/linux,mikrobus.txt
@@ -0,0 +1,81 @@
+mikroBUS add-on board socket
+
+Required properties:
+- compatible: Must be "linux,mikrobus"
+- i2c-adapter:  phandle to the i2c adapter attached to the mikrobus socket.
+- spi-master: spi bus number of the spi-master attached to the mikrobus socket.
+- spi-cs: spi chip-select numbers corresponding to the chip-selects
+	  on the mikrobus socket(0 -> chip select corresponding to CS pin
+	  1 -> chip select corresponding to RST pin).
+- serdev-controller:  phandle to the uart port attached to the mikrobus socket.
+- pwms: phandle to the pwm-controller corresponding to the mikroBUS PWM pin.
+- mikrobus-gpios: gpios array corresponding to GPIOs on the mikroBUS port,
+		  for targets not supporting the AN pin on the mikroBUS port as
+		  GPIO, the length of the gpios array can be 11, otherwise it
+		  should be 12.
+- pinctrl-names: pinctrl state names to support additional pin usage/deviations
+		 from mikroBUS socket standard usage, must be "default",
+		 "pwm_default", "pwm_gpio", "uart_default", "uart_gpio",
+		 "i2c_default", "i2c_gpio", "spi_default", "spi_gpio", these
+		 pinctrl names should have corresponding pinctrl-N entries which
+		 corresponds to the pinmux state for the pingroup, for example,
+		 i2c_default corresponds to the state where the I2C pin group
+		 (SCL,SDA) are configured in I2C mode and i2c_gpio mode corresponds
+		 to the pinmux state where these pins are configured as GPIO.
+- pinctrl-N : pinctrl-(0-8) corresponds to the pinctrl states for the states described
+	      above.
+
+Example:
+	mikrobus-0 {
+		compatible = "linux,mikrobus";
+		status = "okay";
+		pinctrl-names = "default", "pwm_default", "pwm_gpio",
+				"uart_default", "uart_gpio", "i2c_default",
+				"i2c_gpio", "spi_default", "spi_gpio";
+		pinctrl-0 = <
+			&P2_03_gpio_input_pin
+			&P1_04_gpio_pin
+			&P1_02_gpio_pin
+		>;
+		pinctrl-1 = <&P2_01_pwm_pin>;
+		pinctrl-2 = <&P2_01_gpio_pin>;
+		pinctrl-3 = <
+			&P2_05_uart_pin
+			&P2_07_uart_pin
+		>;
+		pinctrl-4 = <
+			&P2_05_gpio_pin
+			&P2_07_gpio_pin
+		>;
+		pinctrl-5 = <
+			&P2_09_i2c_pin
+			&P2_11_i2c_pin
+		>;
+		pinctrl-6 = <
+			&P2_09_gpio_pin
+			&P2_11_gpio_pin
+		>;
+		pinctrl-7 = <
+			&P1_12_spi_pin
+			&P1_10_spi_pin
+			&P1_08_spi_sclk_pin
+			&P1_06_spi_cs_pin
+		>;
+		pinctrl-8 = <
+			&P1_12_gpio_pin
+			&P1_10_gpio_pin
+			&P1_08_gpio_pin
+			&P1_06_gpio_pin
+		>;
+		i2c-adapter = <&i2c1>;
+		spi-master = <0>;
+		spi-cs = <0 1>;
+		serdev-controller = <&uart4>;
+		pwms = <&ehrpwm1 0 500000 0>;
+		mikrobus-gpios = <&gpio1 18 0> , <&gpio0 23 0>,
+					<&gpio0 30 0> , <&gpio0 31 0>,
+					<&gpio0 15 0> , <&gpio0 14 0>,
+					<&gpio0 4 0> , <&gpio0 3 0>,
+					<&gpio0 2 0> , <&gpio0 5 0>,
+					<&gpio2 25 0>  , <&gpio2 3 0>;
+	};
\ No newline at end of file
-- 
2.25.1


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

* Re: [greybus-dev] [RFC PATCH v2 3/3] Add Device Tree Bindings for mikroBUS port
  2020-08-18 12:48 ` [RFC PATCH v2 3/3] Add Device Tree Bindings for mikroBUS port Vaishnav M A
@ 2020-08-18 13:35   ` Laurent Pinchart
  2020-08-18 21:22     ` Vaishnav M A
  2020-08-27 15:45   ` Rob Herring
  1 sibling, 1 reply; 16+ messages in thread
From: Laurent Pinchart @ 2020-08-18 13:35 UTC (permalink / raw)
  To: Vaishnav M A
  Cc: greybus-dev, linux-kernel, gregkh, arnd, johan, elder, rajkovic,
	robh, mchehab+huawei, robertcnelson, drew, davem,
	zoran.stojsavljevic

Hi Vaishnav,

Thank you for the patch.

On Tue, Aug 18, 2020 at 06:18:15PM +0530, Vaishnav M A wrote:
> This patch adds device tree bindings for the mikroBUS port,
> device tree overlays for the mikrobus Port on the BeagleBoard.org
> PocketBeagle is available here :
> github.com/beagleboard/bb.org-overlays/blob/master/src/arm/PB-MIKROBUS-0.dts
> 
> Signed-off-by: Vaishnav M A <vaishnav@beagleboard.org>
> ---
>  .../bindings/misc/linux,mikrobus.txt          | 81 +++++++++++++++++++

Would you mind converting this binding document to YAML ? For new
bindings we're trying to enforce usage of YAML, to avoid increasing the
conversion backlog.

>  1 file changed, 81 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/misc/linux,mikrobus.txt
> 
> diff --git a/Documentation/devicetree/bindings/misc/linux,mikrobus.txt b/Documentation/devicetree/bindings/misc/linux,mikrobus.txt
> new file mode 100644
> index 000000000000..99f75caf5f35
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/misc/linux,mikrobus.txt
> @@ -0,0 +1,81 @@
> +mikroBUS add-on board socket
> +
> +Required properties:
> +- compatible: Must be "linux,mikrobus"
> +- i2c-adapter:  phandle to the i2c adapter attached to the mikrobus socket.
> +- spi-master: spi bus number of the spi-master attached to the mikrobus socket.
> +- spi-cs: spi chip-select numbers corresponding to the chip-selects
> +	  on the mikrobus socket(0 -> chip select corresponding to CS pin
> +	  1 -> chip select corresponding to RST pin).
> +- serdev-controller:  phandle to the uart port attached to the mikrobus socket.
> +- pwms: phandle to the pwm-controller corresponding to the mikroBUS PWM pin.
> +- mikrobus-gpios: gpios array corresponding to GPIOs on the mikroBUS port,
> +		  for targets not supporting the AN pin on the mikroBUS port as
> +		  GPIO, the length of the gpios array can be 11, otherwise it
> +		  should be 12.
> +- pinctrl-names: pinctrl state names to support additional pin usage/deviations
> +		 from mikroBUS socket standard usage, must be "default",
> +		 "pwm_default", "pwm_gpio", "uart_default", "uart_gpio",
> +		 "i2c_default", "i2c_gpio", "spi_default", "spi_gpio", these
> +		 pinctrl names should have corresponding pinctrl-N entries which
> +		 corresponds to the pinmux state for the pingroup, for example,
> +		 i2c_default corresponds to the state where the I2C pin group
> +		 (SCL,SDA) are configured in I2C mode and i2c_gpio mode corresponds
> +		 to the pinmux state where these pins are configured as GPIO.
> +- pinctrl-N : pinctrl-(0-8) corresponds to the pinctrl states for the states described
> +	      above.
> +
> +Example:
> +	mikrobus-0 {
> +		compatible = "linux,mikrobus";
> +		status = "okay";
> +		pinctrl-names = "default", "pwm_default", "pwm_gpio",
> +				"uart_default", "uart_gpio", "i2c_default",
> +				"i2c_gpio", "spi_default", "spi_gpio";
> +		pinctrl-0 = <
> +			&P2_03_gpio_input_pin
> +			&P1_04_gpio_pin
> +			&P1_02_gpio_pin
> +		>;
> +		pinctrl-1 = <&P2_01_pwm_pin>;
> +		pinctrl-2 = <&P2_01_gpio_pin>;
> +		pinctrl-3 = <
> +			&P2_05_uart_pin
> +			&P2_07_uart_pin
> +		>;
> +		pinctrl-4 = <
> +			&P2_05_gpio_pin
> +			&P2_07_gpio_pin
> +		>;
> +		pinctrl-5 = <
> +			&P2_09_i2c_pin
> +			&P2_11_i2c_pin
> +		>;
> +		pinctrl-6 = <
> +			&P2_09_gpio_pin
> +			&P2_11_gpio_pin
> +		>;
> +		pinctrl-7 = <
> +			&P1_12_spi_pin
> +			&P1_10_spi_pin
> +			&P1_08_spi_sclk_pin
> +			&P1_06_spi_cs_pin
> +		>;
> +		pinctrl-8 = <
> +			&P1_12_gpio_pin
> +			&P1_10_gpio_pin
> +			&P1_08_gpio_pin
> +			&P1_06_gpio_pin
> +		>;
> +		i2c-adapter = <&i2c1>;
> +		spi-master = <0>;
> +		spi-cs = <0 1>;
> +		serdev-controller = <&uart4>;
> +		pwms = <&ehrpwm1 0 500000 0>;
> +		mikrobus-gpios = <&gpio1 18 0> , <&gpio0 23 0>,
> +					<&gpio0 30 0> , <&gpio0 31 0>,
> +					<&gpio0 15 0> , <&gpio0 14 0>,
> +					<&gpio0 4 0> , <&gpio0 3 0>,
> +					<&gpio0 2 0> , <&gpio0 5 0>,
> +					<&gpio2 25 0>  , <&gpio2 3 0>;
> +	};
> \ No newline at end of file

-- 
Regards,

Laurent Pinchart

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

* Re: [RFC PATCH v2 0/3] mikroBUS driver for add-on boards
  2020-08-18 12:48 [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Vaishnav M A
                   ` (2 preceding siblings ...)
  2020-08-18 12:48 ` [RFC PATCH v2 3/3] Add Device Tree Bindings for mikroBUS port Vaishnav M A
@ 2020-08-18 15:24 ` Greg KH
  2020-08-18 21:52   ` Vaishnav M A
  2020-08-18 20:38 ` Frank Rowand
  4 siblings, 1 reply; 16+ messages in thread
From: Greg KH @ 2020-08-18 15:24 UTC (permalink / raw)
  To: Vaishnav M A
  Cc: greybus-dev, linux-kernel, arnd, johan, elder, robh,
	mchehab+huawei, davem, jkridner, drew, robertcnelson, rajkovic,
	chrisfriedt, zoran.stojsavljevic

On Tue, Aug 18, 2020 at 06:18:12PM +0530, Vaishnav M A wrote:
> Hi,
> 
> This Patch series is an update to the mikroBUS driver
> RFC v1 Patch : https://lkml.org/lkml/2020/7/24/518 .

Please use lore.kernel.org for links, we have no idea if lkml.org will
be working tomorrow or not :)

> The mikrobus driver is updated to add mikrobus ports from device-tree
> overlays, the debug interfaces for adding mikrobus ports through sysFS
> is removed, and the driver considers the extended usage of mikrobus
> port pins from their standard purposes.

I don't know what "properties" and "device" mean with regards to things
here, any chance you can provide a patch to the greybus spec itself that
adds this information so we can better understand the reasoning here to
see if the kernel changes match up with the goals?

thanks,

greg k-h

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

* Re: [RFC PATCH v2 0/3] mikroBUS driver for add-on boards
  2020-08-18 12:48 [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Vaishnav M A
                   ` (3 preceding siblings ...)
  2020-08-18 15:24 ` [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Greg KH
@ 2020-08-18 20:38 ` Frank Rowand
  2020-08-18 21:56   ` Vaishnav M A
  2020-08-25  1:44   ` Frank Rowand
  4 siblings, 2 replies; 16+ messages in thread
From: Frank Rowand @ 2020-08-18 20:38 UTC (permalink / raw)
  To: Vaishnav M A, greybus-dev, linux-kernel, gregkh, arnd, johan,
	elder, Frank Rowand, devicetree
  Cc: robh, mchehab+huawei, davem, jkridner, drew, robertcnelson,
	rajkovic, chrisfriedt, zoran.stojsavljevic

Hi Vaishnav,

+me +devicetree

Please add these two recipients to future versions.

I will comment more after reading the first version and v2.

-Frank


On 2020-08-18 07:48, Vaishnav M A wrote:
> Hi,
> 
> This Patch series is an update to the mikroBUS driver
> RFC v1 Patch : https://lkml.org/lkml/2020/7/24/518 .
> The mikrobus driver is updated to add mikrobus ports from device-tree
> overlays, the debug interfaces for adding mikrobus ports through sysFS
> is removed, and the driver considers the extended usage of mikrobus
> port pins from their standard purposes.
> 
> change log:
>         v2: support for adding mikroBUS ports from DT overlays,
>         remove debug sysFS interface for adding mikrobus ports,
>         consider extended pin usage/deviations from mikrobus standard
>         specifications,
>         use greybus CPort protocol enum instead of new protcol enums
>         Fix cases of wrong indendation, ignoring return values, freeing
>         allocated resources in case of errors and other style suggestions
>         in v1 review.
> 
> Vaishnav M A (3):
>   add mikrobus descriptors to greybus_manifest
>   mikroBUS driver for add-on boards on mikrobus ports
>   Add Device Tree Bindings for mikroBUS port
> 
>  .../bindings/misc/linux,mikrobus.txt          |  81 ++
>  MAINTAINERS                                   |   6 +
>  drivers/misc/Kconfig                          |   1 +
>  drivers/misc/Makefile                         |   1 +
>  drivers/misc/mikrobus/Kconfig                 |  16 +
>  drivers/misc/mikrobus/Makefile                |   7 +
>  drivers/misc/mikrobus/mikrobus_core.c         | 692 ++++++++++++++++++
>  drivers/misc/mikrobus/mikrobus_core.h         | 191 +++++
>  drivers/misc/mikrobus/mikrobus_manifest.c     | 444 +++++++++++
>  drivers/misc/mikrobus/mikrobus_manifest.h     |  21 +
>  drivers/misc/mikrobus/mikrobus_port.c         | 171 +++++
>  include/linux/greybus/greybus_manifest.h      |  47 ++
>  12 files changed, 1678 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/misc/linux,mikrobus.txt
>  create mode 100644 drivers/misc/mikrobus/Kconfig
>  create mode 100644 drivers/misc/mikrobus/Makefile
>  create mode 100644 drivers/misc/mikrobus/mikrobus_core.c
>  create mode 100644 drivers/misc/mikrobus/mikrobus_core.h
>  create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.c
>  create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.h
>  create mode 100644 drivers/misc/mikrobus/mikrobus_port.c
> 


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

* Re: [greybus-dev] [RFC PATCH v2 3/3] Add Device Tree Bindings for mikroBUS port
  2020-08-18 13:35   ` [greybus-dev] " Laurent Pinchart
@ 2020-08-18 21:22     ` Vaishnav M A
  0 siblings, 0 replies; 16+ messages in thread
From: Vaishnav M A @ 2020-08-18 21:22 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: greybus-dev, linux-kernel, gregkh, arnd, johan, elder,
	Ivan Rajković,
	robh, mchehab+huawei, Robert Nelson, Drew Fustini, davem,
	zoran.stojsavljevic

On Tue, Aug 18, 2020 at 7:05 PM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Vaishnav,
>
> Thank you for the patch.
>
> On Tue, Aug 18, 2020 at 06:18:15PM +0530, Vaishnav M A wrote:
> > This patch adds device tree bindings for the mikroBUS port,
> > device tree overlays for the mikrobus Port on the BeagleBoard.org
> > PocketBeagle is available here :
> > github.com/beagleboard/bb.org-overlays/blob/master/src/arm/PB-MIKROBUS-0.dts
> >
> > Signed-off-by: Vaishnav M A <vaishnav@beagleboard.org>
> > ---
> >  .../bindings/misc/linux,mikrobus.txt          | 81 +++++++++++++++++++
>
> Would you mind converting this binding document to YAML ? For new
> bindings we're trying to enforce usage of YAML, to avoid increasing the
> conversion backlog.
>
Hi Laurent,

Sure, I will convert the device tree binding document to YAML in the
next version.
> >  1 file changed, 81 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/misc/linux,mikrobus.txt
> >
> > diff --git a/Documentation/devicetree/bindings/misc/linux,mikrobus.txt b/Documentation/devicetree/bindings/misc/linux,mikrobus.txt
> > new file mode 100644
> > index 000000000000..99f75caf5f35
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/misc/linux,mikrobus.txt
> > @@ -0,0 +1,81 @@
> > +mikroBUS add-on board socket
> > +
> > +Required properties:
> > +- compatible: Must be "linux,mikrobus"
> > +- i2c-adapter:  phandle to the i2c adapter attached to the mikrobus socket.
> > +- spi-master: spi bus number of the spi-master attached to the mikrobus socket.
> > +- spi-cs: spi chip-select numbers corresponding to the chip-selects
> > +       on the mikrobus socket(0 -> chip select corresponding to CS pin
> > +       1 -> chip select corresponding to RST pin).
> > +- serdev-controller:  phandle to the uart port attached to the mikrobus socket.
> > +- pwms: phandle to the pwm-controller corresponding to the mikroBUS PWM pin.
> > +- mikrobus-gpios: gpios array corresponding to GPIOs on the mikroBUS port,
> > +               for targets not supporting the AN pin on the mikroBUS port as
> > +               GPIO, the length of the gpios array can be 11, otherwise it
> > +               should be 12.
> > +- pinctrl-names: pinctrl state names to support additional pin usage/deviations
> > +              from mikroBUS socket standard usage, must be "default",
> > +              "pwm_default", "pwm_gpio", "uart_default", "uart_gpio",
> > +              "i2c_default", "i2c_gpio", "spi_default", "spi_gpio", these
> > +              pinctrl names should have corresponding pinctrl-N entries which
> > +              corresponds to the pinmux state for the pingroup, for example,
> > +              i2c_default corresponds to the state where the I2C pin group
> > +              (SCL,SDA) are configured in I2C mode and i2c_gpio mode corresponds
> > +              to the pinmux state where these pins are configured as GPIO.
> > +- pinctrl-N : pinctrl-(0-8) corresponds to the pinctrl states for the states described
> > +           above.
> > +
> > +Example:
> > +     mikrobus-0 {
> > +             compatible = "linux,mikrobus";
> > +             status = "okay";
> > +             pinctrl-names = "default", "pwm_default", "pwm_gpio",
> > +                             "uart_default", "uart_gpio", "i2c_default",
> > +                             "i2c_gpio", "spi_default", "spi_gpio";
> > +             pinctrl-0 = <
> > +                     &P2_03_gpio_input_pin
> > +                     &P1_04_gpio_pin
> > +                     &P1_02_gpio_pin
> > +             >;
> > +             pinctrl-1 = <&P2_01_pwm_pin>;
> > +             pinctrl-2 = <&P2_01_gpio_pin>;
> > +             pinctrl-3 = <
> > +                     &P2_05_uart_pin
> > +                     &P2_07_uart_pin
> > +             >;
> > +             pinctrl-4 = <
> > +                     &P2_05_gpio_pin
> > +                     &P2_07_gpio_pin
> > +             >;
> > +             pinctrl-5 = <
> > +                     &P2_09_i2c_pin
> > +                     &P2_11_i2c_pin
> > +             >;
> > +             pinctrl-6 = <
> > +                     &P2_09_gpio_pin
> > +                     &P2_11_gpio_pin
> > +             >;
> > +             pinctrl-7 = <
> > +                     &P1_12_spi_pin
> > +                     &P1_10_spi_pin
> > +                     &P1_08_spi_sclk_pin
> > +                     &P1_06_spi_cs_pin
> > +             >;
> > +             pinctrl-8 = <
> > +                     &P1_12_gpio_pin
> > +                     &P1_10_gpio_pin
> > +                     &P1_08_gpio_pin
> > +                     &P1_06_gpio_pin
> > +             >;
> > +             i2c-adapter = <&i2c1>;
> > +             spi-master = <0>;
> > +             spi-cs = <0 1>;
> > +             serdev-controller = <&uart4>;
> > +             pwms = <&ehrpwm1 0 500000 0>;
> > +             mikrobus-gpios = <&gpio1 18 0> , <&gpio0 23 0>,
> > +                                     <&gpio0 30 0> , <&gpio0 31 0>,
> > +                                     <&gpio0 15 0> , <&gpio0 14 0>,
> > +                                     <&gpio0 4 0> , <&gpio0 3 0>,
> > +                                     <&gpio0 2 0> , <&gpio0 5 0>,
> > +                                     <&gpio2 25 0>  , <&gpio2 3 0>;
> > +     };
> > \ No newline at end of file
>
> --
> Regards,
>
> Laurent Pinchart
Thanks and Regards,

Vaishnav

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

* Re: [RFC PATCH v2 0/3] mikroBUS driver for add-on boards
  2020-08-18 15:24 ` [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Greg KH
@ 2020-08-18 21:52   ` Vaishnav M A
  2020-08-19  5:54     ` Greg KH
  0 siblings, 1 reply; 16+ messages in thread
From: Vaishnav M A @ 2020-08-18 21:52 UTC (permalink / raw)
  To: Greg KH
  Cc: greybus-dev, linux-kernel, arnd, johan, elder, robh,
	mchehab+huawei, davem, Jason Kridner, Drew Fustini,
	Robert Nelson, Ivan Rajković,
	chrisfriedt, zoran.stojsavljevic

On Tue, Aug 18, 2020 at 8:54 PM Greg KH <gregkh@linuxfoundation.org> wrote:
>
> On Tue, Aug 18, 2020 at 06:18:12PM +0530, Vaishnav M A wrote:
> > Hi,
> >
> > This Patch series is an update to the mikroBUS driver
> > RFC v1 Patch : https://lkml.org/lkml/2020/7/24/518 .
>
> Please use lore.kernel.org for links, we have no idea if lkml.org will
> be working tomorrow or not :)
>
Hi Greg,

Thanks, will use lore.kernel.org for the links, attaching the corresponding
link to the v1 RFC patch thread for reference:
https://lore.kernel.org/lkml/20200724120637.GA427284@vaishnav-VirtualBox/

> > The mikrobus driver is updated to add mikrobus ports from device-tree
> > overlays, the debug interfaces for adding mikrobus ports through sysFS
> > is removed, and the driver considers the extended usage of mikrobus
> > port pins from their standard purposes.
>
> I don't know what "properties" and "device" mean with regards to things
> here, any chance you can provide a patch to the greybus spec itself that
> adds this information so we can better understand the reasoning here to
> see if the kernel changes match up with the goals?
>
> thanks,
>
> greg k-h
Sure, I will add a patch to the greybus-spec to describe the new descriptors,
the property and device descriptors are introduced to add information
about the SPI/I2C/UART chip/sensor which is required by the corresponding
device drivers, With these descriptors, it will be possible to describe devices
on I2C, SPI, UART, etc. behind a greybus device so as to bind existing kernel
drivers to them, This is not what is currently being done within the mikroBUS
driver, now it tries to instantiate devices on actual I2C, SPI, UART from
describing manifests, but the ultimate goal is to describe the devices on
I2C/SPI/UART behind a greybus device, thus enabling to attach existing
kernel drivers to devices present in add-on boards attached to mikroBUS
ports added via greybus.

Shall I submit a pull request to https://github.com/projectara/greybus-spec
for the specs, is there a different official upstream to greybus-spec?

Thanks and Regards,
Vaishnav M A

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

* Re: [RFC PATCH v2 0/3] mikroBUS driver for add-on boards
  2020-08-18 20:38 ` Frank Rowand
@ 2020-08-18 21:56   ` Vaishnav M A
  2020-08-25  1:44   ` Frank Rowand
  1 sibling, 0 replies; 16+ messages in thread
From: Vaishnav M A @ 2020-08-18 21:56 UTC (permalink / raw)
  To: Frank Rowand
  Cc: greybus-dev, linux-kernel, Greg KH, arnd, johan, elder,
	devicetree, robh, mchehab+huawei, davem, Jason Kridner,
	Drew Fustini, Robert Nelson, Ivan Rajković,
	chrisfriedt, zoran.stojsavljevic

On Wed, Aug 19, 2020 at 2:08 AM Frank Rowand <frowand.list@gmail.com> wrote:
>
> Hi Vaishnav,
>
> +me +devicetree
>
> Please add these two recipients to future versions.
>
> I will comment more after reading the first version and v2.
>
> -Frank
>
Hi Frank,

Sorry, I missed to run get_maintainer.pl after making the changes
will add both recipients in future versions.

Thanks and Regards,
Vaishnav M A
>
> On 2020-08-18 07:48, Vaishnav M A wrote:
> > Hi,
> >
> > This Patch series is an update to the mikroBUS driver
> > RFC v1 Patch : https://lkml.org/lkml/2020/7/24/518 .
> > The mikrobus driver is updated to add mikrobus ports from device-tree
> > overlays, the debug interfaces for adding mikrobus ports through sysFS
> > is removed, and the driver considers the extended usage of mikrobus
> > port pins from their standard purposes.
> >
> > change log:
> >         v2: support for adding mikroBUS ports from DT overlays,
> >         remove debug sysFS interface for adding mikrobus ports,
> >         consider extended pin usage/deviations from mikrobus standard
> >         specifications,
> >         use greybus CPort protocol enum instead of new protcol enums
> >         Fix cases of wrong indendation, ignoring return values, freeing
> >         allocated resources in case of errors and other style suggestions
> >         in v1 review.
> >
> > Vaishnav M A (3):
> >   add mikrobus descriptors to greybus_manifest
> >   mikroBUS driver for add-on boards on mikrobus ports
> >   Add Device Tree Bindings for mikroBUS port
> >
> >  .../bindings/misc/linux,mikrobus.txt          |  81 ++
> >  MAINTAINERS                                   |   6 +
> >  drivers/misc/Kconfig                          |   1 +
> >  drivers/misc/Makefile                         |   1 +
> >  drivers/misc/mikrobus/Kconfig                 |  16 +
> >  drivers/misc/mikrobus/Makefile                |   7 +
> >  drivers/misc/mikrobus/mikrobus_core.c         | 692 ++++++++++++++++++
> >  drivers/misc/mikrobus/mikrobus_core.h         | 191 +++++
> >  drivers/misc/mikrobus/mikrobus_manifest.c     | 444 +++++++++++
> >  drivers/misc/mikrobus/mikrobus_manifest.h     |  21 +
> >  drivers/misc/mikrobus/mikrobus_port.c         | 171 +++++
> >  include/linux/greybus/greybus_manifest.h      |  47 ++
> >  12 files changed, 1678 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/misc/linux,mikrobus.txt
> >  create mode 100644 drivers/misc/mikrobus/Kconfig
> >  create mode 100644 drivers/misc/mikrobus/Makefile
> >  create mode 100644 drivers/misc/mikrobus/mikrobus_core.c
> >  create mode 100644 drivers/misc/mikrobus/mikrobus_core.h
> >  create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.c
> >  create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.h
> >  create mode 100644 drivers/misc/mikrobus/mikrobus_port.c
> >
>

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

* Re: [RFC PATCH v2 0/3] mikroBUS driver for add-on boards
  2020-08-18 21:52   ` Vaishnav M A
@ 2020-08-19  5:54     ` Greg KH
  0 siblings, 0 replies; 16+ messages in thread
From: Greg KH @ 2020-08-19  5:54 UTC (permalink / raw)
  To: Vaishnav M A
  Cc: greybus-dev, linux-kernel, arnd, johan, elder, robh,
	mchehab+huawei, davem, Jason Kridner, Drew Fustini,
	Robert Nelson, Ivan Rajković,
	chrisfriedt, zoran.stojsavljevic

On Wed, Aug 19, 2020 at 03:22:48AM +0530, Vaishnav M A wrote:
> On Tue, Aug 18, 2020 at 8:54 PM Greg KH <gregkh@linuxfoundation.org> wrote:
> >
> > On Tue, Aug 18, 2020 at 06:18:12PM +0530, Vaishnav M A wrote:
> > > Hi,
> > >
> > > This Patch series is an update to the mikroBUS driver
> > > RFC v1 Patch : https://lkml.org/lkml/2020/7/24/518 .
> >
> > Please use lore.kernel.org for links, we have no idea if lkml.org will
> > be working tomorrow or not :)
> >
> Hi Greg,
> 
> Thanks, will use lore.kernel.org for the links, attaching the corresponding
> link to the v1 RFC patch thread for reference:
> https://lore.kernel.org/lkml/20200724120637.GA427284@vaishnav-VirtualBox/
> 
> > > The mikrobus driver is updated to add mikrobus ports from device-tree
> > > overlays, the debug interfaces for adding mikrobus ports through sysFS
> > > is removed, and the driver considers the extended usage of mikrobus
> > > port pins from their standard purposes.
> >
> > I don't know what "properties" and "device" mean with regards to things
> > here, any chance you can provide a patch to the greybus spec itself that
> > adds this information so we can better understand the reasoning here to
> > see if the kernel changes match up with the goals?
> >
> > thanks,
> >
> > greg k-h
> Sure, I will add a patch to the greybus-spec to describe the new descriptors,
> the property and device descriptors are introduced to add information
> about the SPI/I2C/UART chip/sensor which is required by the corresponding
> device drivers, With these descriptors, it will be possible to describe devices
> on I2C, SPI, UART, etc. behind a greybus device so as to bind existing kernel
> drivers to them, This is not what is currently being done within the mikroBUS
> driver, now it tries to instantiate devices on actual I2C, SPI, UART from
> describing manifests, but the ultimate goal is to describe the devices on
> I2C/SPI/UART behind a greybus device, thus enabling to attach existing
> kernel drivers to devices present in add-on boards attached to mikroBUS
> ports added via greybus.
> 
> Shall I submit a pull request to https://github.com/projectara/greybus-spec
> for the specs, is there a different official upstream to greybus-spec?

That's a good place, but for now, you can submit it as part of your
patch series as well, so we can all see it and review it easier.

thanks,

greg k-h

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

* Re: [RFC PATCH v2 1/3] add mikrobus descriptors to greybus_manifest
  2020-08-18 12:48 ` [RFC PATCH v2 1/3] add mikrobus descriptors to greybus_manifest Vaishnav M A
@ 2020-08-20  0:49   ` Vaishnav M A
  2020-08-31  6:26     ` Zoran Stojsavljevic
  0 siblings, 1 reply; 16+ messages in thread
From: Vaishnav M A @ 2020-08-20  0:49 UTC (permalink / raw)
  To: greybus-dev, linux-kernel, Greg KH, arnd, johan, elder
  Cc: robh, mchehab+huawei, davem, Jason Kridner, Drew Fustini,
	Robert Nelson, Ivan Rajković,
	chrisfriedt, zoran.stojsavljevic, Frank Rowand, devicetree

Hi,

Trying to add more information regarding the newly added
descriptors and describe how they are used now within the
mikroBUS driver.

On Tue, Aug 18, 2020 at 6:18 PM Vaishnav M A <vaishnav@beagleboard.org> wrote:
>
> This patch adds new descriptors used in the manifest parsing inside
> the mikrobus driver, the device descriptor help to describe the
> devices on a mikroBUS port, mikrobus descriptor is used to set up
> the mikrobus port pinmux and GPIO states and property descriptor
> to pass named properties to device drivers through the Unified
> Properties API under linux/property.h
>
> The corresponding pull request for manifesto is updated
> at : https://github.com/projectara/manifesto/pull/2
>
> Signed-off-by: Vaishnav M A <vaishnav@beagleboard.org>
> ---
>  include/linux/greybus/greybus_manifest.h | 47 ++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/include/linux/greybus/greybus_manifest.h b/include/linux/greybus/greybus_manifest.h
> index 6e62fe478712..821661ea7f01 100644
> --- a/include/linux/greybus/greybus_manifest.h
> +++ b/include/linux/greybus/greybus_manifest.h
> @@ -23,6 +23,9 @@ enum greybus_descriptor_type {
>         GREYBUS_TYPE_STRING             = 0x02,
>         GREYBUS_TYPE_BUNDLE             = 0x03,
>         GREYBUS_TYPE_CPORT              = 0x04,
> +       GREYBUS_TYPE_MIKROBUS           = 0x05,

The mikrobus descriptor is used to pass information about
the specific pinmux settings and the default GPIO states on
the mikrobus port to be set up for the add-on board to work
correctly, this descriptor has 12 u8 fields(corresponding  to the
12 pins on the mikrobus port) which includes information
about the prior setup required on the mikroBUS port for the
device(s) on the add-on board to work correctly. The mikrobus
descriptor is a fixed-length descriptor and there will be only a
single instance of mikrobus descriptor per add-on board manifest.

> +       GREYBUS_TYPE_PROPERTY           = 0x06,

The property descriptors are used to pass named properties
to the device drivers through the Unified device property interface
under linux/property.h , so that device drivers using the
device_property_read_* call can get the named properties,
the mikrobus driver fetches the information from the manifest
binary and forms a corresponding `struct property_entry` which
will be attached to the `struct device`.
The property descriptor is a variable-length descriptor similar
to the string descriptor and there can be multiple instances of
property descriptor per add-on board manifest.

> +       GREYBUS_TYPE_DEVICE             = 0x07,

The device descriptor is used to describe a device on the
mikrobus port and has necessary fields from `struct i2c_board_info`
and `struct spi_board_info` to describe a device on these buses
in a mikrobus port, even though  SPI/I2C device info structs are used
this descriptor has enough information to describe other kinds of
devices relevant to mikrobus as well.(serdev/platform devices).
The device descriptor is a fixed-length descriptor and there can be
multiple instances of device descriptors in an add-on board manifest
in cases where the add-on board presents more than one device
to the host.

>  };
>
>  enum greybus_protocol {
> @@ -151,6 +154,47 @@ struct greybus_descriptor_cport {
>         __u8    protocol_id;    /* enum greybus_protocol */
>  } __packed;
>
> +/*
> + * A mikrobus descriptor is used to describe the details
> + * about the bus ocnfiguration for the add-on board
> + * connected to the mikrobus port.
> + */
> +struct greybus_descriptor_mikrobus {
> +       __u8 pin_state[12];
> +} __packed;
> +

These 12 u8 fields describe the state of the pins in the
mikrobus port(in clock wise order starting from the PWM
pin)
mikrobus v2 standard specification :
https://download.mikroe.com/documents/standards/mikrobus/mikrobus-standard-specification-v200.pdf
This struct is filled from the mikrobus-descriptor
in the manifest and can have one of the values
for each pin group:
MIKROBUS_STATE_INPUT = 0x01,
MIKROBUS_STATE_OUTPUT_HIGH = 0x02,
MIKROBUS_STATE_OUTPUT_LOW = 0x03,
MIKROBUS_STATE_PWM = 0x04,  ( applicable only to  PWM pin)
MIKROBUS_STATE_SPI = 0x05, ( applicable only to
the group of MOSI, MISO, SCK , CS pins on mikroBUS port)
MIKROBUS_STATE_I2C = 0x06, (applicable only to the SCL, SDA
pins on the mikrobus port)
MIKROBUS_STATE_UART = 0x07,(applicable only to the RX, TX
pins on the mikrobus port)
There are two purposes for adding this descriptor,
1) for some add-on boards some of the pins might need to
be configured as GPIOs deviating from their reserved purposes
An example for this case is an SHT15 Click (https://www.mikroe.com/sht1x-click),
where the SCL and SDA Pins need to be configured as GPIOs
for the driver (drivers/hwmon/sht15.c) to work. The mikrobus
descriptor for this case would look like this :
[mikrobus-descriptor]
pwm-state = 4 (default, pwm)
int-state = 1 (default, input)
rx-state = 7 (default, uart)
tx-state = 7 (default, uart)
scl-state = 3 (note the SCL Pin configured as GPIO)
sda-state = 3 (note the SCL Pin configured as GPIO)
mosi-state = 5 (default, spi)
miso-state = 5 (default, spi)
sck-state = 5 (default, spi)
cs-state = 5 (default, spi)
rst-state = 2 (default, GPIO)
an-state = 1 (default, input)
2) for some add-on boards the driver may not take care
of some additional signals like reset/wake-up/other thus
the mikrobus driver can set-up these GPIOs to a required
default state from the information from the manifest, a good
example for this is the  ENC28J60 click (https://www.mikroe.com/eth-click)
where the reset line(RST pin on the mikrobus port) needs to be
pulled high. The manifest example for this add-on board can
be found here :
https://github.com/vaishnav98/manifesto/blob/mikrobusv3/manifests/ETH-CLICK.mnfs

> +/*
> + * A property descriptor is used to pass named properties
> + * to device drivers through the unified device properties
> + * interface under linux/property.h
> + */
> +struct greybus_descriptor_property {
> +       __u8 length;
> +       __u8 id;
> +       __u8 propname_stringid;
> +       __u8 type;
> +       __u8 value[0];
> +} __packed;
> +

This descriptor is used to fill in `struct property_entry`
(linux/property.h), the propname_stringid
field is used to map to the corresponding string descriptor
which has the property name, the type field has the types
under dev_prop_type (linux/property.h) and there are
some new types which are used within the mikrobus
driver, these are the new types :
MIKROBUS_PROPERTY_TYPE_LINK = 0x01
MIKROBUS_PROPERTY_TYPE_GPIO = 0x02

The property-link type is used to attach an array of properties
to the corresponding device, for example, consider an SPI
EEPROM device which works with the AT25 driver(
drivers/misc/eeprom/at25.c), The device and property
descriptor parts of the manifest will look like this.

[device-descriptor 1]
driver-string-id = 3
prop-link = 1 (The ID of the property-descriptor which
contains the list of IDs of the actual properties to attach with
the device)
protocol = 0xb
reg = 0
mode = 0x3
max-speed-hz = 5000000
[string-descriptor 3]
string = at25 (driver string)

[property-descriptor 1]
name-string-id = 4
type = 0x01 (type is property-link)
value = <2 3 4>(attach properties with id 2,3,4 to the device)
[string-descriptor 4]
string = prop-link

[property-descriptor 2]
name-string-id = 5 (string id for the property name string)
type = 0x05 (U32, driver uses device_property_read_u32 call
to read the value)
value = <262144>
[string-descriptor 5]
string = size (property name string)

[property-descriptor 3]
name-string-id = 6
type = 0x05
value = <256>
[string-descriptor 6]
string = pagesize

[property-descriptor 4]
name-string-id = 7
type = 0x05
value = <24>
[string-descriptor 7]
string = address-width

The gpio-link type is very similar to property descriptor and is used to
pass an array of named gpios to the device driver through GPIO lookup tables,
consider an example for a SHT15 device (drivers/hwmon/sht15.c),
the device and the property(gpio) descriptors are as follows :

[device-descriptor 1]
driver-string-id = 3
protocol = 0xfe
reg = 0
gpio-link = 1 (The ID of the property-descriptor which
contains the list of IDs of the named gpio properties to attach with
the device)

[string-descriptor 3]
string = sht11 (device_id string)

[property-descriptor 1]
name-string-id = 4
type = 0x02 (gpio-link)
value = <2 3> (attach properties with id 2,3 as named gpios to the device)
[string-descriptor 4]
string = gpio-link

[property-descriptor 2]
name-string-id = 5
type = 0x03
value = <4>
[string-descriptor 5]
string = clk (name of the GPIO, the driver uses
devm_gpiod_get or similar calls to get the GPIO)

[property-descriptor 3]
name-string-id = 6
type = 0x03
value = <5>
[string-descriptor 6]
string = data

Note that the values here 4 and 5 for the GPIOs are
the offset numbers(clockwise starting from PWM pin)
within a mikrobus port, the mikrobus drivers translates this
offset information to the actual GPIO while creating the GPIO
lookup table, this ensures that the manifest doesn't have any
port-specific information and a single manifest can be used for
an add-on board over different platforms/sockets.

> +/*
> + * A device descriptor is used to describe the
> + * details required by a add-on board device
> + * driver.
> + */
> +struct greybus_descriptor_device {
> +       __u8 id;
> +       __u8 driver_stringid;
> +       __u8 protocol;
> +       __u8 reg;
> +       __le32 max_speed_hz;
> +       __u8 irq;
> +       __u8 irq_type;
> +       __u8 mode;
> +       __u8 prop_link;
> +       __u8 gpio_link;
> +       __u8 pad[3];
> +} __packed;
> +

The device descriptor is used to describe a device on the
mikrobus port and has necessary fields from `struct i2c_board_info`
and `struct spi_board_info`, of these fields, the irq field is similar to
the gpio descriptor value above in that the value under irq is also
the pin offset within the mikrobus port which will be translated to the
actual GPIO within the mikrobus driver and the irq-type takes types
defined under linux/interrupt.h . For a device with a
IRQF_TRIGGER_RISING interrupt on the INT pin on the mikrobus port
the fields will be :
irq = 1 (offset of INT pin)
irq_type = 1 ( IRQF_TRIGGER_RISING)

>  struct greybus_descriptor_header {
>         __le16  size;
>         __u8    type;           /* enum greybus_descriptor_type */
> @@ -164,6 +208,9 @@ struct greybus_descriptor {
>                 struct greybus_descriptor_interface     interface;
>                 struct greybus_descriptor_bundle        bundle;
>                 struct greybus_descriptor_cport         cport;
> +               struct greybus_descriptor_mikrobus      mikrobus;
> +               struct greybus_descriptor_property      property;
> +               struct greybus_descriptor_device        device;
>         };
>  } __packed;
>
> --
> 2.25.1
>
Thanks and Regards,
Vaishnav

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

* Re: [RFC PATCH v2 0/3] mikroBUS driver for add-on boards
  2020-08-18 20:38 ` Frank Rowand
  2020-08-18 21:56   ` Vaishnav M A
@ 2020-08-25  1:44   ` Frank Rowand
  1 sibling, 0 replies; 16+ messages in thread
From: Frank Rowand @ 2020-08-25  1:44 UTC (permalink / raw)
  To: Vaishnav M A, greybus-dev, linux-kernel, gregkh, arnd, johan,
	elder, devicetree
  Cc: robh, mchehab+huawei, davem, jkridner, drew, robertcnelson,
	rajkovic, chrisfriedt, zoran.stojsavljevic

Hi Vaishnav,

Apologies in advance -- I expect to be very slow in responding this
week.  Linux Plumbers will take some of my time and I am moving to
a new home.

-Frank


On 2020-08-18 15:38, Frank Rowand wrote:
> Hi Vaishnav,
> 
> +me +devicetree
> 
> Please add these two recipients to future versions.
> 
> I will comment more after reading the first version and v2.
> 
> -Frank
> 
> 
> On 2020-08-18 07:48, Vaishnav M A wrote:
>> Hi,
>>
>> This Patch series is an update to the mikroBUS driver
>> RFC v1 Patch : https://lkml.org/lkml/2020/7/24/518 .
>> The mikrobus driver is updated to add mikrobus ports from device-tree
>> overlays, the debug interfaces for adding mikrobus ports through sysFS
>> is removed, and the driver considers the extended usage of mikrobus
>> port pins from their standard purposes.
>>
>> change log:
>>         v2: support for adding mikroBUS ports from DT overlays,
>>         remove debug sysFS interface for adding mikrobus ports,
>>         consider extended pin usage/deviations from mikrobus standard
>>         specifications,
>>         use greybus CPort protocol enum instead of new protcol enums
>>         Fix cases of wrong indendation, ignoring return values, freeing
>>         allocated resources in case of errors and other style suggestions
>>         in v1 review.
>>
>> Vaishnav M A (3):
>>   add mikrobus descriptors to greybus_manifest
>>   mikroBUS driver for add-on boards on mikrobus ports
>>   Add Device Tree Bindings for mikroBUS port
>>
>>  .../bindings/misc/linux,mikrobus.txt          |  81 ++
>>  MAINTAINERS                                   |   6 +
>>  drivers/misc/Kconfig                          |   1 +
>>  drivers/misc/Makefile                         |   1 +
>>  drivers/misc/mikrobus/Kconfig                 |  16 +
>>  drivers/misc/mikrobus/Makefile                |   7 +
>>  drivers/misc/mikrobus/mikrobus_core.c         | 692 ++++++++++++++++++
>>  drivers/misc/mikrobus/mikrobus_core.h         | 191 +++++
>>  drivers/misc/mikrobus/mikrobus_manifest.c     | 444 +++++++++++
>>  drivers/misc/mikrobus/mikrobus_manifest.h     |  21 +
>>  drivers/misc/mikrobus/mikrobus_port.c         | 171 +++++
>>  include/linux/greybus/greybus_manifest.h      |  47 ++
>>  12 files changed, 1678 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/misc/linux,mikrobus.txt
>>  create mode 100644 drivers/misc/mikrobus/Kconfig
>>  create mode 100644 drivers/misc/mikrobus/Makefile
>>  create mode 100644 drivers/misc/mikrobus/mikrobus_core.c
>>  create mode 100644 drivers/misc/mikrobus/mikrobus_core.h
>>  create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.c
>>  create mode 100644 drivers/misc/mikrobus/mikrobus_manifest.h
>>  create mode 100644 drivers/misc/mikrobus/mikrobus_port.c
>>
> 


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

* Re: [RFC PATCH v2 3/3] Add Device Tree Bindings for mikroBUS port
  2020-08-18 12:48 ` [RFC PATCH v2 3/3] Add Device Tree Bindings for mikroBUS port Vaishnav M A
  2020-08-18 13:35   ` [greybus-dev] " Laurent Pinchart
@ 2020-08-27 15:45   ` Rob Herring
  1 sibling, 0 replies; 16+ messages in thread
From: Rob Herring @ 2020-08-27 15:45 UTC (permalink / raw)
  To: Vaishnav M A
  Cc: greybus-dev, linux-kernel, Greg Kroah-Hartman, Arnd Bergmann,
	Johan Hovold, elder, Mauro Carvalho Chehab, David Miller,
	Jason Kridner, Drew Fustini, robertcnelson, rajkovic,
	chrisfriedt, zoran.stojsavljevic

On Tue, Aug 18, 2020 at 6:48 AM Vaishnav M A <vaishnav@beagleboard.org> wrote:
>
> This patch adds device tree bindings for the mikroBUS port,
> device tree overlays for the mikrobus Port on the BeagleBoard.org
> PocketBeagle is available here :
> github.com/beagleboard/bb.org-overlays/blob/master/src/arm/PB-MIKROBUS-0.dts
>
> Signed-off-by: Vaishnav M A <vaishnav@beagleboard.org>
> ---
>  .../bindings/misc/linux,mikrobus.txt          | 81 +++++++++++++++++++
>  1 file changed, 81 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/misc/linux,mikrobus.txt
>
> diff --git a/Documentation/devicetree/bindings/misc/linux,mikrobus.txt b/Documentation/devicetree/bindings/misc/linux,mikrobus.txt
> new file mode 100644
> index 000000000000..99f75caf5f35
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/misc/linux,mikrobus.txt
> @@ -0,0 +1,81 @@
> +mikroBUS add-on board socket
> +
> +Required properties:
> +- compatible: Must be "linux,mikrobus"

mikrobus is only a Linux thing? Just 'mikrobus-connector' is fine.

Are there versions of mikrobus spec/connectors? If so, then should
probably include that into

> +- i2c-adapter:  phandle to the i2c adapter attached to the mikrobus socket.
> +- spi-master: spi bus number of the spi-master attached to the mikrobus socket.
> +- spi-cs: spi chip-select numbers corresponding to the chip-selects
> +         on the mikrobus socket(0 -> chip select corresponding to CS pin
> +         1 -> chip select corresponding to RST pin).

SPI and I2C need a common way to remap from host bus/cs to connector
bus/cs including how to define the child devices and multiple
instances.

> +- serdev-controller:  phandle to the uart port attached to the mikrobus socket.

'serdev' is a Linuxism. This also needs to be defined how child
devices and multiple instances.

There's also a problem with the current serdev implementation that
assigning a serial port to serdev or tty is a one time decision as
probe time. So I don't think hotplug of a serial device will work
today. But that's a Linux problem independent of the binding.

> +- pwms: phandle to the pwm-controller corresponding to the mikroBUS PWM pin.

The PWM binding has a provider specific number of cells, so some
translation is needed. Probably can define a 'pwm-map' property like
gpio-map on this. More below.

> +- mikrobus-gpios: gpios array corresponding to GPIOs on the mikroBUS port,
> +                 for targets not supporting the AN pin on the mikroBUS port as
> +                 GPIO, the length of the gpios array can be 11, otherwise it
> +                 should be 12.

We have 'gpio-map' binding already (it's in the DT spec) created for
this purpose of remapping connector GPIO numbers to host GPIO numbers.


> +- pinctrl-names: pinctrl state names to support additional pin usage/deviations
> +                from mikroBUS socket standard usage, must be "default",
> +                "pwm_default", "pwm_gpio", "uart_default", "uart_gpio",
> +                "i2c_default", "i2c_gpio", "spi_default", "spi_gpio", these
> +                pinctrl names should have corresponding pinctrl-N entries which
> +                corresponds to the pinmux state for the pingroup, for example,
> +                i2c_default corresponds to the state where the I2C pin group
> +                (SCL,SDA) are configured in I2C mode and i2c_gpio mode corresponds
> +                to the pinmux state where these pins are configured as GPIO.
> +- pinctrl-N : pinctrl-(0-8) corresponds to the pinctrl states for the states described
> +             above.
> +
> +Example:
> +       mikrobus-0 {
> +               compatible = "linux,mikrobus";
> +               status = "okay";
> +               pinctrl-names = "default", "pwm_default", "pwm_gpio",
> +                               "uart_default", "uart_gpio", "i2c_default",
> +                               "i2c_gpio", "spi_default", "spi_gpio";
> +               pinctrl-0 = <
> +                       &P2_03_gpio_input_pin
> +                       &P1_04_gpio_pin
> +                       &P1_02_gpio_pin
> +               >;
> +               pinctrl-1 = <&P2_01_pwm_pin>;
> +               pinctrl-2 = <&P2_01_gpio_pin>;
> +               pinctrl-3 = <
> +                       &P2_05_uart_pin
> +                       &P2_07_uart_pin
> +               >;
> +               pinctrl-4 = <
> +                       &P2_05_gpio_pin
> +                       &P2_07_gpio_pin
> +               >;
> +               pinctrl-5 = <
> +                       &P2_09_i2c_pin
> +                       &P2_11_i2c_pin
> +               >;
> +               pinctrl-6 = <
> +                       &P2_09_gpio_pin
> +                       &P2_11_gpio_pin
> +               >;
> +               pinctrl-7 = <
> +                       &P1_12_spi_pin
> +                       &P1_10_spi_pin
> +                       &P1_08_spi_sclk_pin
> +                       &P1_06_spi_cs_pin
> +               >;
> +               pinctrl-8 = <
> +                       &P1_12_gpio_pin
> +                       &P1_10_gpio_pin
> +                       &P1_08_gpio_pin
> +                       &P1_06_gpio_pin
> +               >;
> +               i2c-adapter = <&i2c1>;
> +               spi-master = <0>;
> +               spi-cs = <0 1>;
> +               serdev-controller = <&uart4>;
> +               pwms = <&ehrpwm1 0 500000 0>;
> +               mikrobus-gpios = <&gpio1 18 0> , <&gpio0 23 0>,
> +                                       <&gpio0 30 0> , <&gpio0 31 0>,
> +                                       <&gpio0 15 0> , <&gpio0 14 0>,
> +                                       <&gpio0 4 0> , <&gpio0 3 0>,
> +                                       <&gpio0 2 0> , <&gpio0 5 0>,
> +                                       <&gpio2 25 0>  , <&gpio2 3 0>;
> +       };
> \ No newline at end of file
> --
> 2.25.1
>

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

* Re: [RFC PATCH v2 1/3] add mikrobus descriptors to greybus_manifest
  2020-08-20  0:49   ` Vaishnav M A
@ 2020-08-31  6:26     ` Zoran Stojsavljevic
  2020-09-01  8:33       ` Vaishnav M A
  0 siblings, 1 reply; 16+ messages in thread
From: Zoran Stojsavljevic @ 2020-08-31  6:26 UTC (permalink / raw)
  To: Vaishnav M A
  Cc: greybus-dev, linux-kernel, Greg KH, arnd, johan, elder, robh,
	mchehab+huawei, davem, Jason Kridner, Drew Fustini,
	Robert Nelson, Ivan Rajković,
	chrisfriedt, Frank Rowand, devicetree

Hello Vaishnav,

I should say, an excellent work on the greybus_manifest.h file.

Actually, my thoughts will be to have a two-stage commit of the whole
MikroBUS patch.

The first one are these changes with greybus_manifest.h, followed by
dependent mikrobus_core.h and mikrobus_manifest.h.

These two should have included #include
<linux/greybus/greybus_manifest.h> to reflect the correct hierarchical
structure.

The rest is with the mikrobus driver .c code.

It is just an observation from me, I guess, it is obvious.

My two cent worth comment,
Zoran
_______

On Thu, Aug 20, 2020 at 2:49 AM Vaishnav M A <vaishnav@beagleboard.org> wrote:
>
> Hi,
>
> Trying to add more information regarding the newly added
> descriptors and describe how they are used now within the
> mikroBUS driver.
>
> On Tue, Aug 18, 2020 at 6:18 PM Vaishnav M A <vaishnav@beagleboard.org> wrote:
> >
> > This patch adds new descriptors used in the manifest parsing inside
> > the mikrobus driver, the device descriptor help to describe the
> > devices on a mikroBUS port, mikrobus descriptor is used to set up
> > the mikrobus port pinmux and GPIO states and property descriptor
> > to pass named properties to device drivers through the Unified
> > Properties API under linux/property.h
> >
> > The corresponding pull request for manifesto is updated
> > at : https://github.com/projectara/manifesto/pull/2
> >
> > Signed-off-by: Vaishnav M A <vaishnav@beagleboard.org>
> > ---
> >  include/linux/greybus/greybus_manifest.h | 47 ++++++++++++++++++++++++
> >  1 file changed, 47 insertions(+)
> >
> > diff --git a/include/linux/greybus/greybus_manifest.h b/include/linux/greybus/greybus_manifest.h
> > index 6e62fe478712..821661ea7f01 100644
> > --- a/include/linux/greybus/greybus_manifest.h
> > +++ b/include/linux/greybus/greybus_manifest.h
> > @@ -23,6 +23,9 @@ enum greybus_descriptor_type {
> >         GREYBUS_TYPE_STRING             = 0x02,
> >         GREYBUS_TYPE_BUNDLE             = 0x03,
> >         GREYBUS_TYPE_CPORT              = 0x04,
> > +       GREYBUS_TYPE_MIKROBUS           = 0x05,
>
> The mikrobus descriptor is used to pass information about
> the specific pinmux settings and the default GPIO states on
> the mikrobus port to be set up for the add-on board to work
> correctly, this descriptor has 12 u8 fields(corresponding  to the
> 12 pins on the mikrobus port) which includes information
> about the prior setup required on the mikroBUS port for the
> device(s) on the add-on board to work correctly. The mikrobus
> descriptor is a fixed-length descriptor and there will be only a
> single instance of mikrobus descriptor per add-on board manifest.
>
> > +       GREYBUS_TYPE_PROPERTY           = 0x06,
>
> The property descriptors are used to pass named properties
> to the device drivers through the Unified device property interface
> under linux/property.h , so that device drivers using the
> device_property_read_* call can get the named properties,
> the mikrobus driver fetches the information from the manifest
> binary and forms a corresponding `struct property_entry` which
> will be attached to the `struct device`.
> The property descriptor is a variable-length descriptor similar
> to the string descriptor and there can be multiple instances of
> property descriptor per add-on board manifest.
>
> > +       GREYBUS_TYPE_DEVICE             = 0x07,
>
> The device descriptor is used to describe a device on the
> mikrobus port and has necessary fields from `struct i2c_board_info`
> and `struct spi_board_info` to describe a device on these buses
> in a mikrobus port, even though  SPI/I2C device info structs are used
> this descriptor has enough information to describe other kinds of
> devices relevant to mikrobus as well.(serdev/platform devices).
> The device descriptor is a fixed-length descriptor and there can be
> multiple instances of device descriptors in an add-on board manifest
> in cases where the add-on board presents more than one device
> to the host.
>
> >  };
> >
> >  enum greybus_protocol {
> > @@ -151,6 +154,47 @@ struct greybus_descriptor_cport {
> >         __u8    protocol_id;    /* enum greybus_protocol */
> >  } __packed;
> >
> > +/*
> > + * A mikrobus descriptor is used to describe the details
> > + * about the bus ocnfiguration for the add-on board
> > + * connected to the mikrobus port.
> > + */
> > +struct greybus_descriptor_mikrobus {
> > +       __u8 pin_state[12];
> > +} __packed;
> > +
>
> These 12 u8 fields describe the state of the pins in the
> mikrobus port(in clock wise order starting from the PWM
> pin)
> mikrobus v2 standard specification :
> https://download.mikroe.com/documents/standards/mikrobus/mikrobus-standard-specification-v200.pdf
> This struct is filled from the mikrobus-descriptor
> in the manifest and can have one of the values
> for each pin group:
> MIKROBUS_STATE_INPUT = 0x01,
> MIKROBUS_STATE_OUTPUT_HIGH = 0x02,
> MIKROBUS_STATE_OUTPUT_LOW = 0x03,
> MIKROBUS_STATE_PWM = 0x04,  ( applicable only to  PWM pin)
> MIKROBUS_STATE_SPI = 0x05, ( applicable only to
> the group of MOSI, MISO, SCK , CS pins on mikroBUS port)
> MIKROBUS_STATE_I2C = 0x06, (applicable only to the SCL, SDA
> pins on the mikrobus port)
> MIKROBUS_STATE_UART = 0x07,(applicable only to the RX, TX
> pins on the mikrobus port)
> There are two purposes for adding this descriptor,
> 1) for some add-on boards some of the pins might need to
> be configured as GPIOs deviating from their reserved purposes
> An example for this case is an SHT15 Click (https://www.mikroe.com/sht1x-click),
> where the SCL and SDA Pins need to be configured as GPIOs
> for the driver (drivers/hwmon/sht15.c) to work. The mikrobus
> descriptor for this case would look like this :
> [mikrobus-descriptor]
> pwm-state = 4 (default, pwm)
> int-state = 1 (default, input)
> rx-state = 7 (default, uart)
> tx-state = 7 (default, uart)
> scl-state = 3 (note the SCL Pin configured as GPIO)
> sda-state = 3 (note the SCL Pin configured as GPIO)
> mosi-state = 5 (default, spi)
> miso-state = 5 (default, spi)
> sck-state = 5 (default, spi)
> cs-state = 5 (default, spi)
> rst-state = 2 (default, GPIO)
> an-state = 1 (default, input)
> 2) for some add-on boards the driver may not take care
> of some additional signals like reset/wake-up/other thus
> the mikrobus driver can set-up these GPIOs to a required
> default state from the information from the manifest, a good
> example for this is the  ENC28J60 click (https://www.mikroe.com/eth-click)
> where the reset line(RST pin on the mikrobus port) needs to be
> pulled high. The manifest example for this add-on board can
> be found here :
> https://github.com/vaishnav98/manifesto/blob/mikrobusv3/manifests/ETH-CLICK.mnfs
>
> > +/*
> > + * A property descriptor is used to pass named properties
> > + * to device drivers through the unified device properties
> > + * interface under linux/property.h
> > + */
> > +struct greybus_descriptor_property {
> > +       __u8 length;
> > +       __u8 id;
> > +       __u8 propname_stringid;
> > +       __u8 type;
> > +       __u8 value[0];
> > +} __packed;
> > +
>
> This descriptor is used to fill in `struct property_entry`
> (linux/property.h), the propname_stringid
> field is used to map to the corresponding string descriptor
> which has the property name, the type field has the types
> under dev_prop_type (linux/property.h) and there are
> some new types which are used within the mikrobus
> driver, these are the new types :
> MIKROBUS_PROPERTY_TYPE_LINK = 0x01
> MIKROBUS_PROPERTY_TYPE_GPIO = 0x02
>
> The property-link type is used to attach an array of properties
> to the corresponding device, for example, consider an SPI
> EEPROM device which works with the AT25 driver(
> drivers/misc/eeprom/at25.c), The device and property
> descriptor parts of the manifest will look like this.
>
> [device-descriptor 1]
> driver-string-id = 3
> prop-link = 1 (The ID of the property-descriptor which
> contains the list of IDs of the actual properties to attach with
> the device)
> protocol = 0xb
> reg = 0
> mode = 0x3
> max-speed-hz = 5000000
> [string-descriptor 3]
> string = at25 (driver string)
>
> [property-descriptor 1]
> name-string-id = 4
> type = 0x01 (type is property-link)
> value = <2 3 4>(attach properties with id 2,3,4 to the device)
> [string-descriptor 4]
> string = prop-link
>
> [property-descriptor 2]
> name-string-id = 5 (string id for the property name string)
> type = 0x05 (U32, driver uses device_property_read_u32 call
> to read the value)
> value = <262144>
> [string-descriptor 5]
> string = size (property name string)
>
> [property-descriptor 3]
> name-string-id = 6
> type = 0x05
> value = <256>
> [string-descriptor 6]
> string = pagesize
>
> [property-descriptor 4]
> name-string-id = 7
> type = 0x05
> value = <24>
> [string-descriptor 7]
> string = address-width
>
> The gpio-link type is very similar to property descriptor and is used to
> pass an array of named gpios to the device driver through GPIO lookup tables,
> consider an example for a SHT15 device (drivers/hwmon/sht15.c),
> the device and the property(gpio) descriptors are as follows :
>
> [device-descriptor 1]
> driver-string-id = 3
> protocol = 0xfe
> reg = 0
> gpio-link = 1 (The ID of the property-descriptor which
> contains the list of IDs of the named gpio properties to attach with
> the device)
>
> [string-descriptor 3]
> string = sht11 (device_id string)
>
> [property-descriptor 1]
> name-string-id = 4
> type = 0x02 (gpio-link)
> value = <2 3> (attach properties with id 2,3 as named gpios to the device)
> [string-descriptor 4]
> string = gpio-link
>
> [property-descriptor 2]
> name-string-id = 5
> type = 0x03
> value = <4>
> [string-descriptor 5]
> string = clk (name of the GPIO, the driver uses
> devm_gpiod_get or similar calls to get the GPIO)
>
> [property-descriptor 3]
> name-string-id = 6
> type = 0x03
> value = <5>
> [string-descriptor 6]
> string = data
>
> Note that the values here 4 and 5 for the GPIOs are
> the offset numbers(clockwise starting from PWM pin)
> within a mikrobus port, the mikrobus drivers translates this
> offset information to the actual GPIO while creating the GPIO
> lookup table, this ensures that the manifest doesn't have any
> port-specific information and a single manifest can be used for
> an add-on board over different platforms/sockets.
>
> > +/*
> > + * A device descriptor is used to describe the
> > + * details required by a add-on board device
> > + * driver.
> > + */
> > +struct greybus_descriptor_device {
> > +       __u8 id;
> > +       __u8 driver_stringid;
> > +       __u8 protocol;
> > +       __u8 reg;
> > +       __le32 max_speed_hz;
> > +       __u8 irq;
> > +       __u8 irq_type;
> > +       __u8 mode;
> > +       __u8 prop_link;
> > +       __u8 gpio_link;
> > +       __u8 pad[3];
> > +} __packed;
> > +
>
> The device descriptor is used to describe a device on the
> mikrobus port and has necessary fields from `struct i2c_board_info`
> and `struct spi_board_info`, of these fields, the irq field is similar to
> the gpio descriptor value above in that the value under irq is also
> the pin offset within the mikrobus port which will be translated to the
> actual GPIO within the mikrobus driver and the irq-type takes types
> defined under linux/interrupt.h . For a device with a
> IRQF_TRIGGER_RISING interrupt on the INT pin on the mikrobus port
> the fields will be :
> irq = 1 (offset of INT pin)
> irq_type = 1 ( IRQF_TRIGGER_RISING)
>
> >  struct greybus_descriptor_header {
> >         __le16  size;
> >         __u8    type;           /* enum greybus_descriptor_type */
> > @@ -164,6 +208,9 @@ struct greybus_descriptor {
> >                 struct greybus_descriptor_interface     interface;
> >                 struct greybus_descriptor_bundle        bundle;
> >                 struct greybus_descriptor_cport         cport;
> > +               struct greybus_descriptor_mikrobus      mikrobus;
> > +               struct greybus_descriptor_property      property;
> > +               struct greybus_descriptor_device        device;
> >         };
> >  } __packed;
> >
> > --
> > 2.25.1
> >
> Thanks and Regards,
> Vaishnav

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

* Re: [RFC PATCH v2 1/3] add mikrobus descriptors to greybus_manifest
  2020-08-31  6:26     ` Zoran Stojsavljevic
@ 2020-09-01  8:33       ` Vaishnav M A
  0 siblings, 0 replies; 16+ messages in thread
From: Vaishnav M A @ 2020-09-01  8:33 UTC (permalink / raw)
  To: Zoran Stojsavljevic
  Cc: greybus-dev, linux-kernel, Greg KH, arnd, johan, elder,
	Rob Herring, mchehab+huawei, davem, Jason Kridner, Drew Fustini,
	Robert Nelson, Ivan Rajković,
	chrisfriedt, Frank Rowand, devicetree

Hi Zoran,

Thank you for your review,
On Mon, Aug 31, 2020 at 11:56 AM Zoran Stojsavljevic
<zoran.stojsavljevic@gmail.com> wrote:
>
> Hello Vaishnav,
>
> I should say, an excellent work on the greybus_manifest.h file.
>
> Actually, my thoughts will be to have a two-stage commit of the whole
> MikroBUS patch.
>
> The first one are these changes with greybus_manifest.h, followed by
> dependent mikrobus_core.h and mikrobus_manifest.h.
>
> These two should have included #include
> <linux/greybus/greybus_manifest.h> to reflect the correct hierarchical
> structure.
>
> The rest is with the mikrobus driver .c code.
>
> It is just an observation from me, I guess, it is obvious.
>
Sure, we can split up the mikrobus driver patch into two parts and
still ensure that each patch builds without errors, will fix this in the
next version.
> My two cent worth comment,
> Zoran
> _______
>
> On Thu, Aug 20, 2020 at 2:49 AM Vaishnav M A <vaishnav@beagleboard.org> wrote:
> >
> > Hi,
> >
> > Trying to add more information regarding the newly added
> > descriptors and describe how they are used now within the
> > mikroBUS driver.
> >
> > On Tue, Aug 18, 2020 at 6:18 PM Vaishnav M A <vaishnav@beagleboard.org> wrote:
> > >
> > > This patch adds new descriptors used in the manifest parsing inside
> > > the mikrobus driver, the device descriptor help to describe the
> > > devices on a mikroBUS port, mikrobus descriptor is used to set up
> > > the mikrobus port pinmux and GPIO states and property descriptor
> > > to pass named properties to device drivers through the Unified
> > > Properties API under linux/property.h
> > >
> > > The corresponding pull request for manifesto is updated
> > > at : https://github.com/projectara/manifesto/pull/2
> > >
> > > Signed-off-by: Vaishnav M A <vaishnav@beagleboard.org>
> > > ---
> > >  include/linux/greybus/greybus_manifest.h | 47 ++++++++++++++++++++++++
> > >  1 file changed, 47 insertions(+)
> > >
> > > diff --git a/include/linux/greybus/greybus_manifest.h b/include/linux/greybus/greybus_manifest.h
> > > index 6e62fe478712..821661ea7f01 100644
> > > --- a/include/linux/greybus/greybus_manifest.h
> > > +++ b/include/linux/greybus/greybus_manifest.h
> > > @@ -23,6 +23,9 @@ enum greybus_descriptor_type {
> > >         GREYBUS_TYPE_STRING             = 0x02,
> > >         GREYBUS_TYPE_BUNDLE             = 0x03,
> > >         GREYBUS_TYPE_CPORT              = 0x04,
> > > +       GREYBUS_TYPE_MIKROBUS           = 0x05,
> >
> > The mikrobus descriptor is used to pass information about
> > the specific pinmux settings and the default GPIO states on
> > the mikrobus port to be set up for the add-on board to work
> > correctly, this descriptor has 12 u8 fields(corresponding  to the
> > 12 pins on the mikrobus port) which includes information
> > about the prior setup required on the mikroBUS port for the
> > device(s) on the add-on board to work correctly. The mikrobus
> > descriptor is a fixed-length descriptor and there will be only a
> > single instance of mikrobus descriptor per add-on board manifest.
> >
> > > +       GREYBUS_TYPE_PROPERTY           = 0x06,
> >
> > The property descriptors are used to pass named properties
> > to the device drivers through the Unified device property interface
> > under linux/property.h , so that device drivers using the
> > device_property_read_* call can get the named properties,
> > the mikrobus driver fetches the information from the manifest
> > binary and forms a corresponding `struct property_entry` which
> > will be attached to the `struct device`.
> > The property descriptor is a variable-length descriptor similar
> > to the string descriptor and there can be multiple instances of
> > property descriptor per add-on board manifest.
> >
> > > +       GREYBUS_TYPE_DEVICE             = 0x07,
> >
> > The device descriptor is used to describe a device on the
> > mikrobus port and has necessary fields from `struct i2c_board_info`
> > and `struct spi_board_info` to describe a device on these buses
> > in a mikrobus port, even though  SPI/I2C device info structs are used
> > this descriptor has enough information to describe other kinds of
> > devices relevant to mikrobus as well.(serdev/platform devices).
> > The device descriptor is a fixed-length descriptor and there can be
> > multiple instances of device descriptors in an add-on board manifest
> > in cases where the add-on board presents more than one device
> > to the host.
> >
> > >  };
> > >
> > >  enum greybus_protocol {
> > > @@ -151,6 +154,47 @@ struct greybus_descriptor_cport {
> > >         __u8    protocol_id;    /* enum greybus_protocol */
> > >  } __packed;
> > >
> > > +/*
> > > + * A mikrobus descriptor is used to describe the details
> > > + * about the bus ocnfiguration for the add-on board
> > > + * connected to the mikrobus port.
> > > + */
> > > +struct greybus_descriptor_mikrobus {
> > > +       __u8 pin_state[12];
> > > +} __packed;
> > > +
> >
> > These 12 u8 fields describe the state of the pins in the
> > mikrobus port(in clock wise order starting from the PWM
> > pin)
> > mikrobus v2 standard specification :
> > https://download.mikroe.com/documents/standards/mikrobus/mikrobus-standard-specification-v200.pdf
> > This struct is filled from the mikrobus-descriptor
> > in the manifest and can have one of the values
> > for each pin group:
> > MIKROBUS_STATE_INPUT = 0x01,
> > MIKROBUS_STATE_OUTPUT_HIGH = 0x02,
> > MIKROBUS_STATE_OUTPUT_LOW = 0x03,
> > MIKROBUS_STATE_PWM = 0x04,  ( applicable only to  PWM pin)
> > MIKROBUS_STATE_SPI = 0x05, ( applicable only to
> > the group of MOSI, MISO, SCK , CS pins on mikroBUS port)
> > MIKROBUS_STATE_I2C = 0x06, (applicable only to the SCL, SDA
> > pins on the mikrobus port)
> > MIKROBUS_STATE_UART = 0x07,(applicable only to the RX, TX
> > pins on the mikrobus port)
> > There are two purposes for adding this descriptor,
> > 1) for some add-on boards some of the pins might need to
> > be configured as GPIOs deviating from their reserved purposes
> > An example for this case is an SHT15 Click (https://www.mikroe.com/sht1x-click),
> > where the SCL and SDA Pins need to be configured as GPIOs
> > for the driver (drivers/hwmon/sht15.c) to work. The mikrobus
> > descriptor for this case would look like this :
> > [mikrobus-descriptor]
> > pwm-state = 4 (default, pwm)
> > int-state = 1 (default, input)
> > rx-state = 7 (default, uart)
> > tx-state = 7 (default, uart)
> > scl-state = 3 (note the SCL Pin configured as GPIO)
> > sda-state = 3 (note the SCL Pin configured as GPIO)
> > mosi-state = 5 (default, spi)
> > miso-state = 5 (default, spi)
> > sck-state = 5 (default, spi)
> > cs-state = 5 (default, spi)
> > rst-state = 2 (default, GPIO)
> > an-state = 1 (default, input)
> > 2) for some add-on boards the driver may not take care
> > of some additional signals like reset/wake-up/other thus
> > the mikrobus driver can set-up these GPIOs to a required
> > default state from the information from the manifest, a good
> > example for this is the  ENC28J60 click (https://www.mikroe.com/eth-click)
> > where the reset line(RST pin on the mikrobus port) needs to be
> > pulled high. The manifest example for this add-on board can
> > be found here :
> > https://github.com/vaishnav98/manifesto/blob/mikrobusv3/manifests/ETH-CLICK.mnfs
> >
> > > +/*
> > > + * A property descriptor is used to pass named properties
> > > + * to device drivers through the unified device properties
> > > + * interface under linux/property.h
> > > + */
> > > +struct greybus_descriptor_property {
> > > +       __u8 length;
> > > +       __u8 id;
> > > +       __u8 propname_stringid;
> > > +       __u8 type;
> > > +       __u8 value[0];
> > > +} __packed;
> > > +
> >
> > This descriptor is used to fill in `struct property_entry`
> > (linux/property.h), the propname_stringid
> > field is used to map to the corresponding string descriptor
> > which has the property name, the type field has the types
> > under dev_prop_type (linux/property.h) and there are
> > some new types which are used within the mikrobus
> > driver, these are the new types :
> > MIKROBUS_PROPERTY_TYPE_LINK = 0x01
> > MIKROBUS_PROPERTY_TYPE_GPIO = 0x02
> >
> > The property-link type is used to attach an array of properties
> > to the corresponding device, for example, consider an SPI
> > EEPROM device which works with the AT25 driver(
> > drivers/misc/eeprom/at25.c), The device and property
> > descriptor parts of the manifest will look like this.
> >
> > [device-descriptor 1]
> > driver-string-id = 3
> > prop-link = 1 (The ID of the property-descriptor which
> > contains the list of IDs of the actual properties to attach with
> > the device)
> > protocol = 0xb
> > reg = 0
> > mode = 0x3
> > max-speed-hz = 5000000
> > [string-descriptor 3]
> > string = at25 (driver string)
> >
> > [property-descriptor 1]
> > name-string-id = 4
> > type = 0x01 (type is property-link)
> > value = <2 3 4>(attach properties with id 2,3,4 to the device)
> > [string-descriptor 4]
> > string = prop-link
> >
> > [property-descriptor 2]
> > name-string-id = 5 (string id for the property name string)
> > type = 0x05 (U32, driver uses device_property_read_u32 call
> > to read the value)
> > value = <262144>
> > [string-descriptor 5]
> > string = size (property name string)
> >
> > [property-descriptor 3]
> > name-string-id = 6
> > type = 0x05
> > value = <256>
> > [string-descriptor 6]
> > string = pagesize
> >
> > [property-descriptor 4]
> > name-string-id = 7
> > type = 0x05
> > value = <24>
> > [string-descriptor 7]
> > string = address-width
> >
> > The gpio-link type is very similar to property descriptor and is used to
> > pass an array of named gpios to the device driver through GPIO lookup tables,
> > consider an example for a SHT15 device (drivers/hwmon/sht15.c),
> > the device and the property(gpio) descriptors are as follows :
> >
> > [device-descriptor 1]
> > driver-string-id = 3
> > protocol = 0xfe
> > reg = 0
> > gpio-link = 1 (The ID of the property-descriptor which
> > contains the list of IDs of the named gpio properties to attach with
> > the device)
> >
> > [string-descriptor 3]
> > string = sht11 (device_id string)
> >
> > [property-descriptor 1]
> > name-string-id = 4
> > type = 0x02 (gpio-link)
> > value = <2 3> (attach properties with id 2,3 as named gpios to the device)
> > [string-descriptor 4]
> > string = gpio-link
> >
> > [property-descriptor 2]
> > name-string-id = 5
> > type = 0x03
> > value = <4>
> > [string-descriptor 5]
> > string = clk (name of the GPIO, the driver uses
> > devm_gpiod_get or similar calls to get the GPIO)
> >
> > [property-descriptor 3]
> > name-string-id = 6
> > type = 0x03
> > value = <5>
> > [string-descriptor 6]
> > string = data
> >
> > Note that the values here 4 and 5 for the GPIOs are
> > the offset numbers(clockwise starting from PWM pin)
> > within a mikrobus port, the mikrobus drivers translates this
> > offset information to the actual GPIO while creating the GPIO
> > lookup table, this ensures that the manifest doesn't have any
> > port-specific information and a single manifest can be used for
> > an add-on board over different platforms/sockets.
> >
> > > +/*
> > > + * A device descriptor is used to describe the
> > > + * details required by a add-on board device
> > > + * driver.
> > > + */
> > > +struct greybus_descriptor_device {
> > > +       __u8 id;
> > > +       __u8 driver_stringid;
> > > +       __u8 protocol;
> > > +       __u8 reg;
> > > +       __le32 max_speed_hz;
> > > +       __u8 irq;
> > > +       __u8 irq_type;
> > > +       __u8 mode;
> > > +       __u8 prop_link;
> > > +       __u8 gpio_link;
> > > +       __u8 pad[3];
> > > +} __packed;
> > > +
> >
> > The device descriptor is used to describe a device on the
> > mikrobus port and has necessary fields from `struct i2c_board_info`
> > and `struct spi_board_info`, of these fields, the irq field is similar to
> > the gpio descriptor value above in that the value under irq is also
> > the pin offset within the mikrobus port which will be translated to the
> > actual GPIO within the mikrobus driver and the irq-type takes types
> > defined under linux/interrupt.h . For a device with a
> > IRQF_TRIGGER_RISING interrupt on the INT pin on the mikrobus port
> > the fields will be :
> > irq = 1 (offset of INT pin)
> > irq_type = 1 ( IRQF_TRIGGER_RISING)
> >
> > >  struct greybus_descriptor_header {
> > >         __le16  size;
> > >         __u8    type;           /* enum greybus_descriptor_type */
> > > @@ -164,6 +208,9 @@ struct greybus_descriptor {
> > >                 struct greybus_descriptor_interface     interface;
> > >                 struct greybus_descriptor_bundle        bundle;
> > >                 struct greybus_descriptor_cport         cport;
> > > +               struct greybus_descriptor_mikrobus      mikrobus;
> > > +               struct greybus_descriptor_property      property;
> > > +               struct greybus_descriptor_device        device;
> > >         };
> > >  } __packed;
> > >
> > > --
> > > 2.25.1
> > >
> > Thanks and Regards,
> > Vaishnav
Thanks and Regards,
Vaishnav

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

end of thread, other threads:[~2020-09-01  8:34 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-18 12:48 [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Vaishnav M A
2020-08-18 12:48 ` [RFC PATCH v2 1/3] add mikrobus descriptors to greybus_manifest Vaishnav M A
2020-08-20  0:49   ` Vaishnav M A
2020-08-31  6:26     ` Zoran Stojsavljevic
2020-09-01  8:33       ` Vaishnav M A
2020-08-18 12:48 ` [RFC PATCH v2 2/3] mikroBUS driver for add-on boards on mikrobus ports Vaishnav M A
2020-08-18 12:48 ` [RFC PATCH v2 3/3] Add Device Tree Bindings for mikroBUS port Vaishnav M A
2020-08-18 13:35   ` [greybus-dev] " Laurent Pinchart
2020-08-18 21:22     ` Vaishnav M A
2020-08-27 15:45   ` Rob Herring
2020-08-18 15:24 ` [RFC PATCH v2 0/3] mikroBUS driver for add-on boards Greg KH
2020-08-18 21:52   ` Vaishnav M A
2020-08-19  5:54     ` Greg KH
2020-08-18 20:38 ` Frank Rowand
2020-08-18 21:56   ` Vaishnav M A
2020-08-25  1:44   ` Frank Rowand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).