[PATCH linux v1 4/8] drivers: fsi: Add i2c client driver

eajames at linux.vnet.ibm.com eajames at linux.vnet.ibm.com
Fri Feb 3 10:25:57 AEDT 2017


From: "Edward A. James" <eajames at us.ibm.com>

stub for I2C driver over FSI

Signed-off-by: Edward A. James <eajames at us.ibm.com>
---
 drivers/fsi/Kconfig       |   6 ++
 drivers/fsi/Makefile      |   1 +
 drivers/fsi/i2c/Makefile  |   1 +
 drivers/fsi/i2c/iic-fsi.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/fsi/i2c/iic-fsi.h |  29 ++++++++
 drivers/fsi/i2c/iic-int.h |  80 ++++++++++++++++++++++
 6 files changed, 283 insertions(+)
 create mode 100644 drivers/fsi/i2c/Makefile
 create mode 100644 drivers/fsi/i2c/iic-fsi.c
 create mode 100644 drivers/fsi/i2c/iic-fsi.h
 create mode 100644 drivers/fsi/i2c/iic-int.h

diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
index 0fa265c..c78b9b6e 100644
--- a/drivers/fsi/Kconfig
+++ b/drivers/fsi/Kconfig
@@ -24,6 +24,12 @@ config FSI_SCOM
 	---help---
 	This option enables an FSI based SCOM device driver.
 
+config FSI_I2C
+	tristate "I2C FSI client device driver"
+	depends on FSI
+	---help---
+	This option enables an FSI based I2C device driver.
+
 endif
 
 endmenu
diff --git a/drivers/fsi/Makefile b/drivers/fsi/Makefile
index 3466f08..3a106ba 100644
--- a/drivers/fsi/Makefile
+++ b/drivers/fsi/Makefile
@@ -2,3 +2,4 @@
 obj-$(CONFIG_FSI) += fsi-core.o
 obj-$(CONFIG_FSI_MASTER_GPIO) += fsi-master-gpio.o
 obj-$(CONFIG_FSI_SCOM) += fsi-scom.o
+obj-$(CONFIG_FSI_I2C) += i2c/
diff --git a/drivers/fsi/i2c/Makefile b/drivers/fsi/i2c/Makefile
new file mode 100644
index 0000000..f9f9048
--- /dev/null
+++ b/drivers/fsi/i2c/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FSI_I2C) += iic-fsi.o
diff --git a/drivers/fsi/i2c/iic-fsi.c b/drivers/fsi/i2c/iic-fsi.c
new file mode 100644
index 0000000..51a15a4
--- /dev/null
+++ b/drivers/fsi/i2c/iic-fsi.c
@@ -0,0 +1,166 @@
+/*
+ *   Copyright (c) International Business Machines Corp., 2006, 2010, 2012
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * This file contains the architecture independent IIC FSI code.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fsi.h>
+#include <asm/io.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include "iic-int.h"
+#include "iic-fsi.h"
+
+#include <linux/delay.h>
+#include <linux/moduleparam.h>
+
+struct class* iic_fsi_class = 0;
+dev_t iic_devnum_start = 0;
+
+static const char iic_fsi_version[] = "3.0";
+
+int iic_fsi_probe(struct device *dev);
+int iic_fsi_remove(struct device *dev);
+
+struct iic_reg_access fsi_reg_access =
+{
+	.bus_readb = readb_wrap,
+	.bus_readh = readh_wrap,
+	.bus_readw = readw_wrap,
+	.bus_writeb = writeb_wrap,
+	.bus_writeh = writeh_wrap,
+	.bus_writew = writew_wrap,
+};
+
+static const struct fsi_device_id i2c_ids[] = {
+	{
+		.engine_type = FSI_ENGID_I2C,
+		.version = FSI_VERSION_ANY,
+	},
+	{
+		.engine_type = FSI_ENGID_I2C_BB,
+		.version = FSI_VERSION_ANY,
+	},
+	{ 0 }
+};
+
+static const struct fsi_driver i2c_drv = {
+	.id_table = i2c_ids,
+	.drv = {
+		.name = "iic_fsi_dd",
+		.bus = &fsi_bus_type,
+		.probe = iic_fsi_probe,
+		.remove = iic_fsi_remove,
+	}
+};
+
+/*
+ * Called when an FSI IIC engine is plugged in.  
+ * Causes creation of the /dev entry.
+ * Not allowed to access engine registers in this function.
+ *
+ */
+int iic_fsi_probe(struct device *dev)
+{
+	return 0;
+}
+
+/* This function is called when a link is removed or the driver is unloaded.
+ * It's job is to remove the device from the device hierarchy including 
+ * removal from sysfs (this is where device files get removed).
+ */
+int iic_fsi_remove(struct device* dev)
+{
+	return 0;
+}
+
+/*
+ * Initialize this module.  Creates a class for fsi connected iic devices and
+ * allocates device numbers for them.
+ */
+static int __init iic_fsi_init(void)
+{
+	int rc = 0;
+
+	IENTER();
+
+	rc = alloc_chrdev_region(&iic_devnum_start,
+			0, /*starting minor number*/
+			IIC_FSI_MAX_DEVS,
+			"iic-fsi");
+	if(rc)
+	{
+		 IFLDe(1, "master alloc_chrdev_region failed: rc = %d\n", rc);
+		 return rc;
+	}
+
+	iic_fsi_class = class_create(THIS_MODULE, "iic-fsi");
+	if (IS_ERR(iic_fsi_class))
+	{
+		IFLDe(1, "class_create failed: rc=%ld", 
+				PTR_ERR(iic_fsi_class));
+		goto exit_class_create;
+	}
+	/* Register this driver with the FSI infrastructure */
+	rc = fsi_driver_register(&i2c_drv);
+	if(rc)
+	{
+		IFLDe(1, "fsidrv_register failed: %d", rc);
+		goto exit_drv_register;
+	}
+
+	printk("IIC FSI support loaded, ver. %s\n", iic_fsi_version);
+
+	IEXIT(rc);
+	return rc;
+
+exit_drv_register:
+	class_destroy(iic_fsi_class);
+exit_class_create:
+	unregister_chrdev_region(iic_devnum_start, IIC_FSI_MAX_DEVS);
+	IEXIT(rc);
+	return rc;
+}
+
+static void __exit iic_fsi_exit(void)
+{
+	IENTER();
+	IDBGd(0, "fisdrv_unregister()\n");
+	fsi_driver_unregister(&i2c_drv);
+	IDBGd(0, "unregister_chrdev_region()\n");
+	unregister_chrdev_region(iic_devnum_start, IIC_FSI_MAX_DEVS);
+	if(iic_fsi_class)
+	{
+		IDBGd(0, "class_destroy\n");
+		class_destroy(iic_fsi_class);
+	}
+	printk("IIC FSI support unloaded.\n");
+	IEXIT(0);
+}
+
+module_init(iic_fsi_init);
+module_exit(iic_fsi_exit);
+
+MODULE_AUTHOR("Eddie James <eajames at us.ibm.com>");
+MODULE_DESCRIPTION("IIC FSI Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/fsi/i2c/iic-fsi.h b/drivers/fsi/i2c/iic-fsi.h
new file mode 100644
index 0000000..4decb2c
--- /dev/null
+++ b/drivers/fsi/i2c/iic-fsi.h
@@ -0,0 +1,29 @@
+/*
+ *   Copyright (c) International Business Machines Corp., 2006
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef IIC_FSI_H
+#define IIC_FSI_H
+
+/*
+ * we don't know ahead of time how many minors will be needed as this is based 
+ * on platform type and the possibility of sparsely populated FRU's on special 
+ * systems so picking a safely large number
+ */
+#define IIC_FSI_MAX_DEVS	1024
+
+#endif
diff --git a/drivers/fsi/i2c/iic-int.h b/drivers/fsi/i2c/iic-int.h
new file mode 100644
index 0000000..545b2c3
--- /dev/null
+++ b/drivers/fsi/i2c/iic-int.h
@@ -0,0 +1,80 @@
+/*
+ *   Copyright (c) International Business Machines Corp., 2006, 2012
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef IIC_INT_H
+#define IIC_INT_H
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/fs.h>
+#include <linux/kobject.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/kdev_t.h>
+#include <linux/wait.h>
+#include <linux/i2cfsi.h>
+#include <linux/semaphore.h>
+#include <linux/fsi.h>
+#include <asm/atomic.h>
+
+#define FSI_ENGID_I2C		0x7
+#define FSI_ENGID_I2C_BB	0x17
+
+#ifdef FSI_I2C_DEBUG
+#define IDBGs(num, msg, args...) printk(msg, ## args)
+#define IDBGd(num, msg, args...) printk(msg, ## args)
+#define IDBGf(num, msg, args...) printk(msg, ## args)
+#define IDBGl(num, msg, args...) printk(msg, ## args)
+#else
+#define IDBGs(num, msg, args...)
+#define IDBGd(num, msg, args...)
+#define IDBGf(num, msg, args...)
+#define IDBGl(num, msg, args...)
+#endif
+
+#define IENTER()
+#define IEXIT(RC)
+
+/* IFLDx traces will not get compiled out */
+#define IFLDe(num, msg, args...)\
+	printk("ERR: "msg, ## args)
+#define IFLDi(num, msg, args...)\
+	printk(msg, ## args)
+
+#ifdef FSI_I2C_DEBUG
+#define IFLDs(num, msg, args...) printk(msg, ## args)
+#define IFLDd(num, msg, args...) printk(msg, ## args)
+#define IFLDf(num, msg, args...) printk(msg, ## args)
+#define IFLDl(num, msg, args...) printk(msg, ## args)
+#else
+#define IFLDs(num, msg, args...)
+#define IFLDd(num, msg, args...)
+#define IFLDf(num, msg, args...)
+#define IFLDl(num, msg, args...)
+#endif
+
+struct iic_reg_access
+{
+    int (*bus_readb)(iic_eng_t*, unsigned int, unsigned char*, iic_ffdc_t**);
+    int (*bus_readh)(iic_eng_t*, unsigned int, unsigned short*, iic_ffdc_t**);
+    int (*bus_readw)(iic_eng_t*, unsigned int, unsigned long*, iic_ffdc_t**);
+    int (*bus_writeb)(iic_eng_t*, unsigned int, unsigned char, iic_ffdc_t**);
+    int (*bus_writeh)(iic_eng_t*, unsigned int, unsigned short, iic_ffdc_t**);
+    int (*bus_writew)(iic_eng_t*, unsigned int, unsigned long, iic_ffdc_t**);
+};
+
+#endif
-- 
1.8.3.1



More information about the openbmc mailing list