BAL and Maple Release 2.2
Signed-off-by: Shad Ansari <developer@Carbon.local>
diff --git a/bcm68620_release/release/host_customized/i2c/Makefile b/bcm68620_release/release/host_customized/i2c/Makefile
new file mode 100644
index 0000000..333c2db
--- /dev/null
+++ b/bcm68620_release/release/host_customized/i2c/Makefile
@@ -0,0 +1,19 @@
+# I2C devices driver
+#
+ifeq ("$(OS_KERNEL)", "linux")
+
+MOD_NAME = i2c_devs
+MOD_TYPE = linux_module
+
+srcs = bcmolt_i2c_devs.c
+
+# If called by linux kernel builder - add include paths manually.
+# It is not elegant, but we'll not have many linux modules
+ifneq ("$(KBUILD_SRC)", "")
+ -include $(OUT_DIR_BASE)/Makefile.config.$(MOD_NAME)
+endif
+
+endif
+
+USE_LINT = yes
+
diff --git a/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs.c b/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs.c
new file mode 100644
index 0000000..48e9ec4
--- /dev/null
+++ b/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs.c
@@ -0,0 +1,1038 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/cdev.h>
+#include <asm/uaccess.h> /*copy_from_user*/
+#include <linux/proc_fs.h>
+#include "bcmos_system.h"
+#include "bcmolt_i2c_devs.h"
+#include "bcmolt_i2c_devs_ioctl.h"
+
+#define BCM_I2C_DEV_ADDR_START typedef enum {
+#define BCM_I2C_DEV_ADDR(name, desc, val) name = val,
+#define BCM_I2C_DEV_ADDR_END } bcm_i2c_dev_addr;
+
+#include "bcmolt_i2c_devs_addr.h"
+
+#define PROC_DIR_NAME "maple_i2c"
+#define PROC_ENTRY_NAME "i2c"
+#define MAX_EAGAIN_ITERS 200 /* 10ms per iter */
+
+/* uncomment the next line to enable debug output to the kernel CLI */
+/* #define I2C_DEBUG_PRINTS 1 */
+#ifdef I2C_DEBUG_PRINTS
+#define i2c_debug_print(fmt, args...) printk("%s#%d: " fmt, __FUNCTION__, __LINE__, ## args)
+#else
+#define i2c_debug_print(...)
+#endif
+
+int maple_i2c_chrdev_major = 216;
+module_param(maple_i2c_chrdev_major, int, S_IRUSR | S_IRGRP | S_IWGRP);
+MODULE_PARM_DESC(maple_i2c_chrdev_major, "maple_i2c_major");
+
+static struct proc_dir_entry *i2c_proc_dir;
+static struct proc_dir_entry *i2c_proc_entry;
+static char is_chrdev_reg;
+static char is_cdev_add;
+static int i2c_client_num;
+static int i2c_num_clients;
+
+const unsigned short normal_i2c[] = {
+ I2C_SW0_I2C_ADDR,
+ I2C_SW1_I2C_ADDR,
+ I2C_SW2_I2C_ADDR,
+ I2C_SW3_I2C_ADDR,
+ I2C_SW4_I2C_ADDR,
+ SFP_I2C_ADDR1,
+ SFP_I2C_ADDR2,
+ FPGA_I2C_ADDR,
+ PON_DPLL_I2C_ADDR,
+ PM_DPLL_I2C_ADDR,
+ CXP_R_I2C_ADDR,
+ PCIE_SW_I2C_ADDR,
+ I2C_CLIENT_END
+};
+
+static unsigned char slave_valid[SLAVE_NUM_OF_SLAVES] = {0};
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static const struct i2c_device_id maple_i2c_id_table[] = {
+ { "maple_i2c", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, maple_i2c_id_table);
+
+static void bcm_access_fpga(void);
+
+/*
+ * Client data (each client gets its own)
+ */
+struct maple_i2c_data {
+ struct i2c_client client;
+};
+
+static struct maple_i2c_data *pclient_data_ar[SLAVE_NUM_OF_SLAVES];
+
+static int get_client(unsigned char client_num, struct i2c_client **client)
+{
+ if ((client_num >= SLAVE_NUM_OF_SLAVES) || !slave_valid[client_num])
+ {
+ i2c_debug_print("I2C error: Wrong client number 0x%x\n", client_num);
+ return -1;
+ }
+ *client = &pclient_data_ar[client_num]->client;
+
+ return 0;
+}
+
+
+/*
+ * Helper functions which attempt I2C transfer until successful, or error code is other than -EAGAIN
+ */
+
+static int maple_i2c_send(unsigned char client_num, u8 *buf, size_t count)
+{
+ struct i2c_client *client;
+ int rc;
+ int niter = 0;
+
+ if (get_client(client_num, &client))
+ return -1;
+
+ do {
+ rc = i2c_master_send(client, buf, count);
+ if (rc == -EAGAIN)
+ msleep(10);
+ } while (rc == -EAGAIN && ++niter < MAX_EAGAIN_ITERS);
+ rc = (rc == count) ? 0 : (rc < 0 ) ? rc : -1;
+
+ return rc;
+}
+
+static int maple_i2c_recv(unsigned char client_num, u8 *buf, size_t count)
+{
+ struct i2c_client *client;
+ int rc;
+ int niter = 0;
+
+ if (get_client(client_num, &client))
+ return -1;
+
+ do {
+ rc = i2c_master_recv(client, buf, count);
+ if (rc == -EAGAIN)
+ msleep(10);
+ } while (rc == -EAGAIN && ++niter < MAX_EAGAIN_ITERS);
+ rc = (rc == count) ? 0 : (rc < 0 ) ? rc : -1;
+
+ return rc;
+}
+
+
+static int maple_i2c_read_with_offset(unsigned char client_num, u8 *offset, size_t offset_size, u8 *buf, size_t count)
+{
+ struct i2c_client *client;
+ struct i2c_msg msg[2];
+ int rc;
+ int niter = 0;
+
+ if (get_client(client_num, &client))
+ return -1;
+
+ msg[0].addr = msg[1].addr = client->addr;
+ msg[0].flags = msg[1].flags = client->flags & I2C_M_TEN;
+
+ msg[0].len = offset_size;
+ msg[0].buf = offset;
+
+ msg[1].flags |= I2C_M_RD;
+ msg[1].len = count;
+ msg[1].buf = buf;
+
+ do {
+ rc = i2c_transfer(client->adapter, msg, 2);
+ if (rc == -EAGAIN)
+ msleep(10);
+ } while (rc == -EAGAIN && ++niter < MAX_EAGAIN_ITERS);
+
+ rc = (rc == 2) ? 0 : (rc < 0 ) ? rc : -1;
+
+ return rc;
+}
+
+ssize_t maple_i2c_write(unsigned char client_num, char *buf, size_t count)
+{
+ int rc;
+
+ i2c_debug_print("Write to switch: client=0x%x val = 0x%x\n", normal_i2c[client_num], *buf);
+ rc = maple_i2c_send(client_num, (u8 *)buf, count);
+
+ if (rc < 0)
+ i2c_debug_print("Write Failed. rc=%d client=%u[%u]\n", rc,
+ normal_i2c[client_num], client_num);
+ else
+ i2c_debug_print("Write Successful client=%u[%u]\n",
+ normal_i2c[client_num], client_num);
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_write);
+
+ssize_t maple_i2c_read(unsigned char client_num, char *buf, size_t count)
+{
+ int rc;
+
+ i2c_debug_print("Read from switch: client 0x%x\n", normal_i2c[client_num]);
+ rc = maple_i2c_recv(client_num, (u8 *)buf, count);
+
+ if (rc < 0)
+ i2c_debug_print("Read Failed. rc=%d client=%u[%u]\n", rc,
+ normal_i2c[client_num], client_num);
+ else
+ i2c_debug_print("Read Successful: count=%u val = 0x%x\n", (unsigned)count, *buf);
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_read);
+
+int maple_i2c_write_byte(unsigned char client_num, unsigned char offset, unsigned char val)
+{
+ u8 buf[2];
+ int rc;
+
+ i2c_debug_print("Write Byte: client=0x%x offset = 0x%x, val = 0x%x\n", normal_i2c[client_num], offset, val);
+
+ buf[0] = offset;
+ buf[1] = val;
+ rc = maple_i2c_send(client_num, buf, 2);
+
+ if (rc < 0)
+ i2c_debug_print("Write Byte Failed. rc=%d offset=0x%x val=0x%x client=%u[%u]\n",
+ rc, offset, val,
+ normal_i2c[client_num], client_num);
+ else
+ i2c_debug_print("Write Byte: offset=0x%x val=0x%x client=%u/%u\n",
+ offset, val,
+ normal_i2c[client_num], client_num);
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_write_byte);
+
+int maple_i2c_read_byte(unsigned char client_num, unsigned char offset, unsigned char *data)
+{
+ u8 o = offset;
+ u8 val;
+ int rc;
+
+ i2c_debug_print("Write Byte: client=0x%x offset = 0x%x, val = 0x%x\n", normal_i2c[client_num], offset, val);
+
+ rc = maple_i2c_read_with_offset(client_num, &o, 1, &val, 1);
+
+ if (rc < 0)
+ i2c_debug_print("Read Byte Failed. rc=%d client=%u[%u]\n", rc,
+ normal_i2c[client_num], client_num);
+ else
+ {
+ *data = val;
+ i2c_debug_print("Read Byte: client=0x%x offset = 0x%x, val = 0x%x\n",
+ normal_i2c[client_num], offset, *data);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_read_byte);
+
+
+int maple_i2c_write_word(unsigned char client_num, unsigned char offset, unsigned short val)
+{
+ u8 buf[3];
+ int rc;
+
+ i2c_debug_print("Write Word: offset = 0x%x, val = 0x%x\n", offset, val);
+
+ /* The offset to be written should be the first byte in the I2C write */
+ buf[0] = offset;
+ buf[1] = (char)(val&0xFF);
+ buf[2] = (char)(val>>8);
+ rc = maple_i2c_send(client_num, buf, sizeof(buf));
+
+ if (rc < 0)
+ i2c_debug_print("Write Word Failed. rc=%d offset=0x%x val=0x%x, client=%u[%u]\n",
+ rc, offset, val,
+ normal_i2c[client_num], client_num);
+ else
+ i2c_debug_print("Write Word: offset=0x%x val=0x%x, client=%u[%u]\n",
+ offset, val,
+ normal_i2c[client_num], client_num);
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_write_word);
+
+int maple_i2c_read_word(unsigned char client_num, unsigned char offset, unsigned short *data)
+{
+ u8 o = offset;
+ u8 buf[2];
+ int rc;
+
+ rc = maple_i2c_read_with_offset(client_num, &o, 1, buf, sizeof(buf));
+
+ if (rc < 0)
+ i2c_debug_print("Read Word Failed. rc=%d offset=0x%x client=%u[%u]\n",
+ rc, offset,
+ normal_i2c[client_num], client_num);
+ else
+ {
+ *data = (buf[1]<<8) | buf[0]; /* I2C data is LE */
+ i2c_debug_print("Read Word: offset = 0x%x, val = 0x%x client=%u[%u]\n",
+ offset, *data,
+ normal_i2c[client_num], client_num);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_read_word);
+
+
+int maple_i2c_write_reg(unsigned char client_num, unsigned char offset, int val)
+{
+ u8 buf[5];
+ int rc;
+
+ i2c_debug_print("Write Register: offset = 0x%x, val = 0x%x\n", offset, val);
+
+ /* Set the buf[0] to be the offset for write operation */
+ buf[0] = offset;
+
+ /* On the I2C bus, LS Byte should go first */
+ buf[1] = val & 0xff;
+ buf[2] = (val >> 8) & 0xff;
+ buf[3] = (val >> 16) & 0xff;
+ buf[4] = (val >> 24) & 0xff;
+ rc = maple_i2c_send(client_num, buf, sizeof(buf));
+
+ if (rc < 0)
+ i2c_debug_print("Write Reg Failed. rc=%d offset=0x%x val=0x%x client=%u[%u]\n",
+ rc, offset, val,
+ normal_i2c[client_num], client_num);
+ else
+ i2c_debug_print("Write Reg Successful. offset=0x%x val=0x%x client=%u[%u]\n",
+ offset, val,
+ normal_i2c[client_num], client_num);
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_write_reg);
+
+
+int maple_i2c_read_reg(unsigned char client_num, unsigned char offset, unsigned int *data)
+{
+ u8 o = offset;
+ u8 buf[4];
+ int rc;
+
+ rc = maple_i2c_read_with_offset(client_num, &o, 1, buf, sizeof(buf));
+
+ if (rc < 0)
+ i2c_debug_print("Read Reg Failed. rc=%d offset=0x%x client=%u[%u]\n",
+ rc, offset,
+ normal_i2c[client_num], client_num);
+ else
+ {
+ *data = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); /* LS byte is transferred first */
+ i2c_debug_print("Read Register: client=0x%x offset = 0x%x, val = 0x%x\n", normal_i2c[client_num], offset, *data);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_read_reg);
+
+
+int maple_i2c_write_fpga(unsigned char client_num, unsigned int offset, unsigned int val)
+{
+ u8 buf[8];
+ int rc;
+
+ bcm_access_fpga();
+
+ i2c_debug_print("Write fpga: offset = 0x%x, val = 0x%x\n", offset, val);
+
+ /* Set the offset for write operation */
+ // offset = swab32(offset);
+ memcpy(&buf[0], (char*)&offset, 4);
+
+ /* On the I2C bus, LS Byte should go first */
+ // val = swab32(val);
+ memcpy(&buf[4], (char*)&val, 4);
+
+ rc = maple_i2c_send(client_num, buf, sizeof(buf));
+
+ if (rc < 0)
+ i2c_debug_print("Write FPGA Failed. rc=%d offset=0x%x val=0x%x client=%u[%u]\n",
+ rc, offset, val,
+ normal_i2c[client_num], client_num);
+ else
+ i2c_debug_print("Write FPGA: offset=0x%x val=0x%x client=%u[%u]\n",
+ offset, val,
+ normal_i2c[client_num], client_num);
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_write_fpga);
+
+int maple_i2c_read_fpga(unsigned char client_num, unsigned int offset, unsigned int *data)
+{
+ u8 obuf[4];
+ u8 buf[4];
+ int rc;
+
+ bcm_access_fpga();
+
+ /* FPGA expects 4 byte offset in BIG ENDIAN format */
+ obuf[0] = (offset >> 24) & 0xff;
+ obuf[1] = (offset >> 16) & 0xff;
+ obuf[2] = (offset >> 8) & 0xff;
+ obuf[3] = offset & 0xff;
+ rc = maple_i2c_read_with_offset(client_num, obuf, sizeof(obuf), buf, sizeof(buf));
+
+ if (rc < 0)
+ i2c_debug_print("Read FPGA Failed. rc=%d offset=0x%x client=%u[%u]\n",
+ rc, offset,
+ normal_i2c[client_num], client_num);
+ else
+ {
+ *data = buf[3] | (buf[2] << 8) | (buf[1] << 16) | (buf[0] << 24); /* MS byte is transferred first */
+ i2c_debug_print("Read FPGA: offset = 0x%x, val = 0x%x %02x %02x %02x %02x client=%u[%u]\n",
+ offset, *data, buf[0], buf[1], buf[2], buf[3],
+ normal_i2c[client_num], client_num);
+ }
+ return rc;
+}
+EXPORT_SYMBOL(maple_i2c_read_fpga);
+
+enum client_num maple_i2c_get_client(u32 addr)
+{
+ enum client_num i = 0;
+ while (i < SLAVE_NUM_OF_SLAVES)
+ {
+ if (pclient_data_ar[i])
+ {
+ if (slave_valid[i] && pclient_data_ar[i]->client.addr == addr)
+ {
+ break;
+ }
+ }
+ i++;
+ }
+ return i;
+}
+EXPORT_SYMBOL(maple_i2c_get_client);
+
+static int dev_change(u32 addr)
+{
+ enum client_num i = maple_i2c_get_client(addr);
+
+ if (i < SLAVE_NUM_OF_SLAVES)
+ {
+ i2c_client_num = i;
+ i2c_debug_print("Slave was set successfully i %d, addr 0x%x\n", i, addr);
+ }
+ else
+ {
+ i2c_debug_print("Failed to set slave i %d, addr 0x%x\n", i, addr);
+ }
+
+ return 0;
+}
+
+static void bcm_access_fpga(void)
+{
+ static int access_enabled;
+ int fpga_client_num = maple_i2c_get_client(I2C_SW1_I2C_ADDR);
+ uint8_t b;
+
+ if (access_enabled)
+ return;
+ b = 4;
+ maple_i2c_write(fpga_client_num, &b, 1);
+ access_enabled = 1;
+}
+#define BCM_FPGA_REG_RESETS 0x2
+#define BCM_FPGA_REG_FPGA_VERSION 0x0
+/* 1 = out of reset bcm_board_config_reset_value */
+void reset_maple(int bit,int param)
+{
+ int fpga_client_num = maple_i2c_get_client(FPGA_I2C_ADDR);
+ int sw_client_num = maple_i2c_get_client(I2C_SW0_I2C_ADDR);
+ uint8_t b = 1;
+ uint32_t reset_values;
+
+ maple_i2c_write(sw_client_num, &b, 1);
+
+ /* Read-modify-write so we can set only the relevant bit */
+ maple_i2c_read_fpga(fpga_client_num, BCM_FPGA_REG_RESETS, &reset_values);
+
+ if (param)
+ reset_values |= 1 << bit;
+ else
+ reset_values &= ~(1 << bit);
+ maple_i2c_write_fpga(fpga_client_num, BCM_FPGA_REG_RESETS, reset_values);
+}
+EXPORT_SYMBOL(reset_maple);
+
+/* Calls the appropriate function based on user command */
+static int exec_command(const char *buf, size_t count)
+{
+#define MAX_ARGS 4
+#define MAX_ARG_SIZE 32
+ int i, argc = 0, val = 0;
+ char cmd;
+ u32 offset = 0;
+ char arg[MAX_ARGS][MAX_ARG_SIZE];
+#define LOG_WR_KBUF_SIZE 128
+ char kbuf[LOG_WR_KBUF_SIZE];
+
+ if ((count > LOG_WR_KBUF_SIZE-1) || (copy_from_user(kbuf, buf, count) != 0))
+ return -EFAULT;
+ kbuf[count]=0;
+ argc = sscanf(kbuf, "%c %s %s %s %s", &cmd, arg[0], arg[1], arg[2], arg[3]);
+
+ if (argc < 1)
+ {
+ printk("Need at-least 2 arguments\n");
+ return -EFAULT;
+ }
+
+ for (i=0; i<MAX_ARGS; ++i) {
+ arg[i][MAX_ARG_SIZE-1] = '\0';
+ }
+ offset = (u32)simple_strtoul(arg[0], NULL, 0);
+ if (argc == 3)
+ val = (int)simple_strtoul(arg[1], NULL, 0);
+
+ switch (cmd)
+ {
+ case 'm':
+ reset_maple(0,offset); // maple out of reset(1) | reset (0)
+ break;
+ case 'k':
+ reset_maple(4,offset); // katana2 out of reset(1) | reset (0)
+ break;
+ case 'b':
+ if (argc == 3)
+ maple_i2c_write_byte(i2c_client_num, (u8)offset, (u8)val);
+ else
+ {
+ u8 data;
+ maple_i2c_read_byte(i2c_client_num, (u8)offset, &data);
+ printk("client 0x%x, offset 0x%x, data=0x%x\n", normal_i2c[i2c_client_num], offset, data);
+ }
+ break;
+
+ case 's':
+ if (argc == 2)
+ {
+ u8 data = (u8)offset;
+ maple_i2c_write(i2c_client_num, &data, 1);
+ }
+ else
+ {
+ u8 data = offset;
+ maple_i2c_read(i2c_client_num, &data, 1);
+ printk("client 0x%x, data=0x%x\n", normal_i2c[i2c_client_num], data);
+ }
+ break;
+
+ case 'w':
+ if (argc == 3)
+ maple_i2c_write_word(i2c_client_num, (u8)offset, (u16)val);
+ else
+ {
+ u16 data;
+ maple_i2c_read_word(i2c_client_num, (u8)offset, &data);
+ printk("client 0x%x, offset 0x%x, data=0x%x\n", normal_i2c[i2c_client_num], offset, data);
+ }
+ break;
+
+ case 'd':
+ if (argc == 3)
+ maple_i2c_write_reg(i2c_client_num, (u8)offset, val);
+ else
+ {
+ u32 data;
+ maple_i2c_read_reg(i2c_client_num, (u8)offset, &data);
+ printk("client 0x%x, offset 0x%x, data=0x%x\n", normal_i2c[i2c_client_num], offset, data);
+ }
+ break;
+
+ case 'f':
+ if (argc == 3)
+ maple_i2c_write_fpga(i2c_client_num, offset, val);
+ else
+ {
+ u32 data;
+ maple_i2c_read_fpga(i2c_client_num, offset, &data);
+ printk("client 0x%x, offset 0x%x, data=0x%x\n", normal_i2c[i2c_client_num], offset, data);
+ }
+ break;
+
+ case 'c':
+ dev_change(offset);
+ break;
+
+ default:
+ printk("Invalid command.\n Valid commands:\n"
+ " Change I2C Addr: c addr\n"
+ " Write Reg: d offset val\n"
+ " Read Reg: d offset\n"
+ " Write Word: w offset val\n"
+ " Read Word: w offset\n"
+ " Write Byte: b offset val\n"
+ " Read Byte: b offset\n"
+ " Write fpga: f offset val\n"
+ " Read fpga: f offset\n"
+ " Write to switch: s val (one byte)\n"
+ " Read from switch:s\n"
+ " Maple: m <0|1>\n"
+ " Katana2: k <0|1>\n"
+ );
+ break;
+ }
+ return count;
+}
+
+
+
+/* Read Function of PROCFS attribute "maple_i2c/test" */
+static ssize_t maple_i2c_proc_test_read(struct file *f, char *buf, size_t count,
+ loff_t *pos)
+{
+ printk(" Usage: echo command > "
+ " /proc/maple_i2c/test\n");
+ printk(" supported commands:\n"
+ " Change I2C Addr: c addr\n"
+ " Write Reg: d offset val\n"
+ " Read Reg: d offset\n"
+ " Write Word: w offset val\n"
+ " Read Word: w offset\n"
+ " Write Byte: b offset val\n"
+ " Read Byte: b offset\n"
+ " Write fpga: f offset val\n"
+ " Read fpga: f offset\n"
+ " Write to switch: s val (one byte)\n"
+ " Read from switch:s\n"
+ );
+ return 0;
+}
+
+/* Write Function of PROCFS attribute "maple_i2c/test" */
+static ssize_t maple_i2c_proc_test_write(struct file *f, const char *buf,
+ size_t count, loff_t *pos)
+{
+ return exec_command(buf, count);
+}
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int maple_i2c_dev_detect(struct i2c_client *client, struct i2c_board_info *info)
+{
+ i2c_debug_print("detecting i2c device 0x%x\n", client->addr);
+
+ /* TODO: detection and identification */
+
+ strcpy(info->type, "maple_i2c");
+ info->flags = 0;
+ return 0;
+}
+
+static struct file_operations maple_i2c_fops =
+{
+ read: maple_i2c_proc_test_read,
+ write: maple_i2c_proc_test_write
+};
+
+static int maple_i2c_dev_create_proc(void)
+{
+ i2c_proc_dir = proc_mkdir(PROC_DIR_NAME, NULL);
+ if (!i2c_proc_dir)
+ {
+ i2c_debug_print("fail to create proc dir\n");
+ return -ENOMEM;
+ }
+
+ i2c_proc_entry = create_proc_entry(PROC_ENTRY_NAME, 0, i2c_proc_dir);
+ if (!i2c_proc_entry)
+ {
+ remove_proc_entry(PROC_DIR_NAME, NULL);
+ return -ENOMEM;
+ }
+
+ i2c_proc_entry->proc_fops = &maple_i2c_fops;
+
+ return 0;
+}
+
+static int maple_i2c_chrdev_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static int maple_i2c_chrdev_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static long maple_i2c_chrdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int linux_rc = 0;
+ int rc;
+ maple_i2c_ioctl_param params;
+
+ /* don't even decode wrong cmds: better returning ENOTTY than EFAULT */
+ if (_IOC_TYPE(cmd) != MAPLE_I2C_IOCTL_MAGIC)
+ return -ENOTTY;
+
+ /*
+ * the type is a bitmask, and VERIFY_WRITE catches R/W
+ * transfers. Note that the type is user-oriented, while
+ * verify_area is kernel-oriented, so the concept of "read" and
+ * "write" is reversed
+ */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ linux_rc = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ linux_rc = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
+ if (linux_rc)
+ return -EFAULT;
+
+ switch (cmd)
+ {
+ case MAPLE_I2C_IOCTL_OP_DEV_CHANGE:
+ {
+ linux_rc = copy_from_user((char *)¶ms, (char *)arg, sizeof(params));
+ if (linux_rc < 0)
+ break;
+ return dev_change(params.addr);
+ }
+ break;
+ case MAPLE_I2C_IOCTL_OP_DEV_WRITE:
+ {
+ linux_rc = copy_from_user((char *)¶ms, (char *)arg, sizeof(params));
+ if (linux_rc < 0)
+ break;
+ switch (params.count)
+ {
+ case 8:
+ return maple_i2c_write_byte(i2c_client_num, params.addr, params.val);
+ case 16:
+ return maple_i2c_write_word(i2c_client_num, params.addr, params.val);
+ case 32:
+ return maple_i2c_write_reg(i2c_client_num, params.addr, params.val);
+ default:
+ return -EINVAL;
+ }
+ }
+ break;
+ case MAPLE_I2C_IOCTL_OP_DEV_READ:
+ {
+ unsigned char b;
+ unsigned short w;
+ unsigned int r;
+
+ linux_rc = copy_from_user((char *)¶ms, (char *)arg, sizeof(params));
+ if (linux_rc < 0)
+ break;
+ switch (params.count)
+ {
+ case 8:
+ linux_rc = maple_i2c_read_byte(i2c_client_num, params.addr, &b);
+ if (linux_rc < 0)
+ break;
+ params.val = b;
+ break;
+ case 16:
+ linux_rc = maple_i2c_read_word(i2c_client_num, params.addr, &w);
+ if (linux_rc < 0)
+ break;
+ params.val = w;
+ break;
+ case 32:
+ linux_rc = maple_i2c_read_reg(i2c_client_num, params.addr, &r);
+ if (linux_rc < 0)
+ break;
+ params.val = r;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (linux_rc < 0)
+ break;
+ return copy_to_user((char *)arg, (char *)¶ms, sizeof(params));
+ }
+ case MAPLE_I2C_IOCTL_OP_SWITCH_WRITE:
+ {
+ char b;
+
+ linux_rc = copy_from_user((char *)¶ms, (char *)arg, sizeof(params));
+ if (linux_rc < 0)
+ break;
+ b = params.val;
+ return maple_i2c_write(i2c_client_num, &b, 1);
+ }
+ case MAPLE_I2C_IOCTL_OP_SWITCH_READ:
+ {
+ char b;
+
+ linux_rc = maple_i2c_read(i2c_client_num, &b, 1);
+ if (linux_rc < 0)
+ break;
+ params.val = b;
+ return copy_to_user((char *)arg, (char *)¶ms, sizeof(params));
+ }
+ case MAPLE_I2C_IOCTL_OP_FPGA_WRITE:
+ {
+ linux_rc = copy_from_user((char *)¶ms, (char *)arg, sizeof(params));
+ if (linux_rc < 0)
+ break;
+ return maple_i2c_write_fpga(i2c_client_num, params.addr, params.val);
+ }
+ case MAPLE_I2C_IOCTL_OP_FPGA_READ:
+ {
+ linux_rc = copy_from_user((char *)¶ms, (char *)arg, sizeof(params));
+ if (linux_rc < 0)
+ break;
+ linux_rc = maple_i2c_read_fpga(i2c_client_num, params.addr, ¶ms.val);
+ if (linux_rc < 0)
+ break;
+ return copy_to_user((char *)arg, (char *)¶ms, sizeof(params));
+ }
+ default:
+ rc = -ENOTTY;
+ break;
+ }
+
+ return linux_rc;
+}
+
+static ssize_t maple_i2c_chrdev_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ return 0;
+}
+
+static struct file_operations maple_i2c_chrdev_fops =
+{
+ .owner = THIS_MODULE,
+ .open = maple_i2c_chrdev_open,
+ .release = maple_i2c_chrdev_release,
+ .write = maple_i2c_chrdev_write,
+ .unlocked_ioctl = maple_i2c_chrdev_ioctl
+};
+
+static struct cdev maple_i2c_chrdev_cdev;
+
+static int maple_i2c_dev_create_chrdev(void)
+{
+ dev_t dev = MKDEV(maple_i2c_chrdev_major, 0);
+ int linux_rc;
+
+ is_chrdev_reg = 0;
+ is_cdev_add = 0;
+ /*
+ * Register your major, and accept a dynamic number.
+ */
+ if (!maple_i2c_chrdev_major)
+ return -1;
+ linux_rc = register_chrdev_region(dev, 0, "maple_i2c");
+ if (linux_rc < 0)
+ {
+ i2c_debug_print("register_chrdev_region()->%d\n", linux_rc);
+ return -EIO;
+ }
+ is_chrdev_reg = 1;
+
+ cdev_init(&maple_i2c_chrdev_cdev, &maple_i2c_chrdev_fops);
+ linux_rc = cdev_add(&maple_i2c_chrdev_cdev, dev, 1);
+ if (linux_rc < 0)
+ {
+ i2c_debug_print("cdev_add()->%d\n", linux_rc);
+ return -EIO;
+ }
+ is_cdev_add = 1;
+
+ return 0;
+}
+
+static int maple_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int err = 0;
+ struct maple_i2c_data *pclient_data;
+
+ i2c_debug_print("!!!! i2c device 0x%x probe\n", client->addr);
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ goto exit;
+
+ if (!(pclient_data = kzalloc(sizeof(struct maple_i2c_data), GFP_KERNEL)))
+ {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ pclient_data->client.addr = client->addr;
+ pclient_data->client.adapter = client->adapter;
+ pclient_data->client.driver = client->driver;
+ pclient_data->client.flags = client->flags;
+
+ i2c_set_clientdata(client, pclient_data);
+
+ switch(client->addr)
+ {
+ case I2C_SW0_I2C_ADDR:
+ pclient_data_ar[SLAVE_SWITCH_70] = pclient_data;
+ slave_valid[SLAVE_SWITCH_70] = 1;
+ break;
+ case I2C_SW1_I2C_ADDR:
+ pclient_data_ar[SLAVE_SWITCH_71] = pclient_data;
+ slave_valid[SLAVE_SWITCH_71] = 1;
+ break;
+ case I2C_SW2_I2C_ADDR:
+ pclient_data_ar[SLAVE_SWITCH_72] = pclient_data;
+ slave_valid[SLAVE_SWITCH_72] = 1;
+ break;
+ case I2C_SW3_I2C_ADDR:
+ pclient_data_ar[SLAVE_SWITCH_73] = pclient_data;
+ slave_valid[SLAVE_SWITCH_73] = 1;
+ break;
+ case I2C_SW4_I2C_ADDR:
+ pclient_data_ar[SLAVE_SWITCH_74] = pclient_data;
+ slave_valid[SLAVE_SWITCH_74] = 1;
+ break;
+ case SFP_I2C_ADDR1:
+ pclient_data_ar[SLAVE_SFP_50] = pclient_data;
+ slave_valid[SLAVE_SFP_50] = 1;
+ break;
+ case SFP_I2C_ADDR2:
+ pclient_data_ar[SLAVE_SFP_51] = pclient_data;
+ slave_valid[SLAVE_SFP_51] = 1;
+ break;
+ case FPGA_I2C_ADDR:
+ pclient_data_ar[SLAVE_FPGA_40] = pclient_data;
+ slave_valid[SLAVE_FPGA_40] = 1;
+ break;
+ case PON_DPLL_I2C_ADDR:
+ pclient_data_ar[SLAVE_PON_DPLL_68] = pclient_data;
+ slave_valid[SLAVE_PON_DPLL_68] = 1;
+ break;
+ case PM_DPLL_I2C_ADDR:
+ pclient_data_ar[SLAVE_PM_DPLL_6A] = pclient_data;
+ slave_valid[SLAVE_PM_DPLL_6A] = 1;
+ break;
+ case CXP_R_I2C_ADDR:
+ pclient_data_ar[SLAVE_CXP_R_54] = pclient_data;
+ slave_valid[SLAVE_CXP_R_54] = 1;
+ break;
+ case PCIE_SW_I2C_ADDR:
+ pclient_data_ar[SLAVE_PCIE_SW_3C] = pclient_data;
+ slave_valid[SLAVE_PCIE_SW_3C] = 1;
+ break;
+ default:
+ i2c_debug_print("%s client addr out of range 0x%x\n", __FUNCTION__, client->addr);
+ goto exit_kfree;
+ }
+
+ /* Create only once */
+ if (i2c_proc_entry == NULL)
+ {
+ if (maple_i2c_dev_create_proc() < 0)
+ goto exit_kfree;
+ }
+ if (!is_cdev_add)
+ {
+ if (maple_i2c_dev_create_chrdev() < 0)
+ goto exit_kfree;
+ }
+ ++i2c_num_clients;
+
+ return 0;
+
+exit_kfree:
+ kfree(pclient_data);
+exit:
+ return err;
+}
+
+static int maple_i2c_dev_remove(struct i2c_client *client)
+{
+ kfree(i2c_get_clientdata(client));
+ --i2c_num_clients;
+ if (!i2c_num_clients)
+ {
+ if (i2c_proc_entry != NULL)
+ {
+ remove_proc_entry(PROC_ENTRY_NAME, i2c_proc_dir);
+ i2c_proc_entry = NULL;
+ }
+ if (i2c_proc_dir != NULL)
+ {
+ remove_proc_entry(PROC_DIR_NAME, NULL);
+ i2c_proc_dir = NULL;
+ }
+ if (is_cdev_add)
+ {
+ cdev_del(&maple_i2c_chrdev_cdev);
+ is_cdev_add = 0;
+ }
+ if (is_chrdev_reg)
+ {
+ unregister_chrdev_region(MKDEV(maple_i2c_chrdev_major, 0), 1);
+ is_chrdev_reg = 0;
+ }
+ }
+
+ return 0;
+}
+
+static struct i2c_driver maple_i2c_dev_driver = {
+ .class = ~0,
+ .driver = {
+ .name = "maple_i2c",
+ },
+ .probe = maple_i2c_dev_probe,
+ .remove = maple_i2c_dev_remove,
+ .id_table = maple_i2c_id_table,
+ .detect = maple_i2c_dev_detect,
+ .address_list = normal_i2c,
+};
+
+module_i2c_driver(maple_i2c_dev_driver);
+
+MODULE_DESCRIPTION("maple i2c devices");
+MODULE_LICENSE("GPL");
+
diff --git a/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs.h b/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs.h
new file mode 100644
index 0000000..ad0edaa
--- /dev/null
+++ b/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs.h
@@ -0,0 +1,226 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+ */
+
+#ifndef _BCMOLT_I2C_DEVS_H_
+#define _BCMOLT_I2C_DEVS_H_
+
+/* When inserting the module (with insmod) onlt the I2C switch devices (I2C_SWX_I2C_ADDR)
+ will be automatically detected, and therefore will be probed.
+ Probing all other devices can be done after inerting the module via sysfs.
+ for example, in order to probe FPGA device, the following line should be applied:
+ -- echo maple_i2c FPGA_I2C_ADDR > /sys/bus/i2c/devices/i2c-0/new_device --
+*/
+enum client_num
+{
+ SLAVE_SWITCH_70 = 0,
+ SLAVE_SWITCH_71 = 1,
+ SLAVE_SWITCH_72 = 2,
+ SLAVE_SWITCH_73 = 3,
+ SLAVE_SWITCH_74 = 4,
+ SLAVE_SFP_50 = 5,
+ SLAVE_SFP_51 = 6,
+ SLAVE_FPGA_40 = 7,
+ SLAVE_PON_DPLL_68 = 8,
+ SLAVE_PM_DPLL_6A = 9,
+ SLAVE_CXP_R_54 = 10,
+ SLAVE_PCIE_SW_3C = 11,
+ SLAVE_NUM_OF_SLAVES
+};
+
+
+/*****************************************************************
+ maple_i2c_write
+
+ DESCRIPTION:
+ Writes serially data to I2C device
+
+ PARAMETERS:
+ client num - The client to write to.
+ buf - The buffer to write.
+ count - Number of bytes to write
+
+ OUTPUT:
+ The number of bytes that were written, when fails return negative number
+********************************************************************/
+ssize_t maple_i2c_write(unsigned char client_num, char *buf, size_t count);
+
+/*****************************************************************
+ maple_i2c_read
+
+ DESCRIPTION:
+ Read serially data from I2C device
+
+ PARAMETERS:
+ client num - The client to write to.
+ buf - The buffer to read to.
+ count - Number of bytes to read
+
+ OUTPUT:
+ The number of bytes that were read, when fails return negative number
+********************************************************************/
+ssize_t maple_i2c_read(unsigned char client_num, char *buf, size_t count);
+
+/*****************************************************************
+ maple_i2c_write_byte
+
+ DESCRIPTION:
+ Write byte to I2C device
+
+ PARAMETERS:
+ client num - The client to write to.
+ offset - The offset to write to.
+ val - Tha data to write.
+
+ OUTPUT:
+ 0 on success, -1 on failure.
+********************************************************************/
+int maple_i2c_write_byte(unsigned char client_num, unsigned char offset, unsigned char val);
+
+/*****************************************************************
+ maple_i2c_read_byte
+
+ DESCRIPTION:
+ Read byte from I2C device
+
+ PARAMETERS:
+ client num - The client to read from.
+ offset - The offset to read from.
+ data - the read value is written to this pointer.
+ OUTPUT:
+ 0 on success, -1 on failure.
+********************************************************************/
+int maple_i2c_read_byte(unsigned char client_num, unsigned char offset, unsigned char* data);
+
+/*****************************************************************
+ maple_i2c_write_word
+
+ DESCRIPTION:
+ Write 16 bit word to I2C device
+
+ PARAMETERS:
+ client num - The client to write to.
+ offset - The offset to write to.
+ val - Tha data to write.
+
+ OUTPUT:
+ 0 on success, -1 on failure.
+********************************************************************/
+int maple_i2c_write_word(unsigned char client_num, unsigned char offset, unsigned short val);
+
+/*****************************************************************
+ maple_i2c_read_word
+
+ DESCRIPTION:
+ Read 16 bit word from I2C device
+
+ PARAMETERS:
+ client num - The client to read from.
+ offset - The offset to read from.
+ data - the read value is written to this pointer.
+ OUTPUT:
+ 0 on success, -1 on failure.
+********************************************************************/
+int maple_i2c_read_word(unsigned char client_num, unsigned char offset, unsigned short* data);
+
+/*****************************************************************
+ maple_i2c_write_reg
+
+ DESCRIPTION:
+ Write 32 bit register to I2C device
+
+ PARAMETERS:
+ client num - The client to write to.
+ offset - The offset to write to.
+ val - Tha data to write.
+
+ OUTPUT:
+ 0 on success, -1 on failure.
+********************************************************************/
+int maple_i2c_write_reg(unsigned char client_num, unsigned char offset, int val);
+
+/*****************************************************************
+ maple_i2c_read_reg
+
+ DESCRIPTION:
+ Read 32 bit word from I2C device
+
+ PARAMETERS:
+ client num - The client to read from.
+ offset - The offset to read from.
+ data - the read value is written to this pointer.
+ OUTPUT:
+ 0 on success, -1 on failure.
+********************************************************************/
+int maple_i2c_read_reg(unsigned char client_num, unsigned char offset, unsigned int* data);
+
+/*****************************************************************
+ maple_i2c_write_fpga
+
+ DESCRIPTION:
+ Write 32 bit register to I2C fpga device
+
+ PARAMETERS:
+ client num - The client to write to.
+ offset - The offset to write to.
+ val - Tha data to write.
+
+ OUTPUT:
+ 0 on success, -1 on failure.
+********************************************************************/
+int maple_i2c_write_fpga(unsigned char client_num, unsigned int offset, unsigned int val);
+
+/*****************************************************************
+ maple_i2c_read_fpga
+
+ DESCRIPTION:
+ Read 32 bit word from I2C fpga device
+
+ PARAMETERS:
+ client num - The client to read from.
+ offset - The offset to read from.
+ data - the read value is written to this pointer.
+ OUTPUT:
+ 0 on success, -1 on failure.
+********************************************************************/
+int maple_i2c_read_fpga(unsigned char client_num, unsigned int offset, unsigned int* data);
+
+/*****************************************************************
+ maple_i2c_get_client
+
+ DESCRIPTION:
+ Gets an I2C client number from an address
+
+ PARAMETERS:
+ addr - The address of the client.
+ OUTPUT:
+ The client number for this client, or SLAVE_NUM_OF_SLAVES on failure.
+********************************************************************/
+enum client_num maple_i2c_get_client(unsigned int addr);
+
+#endif /* _MAPLE_I2C_DEVS_H_ */
diff --git a/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs_addr.h b/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs_addr.h
new file mode 100644
index 0000000..f1a9a2c
--- /dev/null
+++ b/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs_addr.h
@@ -0,0 +1,50 @@
+/*
+<:copyright-BRCM:2016:DUAL/GPL:standard
+
+ Broadcom Proprietary and Confidential.(c) 2016 Broadcom
+ All Rights Reserved
+
+Unless you and Broadcom execute a separate written software license
+agreement governing use of this software, this software is licensed
+to you under the terms of the GNU General Public License version 2
+(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
+with the following added to such license:
+
+ As a special exception, the copyright holders of this software give
+ you permission to link this software with independent modules, and
+ to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent
+ module, the terms and conditions of the license of that module.
+ An independent module is a module which is not derived from this
+ software. The special exception does not apply to any modifications
+ of the software.
+
+Not withstanding the above, under no circumstances may you combine
+this software in any way with any other Broadcom software provided
+under a license other than the GPL, without Broadcom's express prior
+written consent.
+
+:>
+ */
+
+#ifndef _BCMOLT_I2C_DEVS_ADDR_H_
+#define _BCMOLT_I2C_DEVS_ADDR_H_
+
+BCM_I2C_DEV_ADDR_START
+BCM_I2C_DEV_ADDR(I2C_SW0_I2C_ADDR, "sw0", 0x70)
+BCM_I2C_DEV_ADDR(I2C_SW1_I2C_ADDR, "sw1", 0x71)
+BCM_I2C_DEV_ADDR(I2C_SW2_I2C_ADDR, "sw2", 0x72)
+BCM_I2C_DEV_ADDR(I2C_SW3_I2C_ADDR, "sw3", 0x73)
+BCM_I2C_DEV_ADDR(I2C_SW4_I2C_ADDR, "sw4", 0x74)
+BCM_I2C_DEV_ADDR(SFP_I2C_ADDR1, "sfp1", 0x50)
+BCM_I2C_DEV_ADDR(SFP_I2C_ADDR2, "sfp2", 0x51)
+BCM_I2C_DEV_ADDR(FPGA_I2C_ADDR, "fpga", 0x40)
+BCM_I2C_DEV_ADDR(PON_DPLL_I2C_ADDR, "pon_dpll", 0x68)
+BCM_I2C_DEV_ADDR(PM_DPLL_I2C_ADDR, "pm_dpll", 0x6a)
+BCM_I2C_DEV_ADDR(CXP_T_I2C_ADDR, "cxp_t", 0x50)
+BCM_I2C_DEV_ADDR(CXP_R_I2C_ADDR, "cxp_r", 0x54)
+BCM_I2C_DEV_ADDR(PCIE_SW_I2C_ADDR, "pcie_sw", 0x3c)
+BCM_I2C_DEV_ADDR_END
+
+#endif
+
diff --git a/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs_ioctl.h b/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs_ioctl.h
new file mode 100644
index 0000000..e15f71a
--- /dev/null
+++ b/bcm68620_release/release/host_customized/i2c/bcmolt_i2c_devs_ioctl.h
@@ -0,0 +1,24 @@
+#ifndef _BCMOLT_I2C_DEVS_IOCTL_H_
+#define _BCMOLT_I2C_DEVS_IOCTL_H_
+
+#include <linux/ioctl.h>
+
+typedef struct
+{
+ uint32_t count;
+ uint32_t addr;
+ uint32_t val;
+} maple_i2c_ioctl_param;
+
+#define MAPLE_I2C_IOCTL_MAGIC 'I'
+
+#define MAPLE_I2C_IOCTL_OP_DEV_CHANGE _IOW(MAPLE_I2C_IOCTL_MAGIC, 1, maple_i2c_ioctl_param)
+#define MAPLE_I2C_IOCTL_OP_DEV_WRITE _IOW(MAPLE_I2C_IOCTL_MAGIC, 2, maple_i2c_ioctl_param)
+#define MAPLE_I2C_IOCTL_OP_DEV_READ _IOWR(MAPLE_I2C_IOCTL_MAGIC, 3, maple_i2c_ioctl_param)
+#define MAPLE_I2C_IOCTL_OP_SWITCH_WRITE _IOW(MAPLE_I2C_IOCTL_MAGIC, 4, maple_i2c_ioctl_param)
+#define MAPLE_I2C_IOCTL_OP_SWITCH_READ _IOR(MAPLE_I2C_IOCTL_MAGIC, 5, maple_i2c_ioctl_param)
+#define MAPLE_I2C_IOCTL_OP_FPGA_WRITE _IOW(MAPLE_I2C_IOCTL_MAGIC, 6, maple_i2c_ioctl_param)
+#define MAPLE_I2C_IOCTL_OP_FPGA_READ _IOWR(MAPLE_I2C_IOCTL_MAGIC, 7, maple_i2c_ioctl_param)
+
+#endif
+