diff --git a/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c b/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c
index 814889464596..16b9ba2fbc4c 100644
--- a/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c
+++ b/platform/broadcom/sonic-platform-modules-delta/ag5648/modules/delta_ag5648_platform.c
@@ -1,1542 +1,1644 @@
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sysfs.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/dmi.h>
-#include <linux/version.h>
-#include <linux/ctype.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/i2c/pca954x.h>
-#include <linux/i2c-mux.h>
-#include <linux/i2c-mux-gpio.h>
-#include <linux/i2c/sff-8436.h>
-
-#define BUS4_DEV_NUM 54
-#define DEFAULT_NUM  1
-#define BUS4_BASE_NUM 10
-#define BUS4_MUX_REG 0x18
-
-#define TEMP_FAN_VAL  0x06
-#define FANIO_CTL_VAL 0x07
-#define FAN_CTRL_VAL  0x05
-#define PSU1_VAL      0x00
-#define PSU2_VAL      0x20
-#define HOT_SWAP1_VAL 0x10
-#define HOT_SWAP2_VAL 0x30
-
-#define SYSTEM_CPLD_REG  0x31
-#define MASTER_CPLD_REG  0x35
-#define SLAVE_CPLD_REG   0x39
-
-#define FAN_LED_REG      0x05
-#define LED_REG          0x04
-
-#define SFP_PRESENCE_1   0x08
-#define SFP_PRESENCE_2   0x09
-#define SFP_PRESENCE_3   0x0a
-#define SFP_PRESENCE_4   0x0b
-#define SFP_PRESENCE_5   0x0c
-#define SFP_PRESENCE_6   0x08
-#define SFP_PRESENCE_7   0x09
-#define QSFP_PRESENCE    0x12
-        
-#define QSFP_RESPONSE    0x10
-#define QSFP_LP_MODE     0x11
-#define QSFP_RESET       0x13        
-
-
-#define SFF8436_INFO(data) \
-    .type = "sff8436", .addr = 0x50, .platform_data = (data)
-
-#define SFF_8346_PORT(eedata) \
-    .byte_len = 256, .page_size = 1, .flags = SFF_8436_FLAG_READONLY
-	
-#define ag5648_i2c_device_num(NUM){                                           \
-        .name                   = "delta-ag5648-i2c-device",                  \
-        .id                     = NUM,                                        \
-        .dev                    = {                                           \
-                    .platform_data = &ag5648_i2c_device_platform_data[NUM],   \
-                    .release       = device_release,                          \
-        },                                                                    \
-}
-
-/*Define struct to get client of i2c_new_deivce */
-struct i2c_client * i2c_client_9548;
-
-enum{
-    BUS0 = 0,
-    BUS1,
-    BUS2,
-    BUS3,
-    BUS4,
-    BUS5,
-    BUS6,
-    BUS7,
-};
-
-unsigned char reverse_8bits(unsigned char c)
-{
-        unsigned char s = 0;
-        int i;
-        for (i = 0; i < 8; ++i) {
-                s <<= 1;
-                s |= c & 1;
-                c >>= 1;
-        }
-        return s;
-}
-/*----------------   I2C device   - start   ------------- */
-static void device_release(struct device *dev)
-{
-    return;
-}
-
-struct i2c_device_platform_data {
-    int parent;
-    struct i2c_board_info           info;
-    struct i2c_client              *client;
-};
-/* pca9547 - add 8 bus */
-static struct pca954x_platform_mode pca954x_mode[] = {
-  { .adap_id = 2,
-    .deselect_on_exit = 1,
-  },
-  { .adap_id = 3,
-    .deselect_on_exit = 1,
-  },
-  { .adap_id = 4,
-    .deselect_on_exit = 1,
-  },
-  { .adap_id = 5,
-    .deselect_on_exit = 1,
-  },
-  { .adap_id = 6,
-    .deselect_on_exit = 1,
-  },
-  { .adap_id = 7,
-    .deselect_on_exit = 1,
-  },
-  { .adap_id = 8,
-    .deselect_on_exit = 1,
-  },
-  { .adap_id = 9,
-    .deselect_on_exit = 1,
-  },
-};
-
-static struct pca954x_platform_data pca954x_data = {
-  .modes = pca954x_mode,
-  .num_modes = ARRAY_SIZE(pca954x_mode),
-};
-
-static struct i2c_board_info __initdata i2c_info_pca9548[] =
-{
-        {
-            I2C_BOARD_INFO("pca9548", 0x70),
-            .platform_data = &pca954x_data, 
-        },
-};
-
-
-static struct sff_8436_platform_data sff_8436_port[] = {
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-    { SFF_8346_PORT() },
-};
-
-
-static struct i2c_device_platform_data ag5648_i2c_device_platform_data[] = {
-    {
-        /* id eeprom (0x53) */
-        .parent = 2,
-        .info = { I2C_BOARD_INFO("24c02", 0x53) },
-        .client = NULL,
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 2,
-        .info = { I2C_BOARD_INFO("tmp75", 0x4d) },
-        .client = NULL,
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 3,
-        .info = { I2C_BOARD_INFO("tmp75", 0x49) },
-        .client = NULL,
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 3,
-        .info = { I2C_BOARD_INFO("tmp75", 0x4b) },
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 3,
-        .info = { I2C_BOARD_INFO("tmp75", 0x4c) },
-        .client = NULL,
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 3,
-        .info = { I2C_BOARD_INFO("tmp75", 0x4e) },
-        .client = NULL,
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 3,
-        .info = { I2C_BOARD_INFO("tmp75", 0x4f) },
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 3,
-        .info = { I2C_BOARD_INFO("emc2305", 0x4d) },
-        .client = NULL,
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 5,
-        .info = { I2C_BOARD_INFO("emc2305", 0x4d) },
-        .client = NULL,
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 3,
-        .info = { I2C_BOARD_INFO("ltc4215", 0x40) },
-        .client = NULL,
-    },
-    {
-        /* tmp75 (0x4d) */
-        .parent = 3,
-        .info = { I2C_BOARD_INFO("ltc4215", 0x42) },
-    },
-    {
-        /* psu1 (0x59) */
-        .parent = 6,
-        .info = { I2C_BOARD_INFO("dni_ag5648_psu", 0x59) },
-        .client = NULL,
-    },
-    {
-        /* psu2 (0x58) */
-        .parent = 6,
-        .info = { I2C_BOARD_INFO("dni_ag5648_psu", 0x58) },
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 10,
-        .info = { SFF8436_INFO(&sff_8436_port[0]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 11,
-        .info = { SFF8436_INFO(&sff_8436_port[1]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 12,
-        .info = { SFF8436_INFO(&sff_8436_port[2]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 13,
-        .info = { SFF8436_INFO(&sff_8436_port[3]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 14,
-        .info = { SFF8436_INFO(&sff_8436_port[4]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 15,
-        .info = { SFF8436_INFO(&sff_8436_port[5]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 16,
-        .info = { SFF8436_INFO(&sff_8436_port[6]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 17,
-        .info = { SFF8436_INFO(&sff_8436_port[7]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 18,
-        .info = { SFF8436_INFO(&sff_8436_port[8]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 19,
-        .info = { SFF8436_INFO(&sff_8436_port[9]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 20,
-        .info = { SFF8436_INFO(&sff_8436_port[10]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 21,
-        .info = { SFF8436_INFO(&sff_8436_port[11]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 22,
-        .info = { SFF8436_INFO(&sff_8436_port[12]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 23,
-        .info = { SFF8436_INFO(&sff_8436_port[13]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 24,
-        .info = { SFF8436_INFO(&sff_8436_port[14]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 25,
-        .info = { SFF8436_INFO(&sff_8436_port[15]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 26,
-        .info = { SFF8436_INFO(&sff_8436_port[16]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 27,
-        .info = { SFF8436_INFO(&sff_8436_port[17]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 28,
-        .info = { SFF8436_INFO(&sff_8436_port[18]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 29,
-        .info = { SFF8436_INFO(&sff_8436_port[19]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 30,
-        .info = { SFF8436_INFO(&sff_8436_port[20]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 31,
-        .info = { SFF8436_INFO(&sff_8436_port[21]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 32,
-        .info = { SFF8436_INFO(&sff_8436_port[22]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 33,
-        .info = { SFF8436_INFO(&sff_8436_port[23]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 34,
-        .info = { SFF8436_INFO(&sff_8436_port[24]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 35,
-        .info = { SFF8436_INFO(&sff_8436_port[25]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 36,
-        .info = { SFF8436_INFO(&sff_8436_port[26]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 37,
-        .info = { SFF8436_INFO(&sff_8436_port[27]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 38,
-        .info = { SFF8436_INFO(&sff_8436_port[28]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 39,
-        .info = { SFF8436_INFO(&sff_8436_port[29]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 40,
-        .info = { SFF8436_INFO(&sff_8436_port[30]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 41,
-        .info = { SFF8436_INFO(&sff_8436_port[31]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 42,
-        .info = { SFF8436_INFO(&sff_8436_port[32]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 43,
-        .info = { SFF8436_INFO(&sff_8436_port[33]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 44,
-        .info = { SFF8436_INFO(&sff_8436_port[34]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 45,
-        .info = { SFF8436_INFO(&sff_8436_port[35]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 46,
-        .info = { SFF8436_INFO(&sff_8436_port[36]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 47,
-        .info = { SFF8436_INFO(&sff_8436_port[37]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 48,
-        .info = { SFF8436_INFO(&sff_8436_port[38]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 49,
-        .info = { SFF8436_INFO(&sff_8436_port[39]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 50,
-        .info = { SFF8436_INFO(&sff_8436_port[40]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 51,
-        .info = { SFF8436_INFO(&sff_8436_port[41]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 52,
-        .info = { SFF8436_INFO(&sff_8436_port[42]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 53,
-        .info = { SFF8436_INFO(&sff_8436_port[43]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 54,
-        .info = { SFF8436_INFO(&sff_8436_port[44]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 55,
-        .info = { SFF8436_INFO(&sff_8436_port[45]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 56,
-        .info = { SFF8436_INFO(&sff_8436_port[46]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 57,
-        .info = { SFF8436_INFO(&sff_8436_port[47]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 58,
-        .info = { SFF8436_INFO(&sff_8436_port[48]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 59,
-        .info = { SFF8436_INFO(&sff_8436_port[49]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 60,
-        .info = { SFF8436_INFO(&sff_8436_port[50]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 61,
-        .info = { SFF8436_INFO(&sff_8436_port[51]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 62,
-        .info = { SFF8436_INFO(&sff_8436_port[52]) },
-        .client = NULL,
-    },
-    {
-        /* qsfp 1 (0x50) */
-        .parent = 63,
-        .info = { SFF8436_INFO(&sff_8436_port[53]) },
-        .client = NULL,
-    },
-};
-
-
-static struct platform_device ag5648_i2c_device[] = {
-    ag5648_i2c_device_num(0),
-    ag5648_i2c_device_num(1),
-    ag5648_i2c_device_num(2),
-    ag5648_i2c_device_num(3),
-    ag5648_i2c_device_num(4),
-    ag5648_i2c_device_num(5),
-    ag5648_i2c_device_num(6),
-    ag5648_i2c_device_num(7),
-    ag5648_i2c_device_num(8),
-    ag5648_i2c_device_num(9),
-    ag5648_i2c_device_num(10),
-    ag5648_i2c_device_num(11),
-    ag5648_i2c_device_num(12),   
-    ag5648_i2c_device_num(13),
-    ag5648_i2c_device_num(14),
-    ag5648_i2c_device_num(15),
-    ag5648_i2c_device_num(16),
-    ag5648_i2c_device_num(17),
-    ag5648_i2c_device_num(18),
-    ag5648_i2c_device_num(19),
-    ag5648_i2c_device_num(20),
-    ag5648_i2c_device_num(21),
-    ag5648_i2c_device_num(22),
-    ag5648_i2c_device_num(23),
-    ag5648_i2c_device_num(24),
-    ag5648_i2c_device_num(25),
-    ag5648_i2c_device_num(26),
-    ag5648_i2c_device_num(27),
-    ag5648_i2c_device_num(28),
-    ag5648_i2c_device_num(29),
-    ag5648_i2c_device_num(30),
-    ag5648_i2c_device_num(31),
-    ag5648_i2c_device_num(32),
-    ag5648_i2c_device_num(33),
-    ag5648_i2c_device_num(34),
-    ag5648_i2c_device_num(35),
-    ag5648_i2c_device_num(36),
-    ag5648_i2c_device_num(37),
-    ag5648_i2c_device_num(38),
-    ag5648_i2c_device_num(39),
-    ag5648_i2c_device_num(40),
-    ag5648_i2c_device_num(41),
-    ag5648_i2c_device_num(42),
-    ag5648_i2c_device_num(43),
-    ag5648_i2c_device_num(44),
-    ag5648_i2c_device_num(45),
-    ag5648_i2c_device_num(46),
-    ag5648_i2c_device_num(47),
-    ag5648_i2c_device_num(48),
-    ag5648_i2c_device_num(49),
-    ag5648_i2c_device_num(50),
-    ag5648_i2c_device_num(51),
-    ag5648_i2c_device_num(52),
-    ag5648_i2c_device_num(53),
-    ag5648_i2c_device_num(54),
-    ag5648_i2c_device_num(55),
-    ag5648_i2c_device_num(56),
-    ag5648_i2c_device_num(57),
-    ag5648_i2c_device_num(58),
-    ag5648_i2c_device_num(59),
-    ag5648_i2c_device_num(60),
-    ag5648_i2c_device_num(61),
-    ag5648_i2c_device_num(62),
-    ag5648_i2c_device_num(63),
-    ag5648_i2c_device_num(64),
-    ag5648_i2c_device_num(65),
-    ag5648_i2c_device_num(66),
-};
- 
-/*----------------   I2C device   - end   ------------- */
-
-/*----------------   I2C driver   - start   ------------- */
-static int __init i2c_device_probe(struct platform_device *pdev)
-{
-    struct i2c_device_platform_data *pdata;
-    struct i2c_adapter *parent;
-
-    pdata = pdev->dev.platform_data;
-    if (!pdata) {
-        dev_err(&pdev->dev, "Missing platform data\n");
-        return -ENODEV;
-    }
-
-    parent = i2c_get_adapter(pdata->parent);
-    if (!parent) {
-        dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
-            pdata->parent);
-        return -ENODEV;
-    }
-
-    pdata->client = i2c_new_device(parent, &pdata->info);
-    if (!pdata->client) {
-        dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n",
-            pdata->info.type, pdata->parent);
-        return -ENODEV;
-    }
-
-    return 0;
-}
-
-static int __exit i2c_deivce_remove(struct platform_device *pdev)
-{
-    struct i2c_adapter *parent;
-    struct i2c_device_platform_data *pdata;
-
-    pdata = pdev->dev.platform_data;
-    if (!pdata) {
-        dev_err(&pdev->dev, "Missing platform data\n");
-        return -ENODEV;
-    }
-
-    if (pdata->client) {
-        parent = i2c_get_adapter(pdata->parent);
-        i2c_unregister_device(pdata->client);
-        i2c_put_adapter(parent);
-    }
-
-    return 0;
-}
-static struct platform_driver i2c_device_driver = {
-    .probe = i2c_device_probe,
-    .remove = __exit_p(i2c_deivce_remove),
-    .driver = {
-        .owner = THIS_MODULE,
-        .name = "delta-ag5648-i2c-device",
-    }
-};
-
-/*----------------   I2C driver   - end   ------------- */
-
-/*----------------    CPLD - start   ------------- */
-
-/*    CPLD  -- device   */
-
-enum cpld_type {
-    system_cpld,
-    master_cpld,
-    slave_cpld,
-};
-
-struct cpld_platform_data {
-    int reg_addr;
-    struct i2c_client *client;
-};
-
-static struct cpld_platform_data ag5648_cpld_platform_data[] = {
-    [system_cpld] = {
-        .reg_addr = SYSTEM_CPLD_REG,
-    },
-    [master_cpld] = {
-        .reg_addr = MASTER_CPLD_REG,
-    },
-    [slave_cpld] = {
-        .reg_addr = SLAVE_CPLD_REG,
-    },
-};
-
-static struct platform_device ag5648_cpld = {
-    .name               = "delta-ag5648-cpld",
-    .id                 = 0,
-    .dev                = {
-                .platform_data   = ag5648_cpld_platform_data,
-                .release         = device_release
-    },
-};
-
-static ssize_t get_present(struct device *dev, struct device_attribute \
-                            *dev_attr, char *buf)
-{
-    int ret;
-    u64 data = 0;
-    u64 data2 = 0;
-    struct cpld_platform_data *pdata = dev->platform_data;
-
-    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_1);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data = (u32)(ret & 0xff);
-
-    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_2);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data |= (u32)(ret & 0xff) << 8;
-
-    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_3);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data |= (u32)(ret & 0xff) << 16;
-
-    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_4);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data |= (u32)(ret & 0xff) << 24;
-
-    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_5);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data2 = ((u32)(ret & 0xf)) ;
-
-    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, SFP_PRESENCE_6);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data2 |= (u32)(ret & 0xff) << 4;
-
-    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, SFP_PRESENCE_7);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data2 |= (u32)((ret >> 4) & 0xf) << 12;
-
-    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, QSFP_PRESENCE);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data2 |= (u32)(ret & 0x3f) << 16;
-
-    return sprintf(buf, "0x%06x%x\n", data2, data);
-}
-
-static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, char *buf) 
-{
-    int ret;
-    u32 data = 0;
-    struct cpld_platform_data *pdata = dev->platform_data;
-
-    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, QSFP_LP_MODE);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data = ((u8)ret & 0x3f) ;
-
-    return sprintf(buf, "0x%02x%012x\n", data);
-}
-
-static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) 
-{
-    unsigned long data;
-    int err;
-
-    struct cpld_platform_data *pdata = dev->platform_data;
-
-    err = kstrtoul(buf, 16, &data);
-    if (err)
-        return err;
-    
-    data = data >> 48;
-    i2c_smbus_write_byte_data(pdata[master_cpld].client, QSFP_LP_MODE, (u8)(data & 0xff));
-
-    return count;
-}
-
-static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, char *buf) 
-{
-    int ret;
-    u64 data = 0;
-    struct cpld_platform_data *pdata = dev->platform_data;
-
-    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, QSFP_RESET);
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-
-    data = ((u8)ret & 0x3f);
-
-    return sprintf(buf, "0x%02x%012x\n", data);
-}
-
-static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) 
-{
-    unsigned long data;
-    int err;
-    struct cpld_platform_data *pdata = dev->platform_data;
-    
-    err = kstrtoul(buf, 16, &data);
-    if (err)
-        return err;
-    data = data >> 48;
-    i2c_smbus_write_byte_data(pdata[master_cpld].client, QSFP_RESET, (u8)(data & 0xff));
-
-    return count;
-}
-
-static ssize_t get_response(struct device *dev, struct device_attribute *devattr, char *buf) 
-{
-    int ret;
-    u8 data = 0;
-    struct cpld_platform_data *pdata = dev->platform_data;
-
-    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, QSFP_RESPONSE);
-
-    if (ret < 0)
-        return sprintf(buf, "error number(%ld)",ret);
-    data = (u8)ret & 0x3f;
-
-    return sprintf(buf, "0x%02x%012x\n", data);
-}
-
-static ssize_t set_response(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) 
-{
-    unsigned long data;
-    int err;
-    struct cpld_platform_data *pdata = dev->platform_data;
-
-    err = kstrtoul(buf, 16, &data);
-    if (err)
-        return err;
-    data = data >> 48;
-    i2c_smbus_write_byte_data(pdata[master_cpld].client, QSFP_RESPONSE, (u8)(data & 0xff));
-
-    return count;
-}
-
-struct platform_led_status{
-	int reg_data;
-	char *led_status;
-	int led_id;
-};
-	
-static struct platform_led_status led_info[] = {
-    {
-        .reg_data = 0x00,//0000 0000
-        .led_status = "fan_off",
-        .led_id = 0,
-    },
-    {
-        .reg_data = 1 << 6,//0100 0000
-        .led_status = "fan_Amber",
-        .led_id = 0,
-    },
-    {
-        .reg_data = 2 << 6,//1000 0000
-        .led_status = "fan_green",
-        .led_id = 0,
-    },
-    {
-        .reg_data = 3 << 6,//1100 0000
-        .led_status = "fan_Blinking_yellow",
-        .led_id = 0,
-    },
-    {
-        .reg_data = 0x00,
-        .led_status = "sys_Blinking_green",
-        .led_id = 1,
-    },
-    {
-        .reg_data = 1 << 4,
-        .led_status = "sys_green",
-        .led_id = 1,
-    },
-    {
-        .reg_data = 2 << 4,
-        .led_status = "sys_Amber",
-        .led_id = 1,
-    },
-    {
-        .reg_data = 3 << 4 ,
-        .led_status = "sys_Amber",
-        .led_id = 1,
-    },
-	{
-		.reg_data = 0x00,
-		.led_status = "pwr_off",
-		.led_id = 2,
-	},
-	{
-		.reg_data = 1 << 1,
-		.led_status = "pwr_Amber",
-		.led_id = 2,
-	},
-	{
-		.reg_data = 2 << 1,
-		.led_status = "pwr_green",
-		.led_id = 2,
-	},
-	{
-		.reg_data = 3 << 1,
-		.led_status = "pwr_Blinking_Amber",
-		.led_id = 2,
-	},
-    {
-        .reg_data = 0x00,
-        .led_status = "fan4_off",
-        .led_id = 3,
-    },
-    {
-        .reg_data = 1 << 6,
-        .led_status = "fan4_green",
-        .led_id = 3,
-    },
-    {
-        .reg_data = 2 << 6,
-        .led_status = "fan4_Amber",
-        .led_id = 3,
-    },
-    {
-        .reg_data = 0x00,
-        .led_status = "fan3_off",
-        .led_id = 4,
-    },
-    {
-        .reg_data = 1 << 4,
-        .led_status = "fan3_green",
-        .led_id = 4,
-    },
-    {
-        .reg_data = 2 << 4,
-        .led_status = "fan3_Amber",
-        .led_id = 4,
-    },
-    {
-        .reg_data = 0x00,
-        .led_status = "fan2_off",
-        .led_id = 5,
-    },
-    {
-        .reg_data = 1 << 2,
-        .led_status = "fan2_green",
-        .led_id = 5,
-    },
-    {
-        .reg_data = 1 << 3,
-        .led_status = "fan2_Amber",
-        .led_id = 5,
-    },
-    {
-        .reg_data = 0x00,
-        .led_status = "fan1_off",
-        .led_id = 6,
-    },
-    {
-        .reg_data = 1,
-        .led_status = "fan1_green",
-        .led_id = 6,
-    },
-    {
-        .reg_data = 2,
-        .led_status = "fan1_Amber",
-        .led_id = 6,
-    },
-};
-	
-struct platform_led_data{
-	int reg_addr;	
-	int mask;		
-};
-	
-static struct platform_led_data led_data[] = {	
-    {
-		.reg_addr = LED_REG,    //0x04
-		.mask = 0xc0,//1100 0000		
-	},
-	{
-		.reg_addr = LED_REG,
-        .mask = 0x30,//0011 0000	
-	},
-	{
-		.reg_addr = LED_REG,
-        .mask = 0x06,//0000 0110	
-	},
-    {
-        .reg_addr = FAN_LED_REG,//0x05
-        .mask = 0xc0,//1100 0000        
-    },
-    {
-        .reg_addr = FAN_LED_REG,
-        .mask = 0x30,//0011 0000    
-    },
-    {
-        .reg_addr = FAN_LED_REG,
-        .mask = 0x0c,//0000 1100    
-    },
-    {
-        .reg_addr = FAN_LED_REG,
-        .mask = 0x03,//0000 0011
-    },  
-};
-	
-
-static ssize_t get_led_color(struct device *dev, struct device_attribute *devattr, char *buf)
-{
-    char str[9][20] = {0};
-    int board_data;
-	int led_data_number;
-	int led_info_number;
-    struct cpld_platform_data *pdata = dev->platform_data;
-
-	for(led_data_number = 0; led_data_number < ARRAY_SIZE(led_data); led_data_number++){	
-        board_data = i2c_smbus_read_byte_data(pdata[slave_cpld].client, led_data[led_data_number].reg_addr);	
-        if(board_data >= 0){
-		    board_data &= led_data[led_data_number].mask;		
-		    for(led_info_number = 0; led_info_number < ARRAY_SIZE(led_info); led_info_number++){
-	            if (led_data_number == led_info[led_info_number].led_id \
-                    && board_data == led_info[led_info_number].reg_data){
-                    sprintf(str[led_data_number], "%s", led_info[led_info_number].led_status);
-			    }		
-		    }
-		}
-		else
-			printk( KERN_ERR "Missing LED board data\n");
-	}		    		
-	return sprintf(buf,"%s\n%s\n%s\n%s\n%s\n%s\n%s\n",str[0],str[1],str[2],str[3],str[4],str[5],str[6]);
-}
-
-static ssize_t set_led_color(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
-{
-	int led_info_number;
-	int led_data_number;
-	int str_compar;
-	int led_reg_value;
-    struct cpld_platform_data *pdata = dev->platform_data;
-	
-	for(led_info_number = 0; led_info_number < ARRAY_SIZE(led_info); led_info_number++){
-		str_compar = strncmp(buf,led_info[led_info_number].led_status,strlen(led_info[led_info_number].led_status));
-		if(str_compar == 0){									
-			for(led_data_number = 0; led_data_number < ARRAY_SIZE(led_data); led_data_number++){				
-			    if(led_info[led_info_number].led_id == led_data_number){
-					led_reg_value = i2c_smbus_read_byte_data(pdata[slave_cpld].client, led_data[led_data_number].reg_addr);
-                    if(led_reg_value >= 0){					
-			            led_reg_value &= (~led_data[led_data_number].mask);					
-				        led_reg_value |= led_info[led_info_number].reg_data;					
-					    i2c_smbus_write_byte_data(pdata[slave_cpld].client, (u8)(led_data[led_data_number].reg_addr & 0xff), (u8)(led_reg_value & 0xff));
-					}
-					else
-						printk( KERN_ERR "Missing LED reg. data\n");
-				}
-		    }
-		}
-	}
-    return count;
-}
-
-static DEVICE_ATTR(sfp_response, S_IWUSR | S_IRUGO, get_response,  set_response );
-static DEVICE_ATTR(sfp_present,  S_IRUGO,           get_present,   NULL         );
-static DEVICE_ATTR(sfp_lpmode,   S_IWUSR | S_IRUGO, get_lpmode,    set_lpmode   );
-static DEVICE_ATTR(sfp_reset,    S_IWUSR | S_IRUGO, get_reset,     set_reset    );
-
-static DEVICE_ATTR(led_control,  S_IRUGO | S_IWUSR, get_led_color, set_led_color);
-
-static struct attribute *ag5648_cpld_attrs[] = {
-    &dev_attr_sfp_response.attr,    
-    &dev_attr_sfp_present.attr,
-    &dev_attr_sfp_lpmode.attr,
-    &dev_attr_sfp_reset.attr,
-    &dev_attr_led_control.attr,
-    NULL,
-};
-
-static struct attribute_group ag5648_cpld_attr_grp = {
-    .attrs = ag5648_cpld_attrs,
-};
-
-/*    CPLD  -- driver   */
-static int __init cpld_probe(struct platform_device *pdev)
-{
-    struct cpld_platform_data *pdata;
-    struct i2c_adapter *parent;
-    int ret,i;
-
-    pdata = pdev->dev.platform_data;
-    if (!pdata) {
-        dev_err(&pdev->dev, "CPLD platform data not found\n");
-        return -ENODEV;
-    }
-
-    parent = i2c_get_adapter(BUS2);
-    if (!parent) {
-        printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS2);
-        return -ENODEV;
-    }
-
-    for (i = 0; i < ARRAY_SIZE(ag5648_cpld_platform_data); i++) {
-        pdata[i].client = i2c_new_dummy(parent, pdata[i].reg_addr);
-        if (!pdata[i].client) {
-            printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[i].reg_addr);
-            goto error;
-        }
-    }
-
-    ret = sysfs_create_group(&pdev->dev.kobj, &ag5648_cpld_attr_grp);
-    if (ret) {
-        printk(KERN_WARNING "Fail to create cpld attribute group");
-        goto error;
-    }
-
-    return 0;
-
-error:    
-    i--;
-    for (; i >= 0; i--) {
-        if (pdata[i].client) {
-            i2c_unregister_device(pdata[i].client);
-        }
-    }
-    i2c_put_adapter(parent);
-    
-    return -ENODEV; 
-}
-
-static int __exit cpld_remove(struct platform_device *pdev)
-{
-    struct i2c_adapter *parent = NULL;
-    struct cpld_platform_data *pdata = pdev->dev.platform_data;
-    int i;
-    sysfs_remove_group(&pdev->dev.kobj, &ag5648_cpld_attr_grp);
-
-    if (!pdata) {
-        dev_err(&pdev->dev, "Missing platform data\n");
-    } 
-    else {
-        for (i = 0; i < ARRAY_SIZE(ag5648_cpld_platform_data); i++) {
-            if (pdata[i].client) {
-                if (!parent) {
-                    parent = (pdata[i].client)->adapter;
-                }
-                i2c_unregister_device(pdata[i].client);
-            }
-        }
-    }
-
-    i2c_put_adapter(parent);
-
-    return 0;
-}
-
-static struct platform_driver cpld_driver = {
-    .probe  = cpld_probe,
-    .remove = __exit_p(cpld_remove),
-    .driver = {
-        .owner  = THIS_MODULE,
-        .name   = "delta-ag5648-cpld",
-    },
-};
-
-/*----------------    CPLD  - end   ------------- */
-
-/*----------------    MUX   - start   ------------- */
-
-struct swpld_mux_platform_data {
-    int parent;
-    int base_nr;
-    int reg_addr;
-    struct i2c_client *cpld;
-};
-
-struct swpld_mux {
-    struct i2c_adapter *parent;
-    struct i2c_adapter **child;
-    struct swpld_mux_platform_data data;
-};
-
-static struct swpld_mux_platform_data ag5648_swpld_mux_platform_data[] = {
-    {
-        .parent         = BUS4, 
-        .base_nr        = BUS4_BASE_NUM, 
-        .cpld           = NULL,
-        .reg_addr       = BUS4_MUX_REG ,
-    },
-};
-
-
-static struct platform_device ag5648_swpld_mux[] = {
-    {
-        .name           = "delta-ag5648-swpld-mux",
-        .id             = 0,
-        .dev            = {
-                .platform_data   = &ag5648_swpld_mux_platform_data[0],
-                .release         = device_release,
-        },
-    },
-};
-
-
-static int cpld_reg_write_byte(struct i2c_client *client, u8 regaddr, u8 val)
-{
-    union i2c_smbus_data data;
-
-    data.byte = val;
-    return client->adapter->algo->smbus_xfer(client->adapter, client->addr,
-                                             client->flags,
-                                             I2C_SMBUS_WRITE,
-                                             regaddr, I2C_SMBUS_BYTE_DATA, &data);
-}
-
-static int swpld_mux_select(struct i2c_adapter *adap, void *data, u8 chan)
-{
-    struct swpld_mux *mux = data;
-    u8 swpld_mux_val=0; 
-    if ( mux->data.base_nr == BUS4_BASE_NUM )
-    {
-        swpld_mux_val = (chan + 0x01);
-    }
-    else
-    {
-        swpld_mux_val = 0x00;
-    }
-    swpld_mux_val=swpld_mux_val & (u8)0x3F;
-
-    return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(swpld_mux_val & 0xff));
-}
-
-static int __init swpld_mux_probe(struct platform_device *pdev)
-{
-    struct swpld_mux *mux;
-    struct swpld_mux_platform_data *pdata;
-    struct i2c_adapter *parent;
-    int i, ret, dev_num;
-
-    pdata = pdev->dev.platform_data;
-    if (!pdata) {
-        dev_err(&pdev->dev, "SWPLD platform data not found\n");
-        return -ENODEV;
-    }
-
-    parent = i2c_get_adapter(pdata->parent);
-    if (!parent) {
-        dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent);
-        return -ENODEV;
-    }
-
-    /* Judge bus number to decide how many devices*/
-    switch (pdata->parent) {
-        case BUS4:
-            dev_num = BUS4_DEV_NUM;
-            break;
-        default :
-            dev_num = DEFAULT_NUM;  
-            break;
-    }
-
-    mux = kzalloc(sizeof(*mux), GFP_KERNEL);
-    if (!mux) {
-        ret = -ENOMEM;
-        printk(KERN_ERR "Failed to allocate memory for mux\n");
-        goto alloc_failed;
-    }
-
-    mux->parent = parent;
-    mux->data = *pdata;
-    mux->child = kzalloc(sizeof(struct i2c_adapter *) * dev_num, GFP_KERNEL);
-    if (!mux->child) {
-        ret = -ENOMEM;
-        printk(KERN_ERR "Failed to allocate memory for device on mux\n");
-        goto alloc_failed2;
-    }
-
-    for (i = 0; i < dev_num; i++) {
-        int nr = pdata->base_nr + i;
-        unsigned int class = 0;
-
-        mux->child[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux,
-                           nr, i, class,
-                           swpld_mux_select, NULL);
-        if (!mux->child[i]) {
-            ret = -ENODEV;
-            dev_err(&pdev->dev, "Failed to add adapter %d\n", i);
-            goto add_adapter_failed;
-        }
-    }
-
-    platform_set_drvdata(pdev, mux);
-    return 0;
-
-add_adapter_failed:
-    for (; i > 0; i--)
-        i2c_del_mux_adapter(mux->child[i - 1]);
-    kfree(mux->child);
-alloc_failed2:
-    kfree(mux);
-alloc_failed:
-    i2c_put_adapter(parent);
-
-    return ret;
-}
-
-
-static int __exit swpld_mux_remove(struct platform_device *pdev)
-{
-    int i;
-    struct swpld_mux *mux = platform_get_drvdata(pdev);
-    struct swpld_mux_platform_data *pdata;
-    struct i2c_adapter *parent;
-    int dev_num;
-
-    pdata = pdev->dev.platform_data;
-    if (!pdata) {
-        dev_err(&pdev->dev, "SWPLD platform data not found\n");
-        return -ENODEV;
-    }
-
-    parent = i2c_get_adapter(pdata->parent);
-    if (!parent) {
-        dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
-            pdata->parent);
-        return -ENODEV;
-    }
-    switch (pdata->parent) {
-        case BUS4:
-            dev_num = BUS4_DEV_NUM;
-            break;
-        default :
-            dev_num = DEFAULT_NUM;  
-            break;
-    }
-
-    for (i = 0; i < dev_num; i++)
-        i2c_del_mux_adapter(mux->child[i]);
-
-    platform_set_drvdata(pdev, NULL);
-    i2c_put_adapter(mux->parent);
-    kfree(mux->child);
-    kfree(mux);
-
-    return 0;
-}
-
-static struct platform_driver swpld_mux_driver = {
-    .probe  = swpld_mux_probe,
-    .remove = __exit_p(swpld_mux_remove), /* TODO */
-    .driver = {
-        .owner  = THIS_MODULE,
-        .name   = "delta-ag5648-swpld-mux",
-    },
-};
-/*----------------    MUX   - end   ------------- */
-
-
-/*----------------   module initialization     ------------- */
-static void __init delta_ag5648_platform_init(void)
-{
-    struct i2c_client *client;
-    struct i2c_adapter *adapter;
-    struct cpld_platform_data *cpld_pdata;
-    struct swpld_mux_platform_data *swpld_pdata;
-    int ret,i = 0;
-
-    //Use pca9547 in i2c_mux_pca954x.c
-    adapter = i2c_get_adapter(BUS1); 
-    //client = i2c_new_device(adapter, &i2c_info_pca9548[0]);
-    i2c_client_9548 = i2c_new_device(adapter, &i2c_info_pca9548[0]);
-    i2c_put_adapter(adapter);
-
-    // set the CPLD prob and remove
-    ret = platform_driver_register(&cpld_driver);
-    if (ret) {
-        printk(KERN_WARNING "Fail to register cpld driver\n");
-        goto error_cpld_driver;
-    }
-
-    // register the mux prob which call the CPLD
-    ret = platform_driver_register(&swpld_mux_driver);
-    if (ret) {
-        printk(KERN_WARNING "Fail to register swpld mux driver\n");
-        goto error_swpld_mux_driver;
-    }
-
-    // register the i2c devices    
-    ret = platform_driver_register(&i2c_device_driver);
-    if (ret) {
-        printk(KERN_WARNING "Fail to register i2c device driver\n");
-        goto error_i2c_device_driver;
-    }
-
-    // register the CPLD
-    ret = platform_device_register(&ag5648_cpld);
-    if (ret) {
-        printk(KERN_WARNING "Fail to create cpld device\n");
-        goto error_ag5648_cpld;
-    }
-    // link the CPLD and the Mux
-    cpld_pdata = ag5648_cpld.dev.platform_data;
-
-
-    swpld_pdata = ag5648_swpld_mux[0].dev.platform_data;
-    swpld_pdata->cpld = cpld_pdata[master_cpld].client;  
-    ret = platform_device_register(&ag5648_swpld_mux[0]);          
-    if (ret) {
-        printk(KERN_WARNING "Fail to create swpld mux %d\n", i);
-        goto error_ag5648_swpld_mux;
-    }
-    
-    for (i = 0; i < ARRAY_SIZE(ag5648_i2c_device); i++)
-    {
-        ret = platform_device_register(&ag5648_i2c_device[i]);
-        if (ret) {
-            printk(KERN_WARNING "Fail to create i2c device %d\n", i);
-            goto error_ag5648_i2c_device;
-        }
-    }
-
-    if (ret)
-        goto error_ag5648_swpld_mux;
-
-    return 0;
-
-error_ag5648_i2c_device:
-    i--;
-    for (; i >= 0; i--) {
-        platform_device_unregister(&ag5648_i2c_device[i]);
-    }
-    i = ARRAY_SIZE(ag5648_swpld_mux);    
-error_ag5648_swpld_mux:
-    i--;
-    for (; i >= 0; i--) {
-        platform_device_unregister(&ag5648_swpld_mux[0]);
-    }
-    platform_driver_unregister(&ag5648_cpld);
-error_ag5648_cpld:
-    platform_driver_unregister(&i2c_device_driver);
-error_i2c_device_driver:
-    platform_driver_unregister(&swpld_mux_driver);
-error_swpld_mux_driver:
-    platform_driver_unregister(&cpld_driver);
-error_cpld_driver:
-    return ret;
-}
-
-static void __exit delta_ag5648_platform_exit(void)
-{
-    int i = 0;
-
-    for ( i = 0; i < ARRAY_SIZE(ag5648_i2c_device); i++ ) {
-        platform_device_unregister(&ag5648_i2c_device[i]);
-    }
-
-    for (i = 0; i < ARRAY_SIZE(ag5648_swpld_mux); i++) {
-        platform_device_unregister(&ag5648_swpld_mux[i]);
-    }
-
-    platform_device_unregister(&ag5648_cpld);
-    platform_driver_unregister(&i2c_device_driver);
-    platform_driver_unregister(&cpld_driver);
-    platform_driver_unregister(&swpld_mux_driver);
-
-    i2c_unregister_device(i2c_client_9548);
-}
-
-module_init(delta_ag5648_platform_init);
-module_exit(delta_ag5648_platform_exit);
-
-MODULE_DESCRIPTION("DNI ag5648 Platform Support");
-MODULE_AUTHOR("Neal Tai <neal.tai@deltaww.com>");
-MODULE_LICENSE("GPL");    
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/dmi.h>
+#include <linux/version.h>
+#include <linux/ctype.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca954x.h>
+#include <linux/i2c-mux.h>
+#include <linux/i2c-mux-gpio.h>
+#include <linux/i2c/sff-8436.h>
+
+#define BUS4_DEV_NUM    54
+#define DEFAULT_NUM      1
+#define BUS4_BASE_NUM   10
+#define BUS4_MUX_REG  0x18
+
+#define TEMP_FAN_VAL  0x06
+#define FANIO_CTL_VAL 0x07
+#define FAN_CTRL_VAL  0x05
+#define PSU1_VAL      0x00
+#define PSU2_VAL      0x20
+#define HOT_SWAP1_VAL 0x10
+#define HOT_SWAP2_VAL 0x30
+
+#define SYSTEM_CPLD_REG  0x31
+#define MASTER_CPLD_REG  0x35
+#define SLAVE_CPLD_REG   0x39
+
+#define FAN_LED_REG      0x05
+#define LED_REG          0x04
+
+#define SFP_PRESENCE_1   0x08
+#define SFP_PRESENCE_2   0x09
+#define SFP_PRESENCE_3   0x0a
+#define SFP_PRESENCE_4   0x0b
+#define SFP_PRESENCE_5   0x0c
+#define SFP_PRESENCE_6   0x08
+#define SFP_PRESENCE_7   0x09
+#define QSFP_PRESENCE    0x12
+        
+#define QSFP_RESPONSE    0x10
+#define QSFP_LP_MODE     0x11
+#define QSFP_RESET       0x13        
+
+
+#define SFF8436_INFO(data) \
+    .type = "sff8436", .addr = 0x50, .platform_data = (data)
+
+#define SFF_8436_PORT(eedata) \
+    .byte_len = 256, .page_size = 1, .flags = SFF_8436_FLAG_READONLY
+	
+#define ag5648_i2c_device_num(NUM){                                           \
+        .name                   = "delta-ag5648-i2c-device",                  \
+        .id                     = NUM,                                        \
+        .dev                    = {                                           \
+                    .platform_data = &ag5648_i2c_device_platform_data[NUM],   \
+                    .release       = device_release,                          \
+        },                                                                    \
+}
+
+/*Define struct to get client of i2c_new_deivce */
+struct i2c_client * i2c_client_9548;
+
+enum{
+    BUS0 = 0,
+    BUS1,
+    BUS2,
+    BUS3,
+    BUS4,
+    BUS5,
+    BUS6,
+    BUS7,
+};
+
+unsigned char reverse_8bits(unsigned char c)
+{
+        unsigned char s = 0;
+        int i;
+        for (i = 0; i < 8; ++i) {
+                s <<= 1;
+                s |= c & 1;
+                c >>= 1;
+        }
+        return s;
+}
+/*----------------   I2C device   - start   ------------- */
+static void device_release(struct device *dev)
+{
+    return;
+}
+
+struct i2c_device_platform_data {
+    int parent;
+    struct i2c_board_info           info;
+    struct i2c_client              *client;
+};
+/* pca9548 - add 8 bus */
+static struct pca954x_platform_mode pca954x_mode[] = {
+  { .adap_id = 2,
+    .deselect_on_exit = 1,
+  },
+  { .adap_id = 3,
+    .deselect_on_exit = 1,
+  },
+  { .adap_id = 4,
+    .deselect_on_exit = 1,
+  },
+  { .adap_id = 5,
+    .deselect_on_exit = 1,
+  },
+  { .adap_id = 6,
+    .deselect_on_exit = 1,
+  },
+  { .adap_id = 7,
+    .deselect_on_exit = 1,
+  },
+  { .adap_id = 8,
+    .deselect_on_exit = 1,
+  },
+  { .adap_id = 9,
+    .deselect_on_exit = 1,
+  },
+};
+
+static struct pca954x_platform_data pca954x_data = {
+  .modes = pca954x_mode,
+  .num_modes = ARRAY_SIZE(pca954x_mode),
+};
+
+static struct i2c_board_info __initdata i2c_info_pca9548[] =
+{
+        {
+            I2C_BOARD_INFO("pca9548", 0x70),
+            .platform_data = &pca954x_data, 
+        },
+};
+
+
+static struct sff_8436_platform_data sff_8436_port[] = {
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+    { SFF_8436_PORT() },
+};
+
+
+static struct i2c_device_platform_data ag5648_i2c_device_platform_data[] = {
+    {
+        /* id eeprom (0x53) */
+        .parent = 2,
+        .info = { I2C_BOARD_INFO("24c02", 0x53) },
+        .client = NULL,
+    },
+    {
+        /* tmp75 (0x4d) */
+        .parent = 2,
+        .info = { I2C_BOARD_INFO("tmp75", 0x4d) },
+        .client = NULL,
+    },
+    {
+        /* tmp75 (0x49) */
+        .parent = 3,
+        .info = { I2C_BOARD_INFO("tmp75", 0x49) },
+        .client = NULL,
+    },
+    {
+        /* tmp75 (0x4b) */
+        .parent = 3,
+        .info = { I2C_BOARD_INFO("tmp75", 0x4b) },
+    },
+    {
+        /* tmp75 (0x4c) */
+        .parent = 3,
+        .info = { I2C_BOARD_INFO("tmp75", 0x4c) },
+        .client = NULL,
+    },
+    {
+        /* tmp75 (0x4e) */
+        .parent = 3,
+        .info = { I2C_BOARD_INFO("tmp75", 0x4e) },
+        .client = NULL,
+    },
+    {
+        /* tmp75 (0x4f) */
+        .parent = 3,
+        .info = { I2C_BOARD_INFO("tmp75", 0x4f) },
+    },
+    {
+        /* tmp75 (0x4d) */
+        .parent = 3,
+        .info = { I2C_BOARD_INFO("emc2305", 0x4d) },
+        .client = NULL,
+    },
+    {
+        /* tmp75 (0x4d) */
+        .parent = 5,
+        .info = { I2C_BOARD_INFO("emc2305", 0x4d) },
+        .client = NULL,
+    },
+    {
+        /* tmp75 (0x40) */
+        .parent = 3,
+        .info = { I2C_BOARD_INFO("ltc4215", 0x40) },
+        .client = NULL,
+    },
+    {
+        /* tmp75 (0x42) */
+        .parent = 3,
+        .info = { I2C_BOARD_INFO("ltc4215", 0x42) },
+    },
+    {
+        /* psu1 (0x59) */
+        .parent = 6,
+        .info = { I2C_BOARD_INFO("dni_ag5648_psu", 0x59) },
+        .client = NULL,
+    },
+    {
+        /* psu2 (0x58) */
+        .parent = 6,
+        .info = { I2C_BOARD_INFO("dni_ag5648_psu", 0x58) },
+    },
+    {
+        /* qsfp 1 (0x50) */
+        .parent = 10,
+        .info = { SFF8436_INFO(&sff_8436_port[0]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 2 (0x50) */
+        .parent = 11,
+        .info = { SFF8436_INFO(&sff_8436_port[1]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 3 (0x50) */
+        .parent = 12,
+        .info = { SFF8436_INFO(&sff_8436_port[2]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 4 (0x50) */
+        .parent = 13,
+        .info = { SFF8436_INFO(&sff_8436_port[3]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 5 (0x50) */
+        .parent = 14,
+        .info = { SFF8436_INFO(&sff_8436_port[4]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 6 (0x50) */
+        .parent = 15,
+        .info = { SFF8436_INFO(&sff_8436_port[5]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 7 (0x50) */
+        .parent = 16,
+        .info = { SFF8436_INFO(&sff_8436_port[6]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 8 (0x50) */
+        .parent = 17,
+        .info = { SFF8436_INFO(&sff_8436_port[7]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 9 (0x50) */
+        .parent = 18,
+        .info = { SFF8436_INFO(&sff_8436_port[8]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 10 (0x50) */
+        .parent = 19,
+        .info = { SFF8436_INFO(&sff_8436_port[9]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 11 (0x50) */
+        .parent = 20,
+        .info = { SFF8436_INFO(&sff_8436_port[10]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 12 (0x50) */
+        .parent = 21,
+        .info = { SFF8436_INFO(&sff_8436_port[11]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 13 (0x50) */
+        .parent = 22,
+        .info = { SFF8436_INFO(&sff_8436_port[12]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 14 (0x50) */
+        .parent = 23,
+        .info = { SFF8436_INFO(&sff_8436_port[13]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 15 (0x50) */
+        .parent = 24,
+        .info = { SFF8436_INFO(&sff_8436_port[14]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 16 (0x50) */
+        .parent = 25,
+        .info = { SFF8436_INFO(&sff_8436_port[15]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 17 (0x50) */
+        .parent = 26,
+        .info = { SFF8436_INFO(&sff_8436_port[16]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 18 (0x50) */
+        .parent = 27,
+        .info = { SFF8436_INFO(&sff_8436_port[17]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 19 (0x50) */
+        .parent = 28,
+        .info = { SFF8436_INFO(&sff_8436_port[18]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 20 (0x50) */
+        .parent = 29,
+        .info = { SFF8436_INFO(&sff_8436_port[19]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 21 (0x50) */
+        .parent = 30,
+        .info = { SFF8436_INFO(&sff_8436_port[20]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 22 (0x50) */
+        .parent = 31,
+        .info = { SFF8436_INFO(&sff_8436_port[21]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 23 (0x50) */
+        .parent = 32,
+        .info = { SFF8436_INFO(&sff_8436_port[22]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 24 (0x50) */
+        .parent = 33,
+        .info = { SFF8436_INFO(&sff_8436_port[23]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 25 (0x50) */
+        .parent = 34,
+        .info = { SFF8436_INFO(&sff_8436_port[24]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 26 (0x50) */
+        .parent = 35,
+        .info = { SFF8436_INFO(&sff_8436_port[25]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 27 (0x50) */
+        .parent = 36,
+        .info = { SFF8436_INFO(&sff_8436_port[26]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 28 (0x50) */
+        .parent = 37,
+        .info = { SFF8436_INFO(&sff_8436_port[27]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 29 (0x50) */
+        .parent = 38,
+        .info = { SFF8436_INFO(&sff_8436_port[28]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 30 (0x50) */
+        .parent = 39,
+        .info = { SFF8436_INFO(&sff_8436_port[29]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 31 (0x50) */
+        .parent = 40,
+        .info = { SFF8436_INFO(&sff_8436_port[30]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 32 (0x50) */
+        .parent = 41,
+        .info = { SFF8436_INFO(&sff_8436_port[31]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 33 (0x50) */
+        .parent = 42,
+        .info = { SFF8436_INFO(&sff_8436_port[32]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 34 (0x50) */
+        .parent = 43,
+        .info = { SFF8436_INFO(&sff_8436_port[33]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 35 (0x50) */
+        .parent = 44,
+        .info = { SFF8436_INFO(&sff_8436_port[34]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 36 (0x50) */
+        .parent = 45,
+        .info = { SFF8436_INFO(&sff_8436_port[35]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 37 (0x50) */
+        .parent = 46,
+        .info = { SFF8436_INFO(&sff_8436_port[36]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 38 (0x50) */
+        .parent = 47,
+        .info = { SFF8436_INFO(&sff_8436_port[37]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 39 (0x50) */
+        .parent = 48,
+        .info = { SFF8436_INFO(&sff_8436_port[38]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 40 (0x50) */
+        .parent = 49,
+        .info = { SFF8436_INFO(&sff_8436_port[39]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 41 (0x50) */
+        .parent = 50,
+        .info = { SFF8436_INFO(&sff_8436_port[40]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 42 (0x50) */
+        .parent = 51,
+        .info = { SFF8436_INFO(&sff_8436_port[41]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 43 (0x50) */
+        .parent = 52,
+        .info = { SFF8436_INFO(&sff_8436_port[42]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 44 (0x50) */
+        .parent = 53,
+        .info = { SFF8436_INFO(&sff_8436_port[43]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 45 (0x50) */
+        .parent = 54,
+        .info = { SFF8436_INFO(&sff_8436_port[44]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 46 (0x50) */
+        .parent = 55,
+        .info = { SFF8436_INFO(&sff_8436_port[45]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 47 (0x50) */
+        .parent = 56,
+        .info = { SFF8436_INFO(&sff_8436_port[46]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 48 (0x50) */
+        .parent = 57,
+        .info = { SFF8436_INFO(&sff_8436_port[47]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 49 (0x50) */
+        .parent = 58,
+        .info = { SFF8436_INFO(&sff_8436_port[48]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 50 (0x50) */
+        .parent = 59,
+        .info = { SFF8436_INFO(&sff_8436_port[49]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 51 (0x50) */
+        .parent = 60,
+        .info = { SFF8436_INFO(&sff_8436_port[50]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 52 (0x50) */
+        .parent = 61,
+        .info = { SFF8436_INFO(&sff_8436_port[51]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 53 (0x50) */
+        .parent = 62,
+        .info = { SFF8436_INFO(&sff_8436_port[52]) },
+        .client = NULL,
+    },
+    {
+        /* qsfp 54 (0x50) */
+        .parent = 63,
+        .info = { SFF8436_INFO(&sff_8436_port[53]) },
+        .client = NULL,
+    },
+};
+
+
+static struct platform_device ag5648_i2c_device[] = {
+    ag5648_i2c_device_num(0),
+    ag5648_i2c_device_num(1),
+    ag5648_i2c_device_num(2),
+    ag5648_i2c_device_num(3),
+    ag5648_i2c_device_num(4),
+    ag5648_i2c_device_num(5),
+    ag5648_i2c_device_num(6),
+    ag5648_i2c_device_num(7),
+    ag5648_i2c_device_num(8),
+    ag5648_i2c_device_num(9),
+    ag5648_i2c_device_num(10),
+    ag5648_i2c_device_num(11),
+    ag5648_i2c_device_num(12),   
+    ag5648_i2c_device_num(13),
+    ag5648_i2c_device_num(14),
+    ag5648_i2c_device_num(15),
+    ag5648_i2c_device_num(16),
+    ag5648_i2c_device_num(17),
+    ag5648_i2c_device_num(18),
+    ag5648_i2c_device_num(19),
+    ag5648_i2c_device_num(20),
+    ag5648_i2c_device_num(21),
+    ag5648_i2c_device_num(22),
+    ag5648_i2c_device_num(23),
+    ag5648_i2c_device_num(24),
+    ag5648_i2c_device_num(25),
+    ag5648_i2c_device_num(26),
+    ag5648_i2c_device_num(27),
+    ag5648_i2c_device_num(28),
+    ag5648_i2c_device_num(29),
+    ag5648_i2c_device_num(30),
+    ag5648_i2c_device_num(31),
+    ag5648_i2c_device_num(32),
+    ag5648_i2c_device_num(33),
+    ag5648_i2c_device_num(34),
+    ag5648_i2c_device_num(35),
+    ag5648_i2c_device_num(36),
+    ag5648_i2c_device_num(37),
+    ag5648_i2c_device_num(38),
+    ag5648_i2c_device_num(39),
+    ag5648_i2c_device_num(40),
+    ag5648_i2c_device_num(41),
+    ag5648_i2c_device_num(42),
+    ag5648_i2c_device_num(43),
+    ag5648_i2c_device_num(44),
+    ag5648_i2c_device_num(45),
+    ag5648_i2c_device_num(46),
+    ag5648_i2c_device_num(47),
+    ag5648_i2c_device_num(48),
+    ag5648_i2c_device_num(49),
+    ag5648_i2c_device_num(50),
+    ag5648_i2c_device_num(51),
+    ag5648_i2c_device_num(52),
+    ag5648_i2c_device_num(53),
+    ag5648_i2c_device_num(54),
+    ag5648_i2c_device_num(55),
+    ag5648_i2c_device_num(56),
+    ag5648_i2c_device_num(57),
+    ag5648_i2c_device_num(58),
+    ag5648_i2c_device_num(59),
+    ag5648_i2c_device_num(60),
+    ag5648_i2c_device_num(61),
+    ag5648_i2c_device_num(62),
+    ag5648_i2c_device_num(63),
+    ag5648_i2c_device_num(64),
+    ag5648_i2c_device_num(65),
+    ag5648_i2c_device_num(66),
+};
+ 
+/*----------------   I2C device   - end   ------------- */
+
+/*----------------   I2C driver   - start   ------------- */
+static int __init i2c_device_probe(struct platform_device *pdev)
+{
+    struct i2c_device_platform_data *pdata;
+    struct i2c_adapter *parent;
+
+    pdata = pdev->dev.platform_data;
+    if (!pdata) {
+        dev_err(&pdev->dev, "Missing platform data\n");
+        return -ENODEV;
+    }
+
+    parent = i2c_get_adapter(pdata->parent);
+    if (!parent) {
+        dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
+            pdata->parent);
+        return -ENODEV;
+    }
+
+    pdata->client = i2c_new_device(parent, &pdata->info);
+    if (!pdata->client) {
+        dev_err(&pdev->dev, "Failed to create i2c client %s at %d\n",
+            pdata->info.type, pdata->parent);
+        return -ENODEV;
+    }
+
+    return 0;
+}
+
+static int __exit i2c_deivce_remove(struct platform_device *pdev)
+{
+    struct i2c_adapter *parent;
+    struct i2c_device_platform_data *pdata;
+
+    pdata = pdev->dev.platform_data;
+    if (!pdata) {
+        dev_err(&pdev->dev, "Missing platform data\n");
+        return -ENODEV;
+    }
+
+    if (pdata->client) {
+	parent = (pdata->client)->adapter;
+        i2c_unregister_device(pdata->client);
+        i2c_put_adapter(parent);
+    }
+
+    return 0;
+}
+static struct platform_driver i2c_device_driver = {
+    .probe = i2c_device_probe,
+    .remove = __exit_p(i2c_deivce_remove),
+    .driver = {
+        .owner = THIS_MODULE,
+        .name = "delta-ag5648-i2c-device",
+    }
+};
+
+/*----------------   I2C driver   - end   ------------- */
+
+/*----------------    CPLD - start   ------------- */
+
+/*    CPLD  -- device   */
+
+enum cpld_type {
+    system_cpld,
+    master_cpld,
+    slave_cpld,
+};
+
+struct cpld_platform_data {
+    int reg_addr;
+    struct i2c_client *client;
+};
+
+static struct cpld_platform_data ag5648_cpld_platform_data[] = {
+    [system_cpld] = {
+        .reg_addr = SYSTEM_CPLD_REG,
+    },
+    [master_cpld] = {
+        .reg_addr = MASTER_CPLD_REG,
+    },
+    [slave_cpld] = {
+        .reg_addr = SLAVE_CPLD_REG,
+    },
+};
+
+static struct platform_device ag5648_cpld = {
+    .name               = "delta-ag5648-cpld",
+    .id                 = 0,
+    .dev                = {
+                .platform_data   = ag5648_cpld_platform_data,
+                .release         = device_release
+    },
+};
+
+static ssize_t get_present(struct device *dev, struct device_attribute \
+                            *dev_attr, char *buf)
+{
+    int ret;
+    u32 data = 0;
+    u32 data2 = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_1);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data = (u32)(ret & 0xff);
+
+    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_2);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data |= (u32)(ret & 0xff) << 8;
+
+    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_3);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data |= (u32)(ret & 0xff) << 16;
+
+    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_4);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data |= (u32)(ret & 0xff) << 24;
+
+    ret = i2c_smbus_read_byte_data(pdata[slave_cpld].client, SFP_PRESENCE_5);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data2 = ((u32)(ret & 0xf)) ;
+
+    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, SFP_PRESENCE_6);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data2 |= (u32)(ret & 0xff) << 4;
+
+    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, SFP_PRESENCE_7);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data2 |= (u32)((ret >> 4) & 0xf) << 12;
+
+    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, QSFP_PRESENCE);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data2 |= (u32)(ret & 0x3f) << 16;
+
+    return sprintf(buf, "0x%06x%x\n", data2, data);
+}
+
+static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr, char *buf) 
+{
+    int ret;
+    u32 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, QSFP_LP_MODE);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data = ((u8)ret & 0x3f) ;
+
+    return sprintf(buf, "0x%02x%012x\n", data, 0);
+}
+
+static ssize_t set_lpmode(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) 
+{
+    unsigned long data;
+    int err;
+
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    err = kstrtoul(buf, 16, &data);
+    if (err)
+        return err;
+    
+    data = data >> 48;
+    i2c_smbus_write_byte_data(pdata[master_cpld].client, QSFP_LP_MODE, (u8)(data & 0xff));
+
+    return count;
+}
+
+static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, char *buf) 
+{
+    int ret;
+    u32 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, QSFP_RESET);
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+
+    data = ((u8)ret & 0x3f);
+
+    return sprintf(buf, "0x%02x%012x\n", data, 0);
+}
+
+static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) 
+{
+    unsigned long data;
+    int err;
+    struct cpld_platform_data *pdata = dev->platform_data;
+    
+    err = kstrtoul(buf, 16, &data);
+    if (err)
+        return err;
+    data = data >> 48;
+    i2c_smbus_write_byte_data(pdata[master_cpld].client, QSFP_RESET, (u8)(data & 0xff));
+
+    return count;
+}
+
+static ssize_t get_response(struct device *dev, struct device_attribute *devattr, char *buf) 
+{
+    int ret;
+    u8 data = 0;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    ret = i2c_smbus_read_byte_data(pdata[master_cpld].client, QSFP_RESPONSE);
+
+    if (ret < 0)
+        return sprintf(buf, "error number(%d)",ret);
+    data = (u8)ret & 0x3f;
+
+    return sprintf(buf, "0x%02x%012x\n", data, 0);
+}
+
+static ssize_t set_response(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) 
+{
+    unsigned long data;
+    int err;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    err = kstrtoul(buf, 16, &data);
+    if (err)
+        return err;
+    data = data >> 48;
+    i2c_smbus_write_byte_data(pdata[master_cpld].client, QSFP_RESPONSE, (u8)(data & 0xff));
+
+    return count;
+}
+
+struct platform_led_status{
+	int reg_data;
+	char *led_status;
+	int led_id;
+};
+	
+static struct platform_led_status led_info[] = {
+    {
+        .reg_data = 0x00,//0000 0000
+        .led_status = "fan_off",
+        .led_id = 0,
+    },
+    {
+        .reg_data = 1 << 6,//0100 0000
+        .led_status = "fan_Amber",
+        .led_id = 0,
+    },
+    {
+        .reg_data = 2 << 6,//1000 0000
+        .led_status = "fan_green",
+        .led_id = 0,
+    },
+    {
+        .reg_data = 3 << 6,//1100 0000
+        .led_status = "fan_Blinking_yellow",
+        .led_id = 0,
+    },
+    {
+        .reg_data = 0x00,
+        .led_status = "sys_Blinking_green",
+        .led_id = 1,
+    },
+    {
+        .reg_data = 1 << 4,
+        .led_status = "sys_green",
+        .led_id = 1,
+    },
+    {
+        .reg_data = 2 << 4,
+        .led_status = "sys_Amber",
+        .led_id = 1,
+    },
+    {
+        .reg_data = 3 << 4 ,
+        .led_status = "sys_Amber",
+        .led_id = 1,
+    },
+    {
+    	.reg_data = 0x00,
+    	.led_status = "pwr_off",
+    	.led_id = 2,
+    },
+    {
+    	.reg_data = 1 << 1,
+    	.led_status = "pwr_Amber",
+    	.led_id = 2,
+    },
+    {
+    	.reg_data = 2 << 1,
+    	.led_status = "pwr_green",
+    	.led_id = 2,
+    },
+    {
+    	.reg_data = 3 << 1,
+    	.led_status = "pwr_Blinking_Amber",
+    	.led_id = 2,
+    },
+    {
+        .reg_data = 0x00,
+        .led_status = "fan4_off",
+        .led_id = 3,
+    },
+    {
+        .reg_data = 1 << 6,
+        .led_status = "fan4_green",
+        .led_id = 3,
+    },
+    {
+        .reg_data = 2 << 6,
+        .led_status = "fan4_Amber",
+        .led_id = 3,
+    },
+    {
+        .reg_data = 0x00,
+        .led_status = "fan3_off",
+        .led_id = 4,
+    },
+    {
+        .reg_data = 1 << 4,
+        .led_status = "fan3_green",
+        .led_id = 4,
+    },
+    {
+        .reg_data = 2 << 4,
+        .led_status = "fan3_Amber",
+        .led_id = 4,
+    },
+    {
+        .reg_data = 0x00,
+        .led_status = "fan2_off",
+        .led_id = 5,
+    },
+    {
+        .reg_data = 1 << 2,
+        .led_status = "fan2_green",
+        .led_id = 5,
+    },
+    {
+        .reg_data = 1 << 3,
+        .led_status = "fan2_Amber",
+        .led_id = 5,
+    },
+    {
+        .reg_data = 0x00,
+        .led_status = "fan1_off",
+        .led_id = 6,
+    },
+    {
+        .reg_data = 1,
+        .led_status = "fan1_green",
+        .led_id = 6,
+    },
+    {
+        .reg_data = 2,
+        .led_status = "fan1_Amber",
+        .led_id = 6,
+    },
+};
+	
+struct platform_led_data{
+	int reg_addr;	
+	int mask;		
+};
+	
+static struct platform_led_data led_data[] = {	
+    {
+	.reg_addr = LED_REG,    //0x04
+	.mask = 0xc0,//1100 0000		
+    },
+    {
+	.reg_addr = LED_REG,
+        .mask = 0x30,//0011 0000	
+    },
+    {
+	.reg_addr = LED_REG,
+        .mask = 0x06,//0000 0110	
+    },
+    {
+        .reg_addr = FAN_LED_REG,//0x05
+        .mask = 0xc0,//1100 0000        
+    },
+    {
+        .reg_addr = FAN_LED_REG,
+        .mask = 0x30,//0011 0000    
+    },
+    {
+        .reg_addr = FAN_LED_REG,
+        .mask = 0x0c,//0000 1100    
+    },
+    {
+        .reg_addr = FAN_LED_REG,
+        .mask = 0x03,//0000 0011
+    },  
+};
+	
+
+static ssize_t get_led_color(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+    char str[9][20] = {0};
+    int board_data;
+    int led_data_number;
+    int led_info_number;
+    struct cpld_platform_data *pdata = dev->platform_data;
+
+    for(led_data_number = 0; led_data_number < ARRAY_SIZE(led_data); led_data_number++){	
+        board_data = i2c_smbus_read_byte_data(pdata[slave_cpld].client, led_data[led_data_number].reg_addr);	
+        if(board_data >= 0){
+                board_data &= led_data[led_data_number].mask;		
+                for(led_info_number = 0; led_info_number < ARRAY_SIZE(led_info); led_info_number++){
+                    if (led_data_number == led_info[led_info_number].led_id \
+                          && board_data == led_info[led_info_number].reg_data){
+                        sprintf(str[led_data_number], "%s", led_info[led_info_number].led_status);
+                    }		
+                }
+        }
+        else
+            printk( KERN_ERR "Missing LED board data\n");
+        }		    		
+	return sprintf(buf,"%s\n%s\n%s\n%s\n%s\n%s\n%s\n",str[0],str[1],str[2],str[3],str[4],str[5],str[6]);
+}
+
+static ssize_t set_led_color(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count)
+{
+	int led_info_number;
+	int led_data_number;
+	int str_compar;
+	int led_reg_value;
+    struct cpld_platform_data *pdata = dev->platform_data;
+	
+	for(led_info_number = 0; led_info_number < ARRAY_SIZE(led_info); led_info_number++){
+		str_compar = strncmp(buf,led_info[led_info_number].led_status,strlen(led_info[led_info_number].led_status));
+		if(str_compar == 0){									
+			for(led_data_number = 0; led_data_number < ARRAY_SIZE(led_data); led_data_number++){				
+			    if(led_info[led_info_number].led_id == led_data_number){
+					led_reg_value = i2c_smbus_read_byte_data(pdata[slave_cpld].client, led_data[led_data_number].reg_addr);
+                    if(led_reg_value >= 0){					
+			            led_reg_value &= (~led_data[led_data_number].mask);					
+				        led_reg_value |= led_info[led_info_number].reg_data;					
+					    i2c_smbus_write_byte_data(pdata[slave_cpld].client, (u8)(led_data[led_data_number].reg_addr & 0xff), (u8)(led_reg_value & 0xff));
+					}
+					else
+						printk( KERN_ERR "Missing LED reg. data\n");
+				}
+		    }
+		}
+	}
+    return count;
+}
+
+static DEVICE_ATTR(sfp_response, S_IWUSR | S_IRUGO, get_response,  set_response );
+static DEVICE_ATTR(sfp_present,  S_IRUGO,           get_present,   NULL         );
+static DEVICE_ATTR(sfp_lpmode,   S_IWUSR | S_IRUGO, get_lpmode,    set_lpmode   );
+static DEVICE_ATTR(sfp_reset,    S_IWUSR | S_IRUGO, get_reset,     set_reset    );
+
+static DEVICE_ATTR(led_control,  S_IRUGO | S_IWUSR, get_led_color, set_led_color);
+
+static struct attribute *ag5648_cpld_attrs[] = {
+    &dev_attr_sfp_response.attr,    
+    &dev_attr_sfp_present.attr,
+    &dev_attr_sfp_lpmode.attr,
+    &dev_attr_sfp_reset.attr,
+    &dev_attr_led_control.attr,
+    NULL,
+};
+
+static struct attribute_group ag5648_cpld_attr_grp = {
+    .attrs = ag5648_cpld_attrs,
+};
+
+/*    CPLD  -- driver   */
+static int __init cpld_probe(struct platform_device *pdev)
+{
+    struct cpld_platform_data *pdata;
+    struct i2c_adapter *parent;
+    int ret,i;
+
+    pdata = pdev->dev.platform_data;
+    if (!pdata) {
+        dev_err(&pdev->dev, "CPLD platform data not found\n");
+        return -ENODEV;
+    }
+
+    parent = i2c_get_adapter(BUS2);
+    if (!parent) {
+        printk(KERN_WARNING "Parent adapter (%d) not found\n",BUS2);
+        return -ENODEV;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(ag5648_cpld_platform_data); i++) {
+        pdata[i].client = i2c_new_dummy(parent, pdata[i].reg_addr);
+        if (!pdata[i].client) {
+            printk(KERN_WARNING "Fail to create dummy i2c client for addr %d\n", pdata[i].reg_addr);
+            goto error;
+        }
+    }
+
+    ret = sysfs_create_group(&pdev->dev.kobj, &ag5648_cpld_attr_grp);
+    if (ret) {
+        printk(KERN_WARNING "Fail to create cpld attribute group");
+        goto error;
+    }
+
+    return 0;
+
+error:    
+    i--;
+    for (; i >= 0; i--) {
+        if (pdata[i].client) {
+            i2c_unregister_device(pdata[i].client);
+        }
+    }
+    i2c_put_adapter(parent);
+    
+    return -ENODEV; 
+}
+
+static int __exit cpld_remove(struct platform_device *pdev)
+{
+    struct i2c_adapter *parent = NULL;
+    struct cpld_platform_data *pdata = pdev->dev.platform_data;
+    int i;
+    sysfs_remove_group(&pdev->dev.kobj, &ag5648_cpld_attr_grp);
+
+    if (!pdata) {
+        dev_err(&pdev->dev, "Missing platform data\n");
+    } 
+    else {
+        for (i = 0; i < ARRAY_SIZE(ag5648_cpld_platform_data); i++) {
+            if (pdata[i].client) {
+                if (!parent) {
+                    parent = (pdata[i].client)->adapter;
+                }
+                i2c_unregister_device(pdata[i].client);
+            }
+        }
+    }
+
+    i2c_put_adapter(parent);
+
+    return 0;
+}
+
+static struct platform_driver cpld_driver = {
+    .probe  = cpld_probe,
+    .remove = __exit_p(cpld_remove),
+    .driver = {
+        .owner  = THIS_MODULE,
+        .name   = "delta-ag5648-cpld",
+    },
+};
+
+/*----------------    CPLD  - end   ------------- */
+
+/*----------------    MUX   - start   ------------- */
+
+struct swpld_mux_platform_data {
+    int parent;
+    int base_nr;
+    int reg_addr;
+    struct i2c_client *cpld;
+};
+
+struct swpld_mux {
+    struct i2c_adapter *parent;
+    struct i2c_adapter **child;
+    struct swpld_mux_platform_data data;
+};
+
+static struct swpld_mux_platform_data ag5648_swpld_mux_platform_data[] = {
+    {
+        .parent         = BUS4, 
+        .base_nr        = BUS4_BASE_NUM, 
+        .cpld           = NULL,
+        .reg_addr       = BUS4_MUX_REG ,
+    },
+};
+
+
+static struct platform_device ag5648_swpld_mux[] = {
+    {
+        .name           = "delta-ag5648-swpld-mux",
+        .id             = 0,
+        .dev            = {
+                .platform_data   = &ag5648_swpld_mux_platform_data[0],
+                .release         = device_release,
+        },
+    },
+};
+
+
+static int cpld_reg_write_byte(struct i2c_client *client, u8 regaddr, u8 val)
+{
+    union i2c_smbus_data data;
+
+    data.byte = val;
+    return client->adapter->algo->smbus_xfer(client->adapter, client->addr,
+                                             client->flags,
+                                             I2C_SMBUS_WRITE,
+                                             regaddr, I2C_SMBUS_BYTE_DATA, &data);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
+static int swpld_mux_select(struct i2c_adapter *adap, void *data, u8 chan)
+{
+    struct swpld_mux *mux = data;
+    u8 swpld_mux_val=0; 
+    if ( mux->data.base_nr == BUS4_BASE_NUM )
+    {
+        swpld_mux_val = (chan + 0x01);
+    }
+    else
+    {
+        swpld_mux_val = 0x00;
+    }
+    swpld_mux_val=swpld_mux_val & (u8)0x3F;
+
+    return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(swpld_mux_val & 0xff));
+}
+#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+static int swpld_mux_select(struct i2c_mux_core *muxc, u32 chan)
+{
+    struct swpld_mux *mux = i2c_mux_priv(muxc);
+    u8 swpld_mux_val=0; 
+    if ( mux->data.base_nr == BUS4_BASE_NUM )
+    {
+        swpld_mux_val = (chan + 0x01);
+    }
+    else
+    {
+        swpld_mux_val = 0x00;
+    }
+    swpld_mux_val=swpld_mux_val & (u8)0x3F;
+
+    return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(swpld_mux_val & 0xff));
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
+static int __init swpld_mux_probe(struct platform_device *pdev)
+{
+    struct swpld_mux *mux;
+    struct swpld_mux_platform_data *pdata;
+    struct i2c_adapter *parent;
+    int i, ret, dev_num;
+
+    pdata = pdev->dev.platform_data;
+    if (!pdata) {
+        dev_err(&pdev->dev, "SWPLD platform data not found\n");
+        return -ENODEV;
+    }
+
+    parent = i2c_get_adapter(pdata->parent);
+    if (!parent) {
+        dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent);
+        return -ENODEV;
+    }
+
+    /* Judge bus number to decide how many devices*/
+    switch (pdata->parent) {
+        case BUS4:
+            dev_num = BUS4_DEV_NUM;
+            break;
+        default :
+            dev_num = DEFAULT_NUM;  
+            break;
+    }
+
+    mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+    if (!mux) {
+        ret = -ENOMEM;
+        printk(KERN_ERR "Failed to allocate memory for mux\n");
+        goto alloc_failed;
+    }
+
+    mux->parent = parent;
+    mux->data = *pdata;
+    mux->child = kzalloc(sizeof(struct i2c_adapter *) * dev_num, GFP_KERNEL);
+    if (!mux->child) {
+        ret = -ENOMEM;
+        printk(KERN_ERR "Failed to allocate memory for device on mux\n");
+        goto alloc_failed2;
+    }
+
+    for (i = 0; i < dev_num; i++) {
+        int nr = pdata->base_nr + i;
+        unsigned int class = 0;
+
+        mux->child[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux,
+                           nr, i, class,
+                           swpld_mux_select, NULL);
+        if (!mux->child[i]) {
+            ret = -ENODEV;
+            dev_err(&pdev->dev, "Failed to add adapter %d\n", i);
+            goto add_adapter_failed;
+        }
+    }
+
+    platform_set_drvdata(pdev, mux);
+    return 0;
+
+add_adapter_failed:
+    for (; i > 0; i--)
+        i2c_del_mux_adapter(mux->child[i - 1]);
+    kfree(mux->child);
+alloc_failed2:
+    kfree(mux);
+alloc_failed:
+    i2c_put_adapter(parent);
+
+    return ret;
+}
+#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+static int __init swpld_mux_probe(struct platform_device *pdev)
+{
+    struct i2c_mux_core *muxc;
+    struct swpld_mux *mux;
+    struct swpld_mux_platform_data *pdata;
+    struct i2c_adapter *parent;
+    int i, ret, dev_num;
+
+    pdata = pdev->dev.platform_data;
+    if (!pdata) {
+        dev_err(&pdev->dev, "SWPLD platform data not found\n");
+        return -ENODEV;
+    }
+
+    mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+    if (!mux) {
+        printk(KERN_ERR "Failed to allocate memory for mux\n");
+        return -ENOMEM;
+    }
+    mux->data = *pdata;
+
+    parent = i2c_get_adapter(pdata->parent);
+    if (!parent) {
+        kfree(mux);
+        dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent);
+        return -ENODEV;
+    }
+
+    /* Judge bus number to decide how many devices*/
+    switch (pdata->parent) {
+        case BUS4:
+            dev_num = BUS4_DEV_NUM;
+            break;
+        default :
+            dev_num = DEFAULT_NUM;  
+            break;
+    }
+
+    muxc = i2c_mux_alloc(parent, &pdev->dev, dev_num, 0, 0,
+                                            swpld_mux_select, NULL);
+    if (!muxc) {
+        ret = -ENOMEM;
+        goto alloc_failed;
+    }
+    muxc->priv = mux;
+    platform_set_drvdata(pdev, muxc);
+
+
+    for (i = 0; i < dev_num; i++) {
+        int nr = pdata->base_nr + i;
+        unsigned int class = 0;
+
+        ret = i2c_mux_add_adapter(muxc, nr, i, class);
+        if (ret) {
+            dev_err(&pdev->dev, "Failed to add adapter %d\n", i);
+            goto add_adapter_failed;
+        }
+    }
+
+    dev_info(&pdev->dev, "%d port mux on %s adapter\n", dev_num, parent->name);
+
+    return 0;
+
+add_adapter_failed:
+    i2c_mux_del_adapters(muxc);
+alloc_failed:
+    kfree(mux);
+    i2c_put_adapter(parent);
+
+    return ret;
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
+static int __exit swpld_mux_remove(struct platform_device *pdev)
+{
+    int i;
+    struct swpld_mux *mux = platform_get_drvdata(pdev);
+    struct swpld_mux_platform_data *pdata;
+    struct i2c_adapter *parent;
+    int dev_num;
+
+    pdata = pdev->dev.platform_data;
+    if (!pdata) {
+        dev_err(&pdev->dev, "SWPLD platform data not found\n");
+        return -ENODEV;
+    }
+
+    parent = i2c_get_adapter(pdata->parent);
+    if (!parent) {
+        dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
+            pdata->parent);
+        return -ENODEV;
+    }
+    switch (pdata->parent) {
+        case BUS4:
+            dev_num = BUS4_DEV_NUM;
+            break;
+        default :
+            dev_num = DEFAULT_NUM;  
+            break;
+    }
+
+    for (i = 0; i < dev_num; i++)
+        i2c_del_mux_adapter(mux->child[i]);
+
+    platform_set_drvdata(pdev, NULL);
+    i2c_put_adapter(mux->parent);
+    kfree(mux->child);
+    kfree(mux);
+
+    return 0;
+}
+#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+static int __exit swpld_mux_remove(struct platform_device *pdev)
+{
+    struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
+
+    i2c_mux_del_adapters(muxc);
+    i2c_put_adapter(muxc->parent);
+
+    return 0;
+}
+#endif
+
+static struct platform_driver swpld_mux_driver = {
+    .probe  = swpld_mux_probe,
+    .remove = __exit_p(swpld_mux_remove), /* TODO */
+    .driver = {
+        .owner  = THIS_MODULE,
+        .name   = "delta-ag5648-swpld-mux",
+    },
+};
+/*----------------    MUX   - end   ------------- */
+
+
+/*----------------   module initialization     ------------- */
+static int __init delta_ag5648_platform_init(void)
+{
+    //struct i2c_client *client;
+    struct i2c_adapter *adapter;
+    struct cpld_platform_data *cpld_pdata;
+    struct swpld_mux_platform_data *swpld_pdata;
+    int ret,i = 0;
+
+    //Use pca9548 in i2c_mux_pca954x.c
+    adapter = i2c_get_adapter(BUS1); 
+    
+    i2c_client_9548 = i2c_new_device(adapter, &i2c_info_pca9548[0]);
+    i2c_put_adapter(adapter);
+
+    // set the CPLD prob and remove
+    ret = platform_driver_register(&cpld_driver);
+    if (ret) {
+        printk(KERN_WARNING "Fail to register cpld driver\n");
+        goto error_cpld_driver;
+    }
+
+    // register the mux prob which call the CPLD
+    ret = platform_driver_register(&swpld_mux_driver);
+    if (ret) {
+        printk(KERN_WARNING "Fail to register swpld mux driver\n");
+        goto error_swpld_mux_driver;
+    }
+
+    // register the i2c devices    
+    ret = platform_driver_register(&i2c_device_driver);
+    if (ret) {
+        printk(KERN_WARNING "Fail to register i2c device driver\n");
+        goto error_i2c_device_driver;
+    }
+
+    // register the CPLD
+    ret = platform_device_register(&ag5648_cpld);
+    if (ret) {
+        printk(KERN_WARNING "Fail to create cpld device\n");
+        goto error_ag5648_cpld;
+    }
+    // link the CPLD and the Mux
+    cpld_pdata = ag5648_cpld.dev.platform_data;
+
+
+    swpld_pdata = ag5648_swpld_mux[0].dev.platform_data;
+    swpld_pdata->cpld = cpld_pdata[master_cpld].client;  
+    ret = platform_device_register(&ag5648_swpld_mux[0]);          
+    if (ret) {
+        printk(KERN_WARNING "Fail to create swpld mux %d\n", i);
+        goto error_ag5648_swpld_mux;
+    }
+    
+    for (i = 0; i < ARRAY_SIZE(ag5648_i2c_device); i++)
+    {
+        ret = platform_device_register(&ag5648_i2c_device[i]);
+        if (ret) {
+            printk(KERN_WARNING "Fail to create i2c device %d\n", i);
+            goto error_ag5648_i2c_device;
+        }
+    }
+
+    if (ret)
+        goto error_ag5648_swpld_mux;
+    return 0;
+
+error_ag5648_i2c_device:
+    i--;
+    for (; i >= 0; i--) {
+        platform_device_unregister(&ag5648_i2c_device[i]);
+    }
+    i = ARRAY_SIZE(ag5648_swpld_mux);    
+error_ag5648_swpld_mux:
+    i--;
+    for (; i >= 0; i--) {
+        platform_device_unregister(&ag5648_swpld_mux[0]);
+    }
+    platform_device_unregister(&ag5648_cpld);
+error_ag5648_cpld:
+    platform_driver_unregister(&i2c_device_driver);
+error_i2c_device_driver:
+    platform_driver_unregister(&swpld_mux_driver);
+error_swpld_mux_driver:
+    platform_driver_unregister(&cpld_driver);
+error_cpld_driver:
+    return ret;
+}
+
+static void __exit delta_ag5648_platform_exit(void)
+{
+    int i = 0;
+
+    for ( i = 0; i < ARRAY_SIZE(ag5648_i2c_device); i++ ) {
+        platform_device_unregister(&ag5648_i2c_device[i]);
+    }
+
+    for (i = 0; i < ARRAY_SIZE(ag5648_swpld_mux); i++) {
+        platform_device_unregister(&ag5648_swpld_mux[i]);
+    }
+
+    platform_device_unregister(&ag5648_cpld);
+    platform_driver_unregister(&i2c_device_driver);
+    platform_driver_unregister(&cpld_driver);
+    platform_driver_unregister(&swpld_mux_driver);
+    i2c_unregister_device(i2c_client_9548);
+}
+
+module_init(delta_ag5648_platform_init);
+module_exit(delta_ag5648_platform_exit);
+
+MODULE_DESCRIPTION("DNI ag5648 Platform Support");
+MODULE_AUTHOR("Neal Tai <neal.tai@deltaww.com>");
+MODULE_LICENSE("GPL");    
diff --git a/platform/broadcom/sonic-platform-modules-delta/debian/rules b/platform/broadcom/sonic-platform-modules-delta/debian/rules
index 58a3597e7a44..d0398ecaca17 100755
--- a/platform/broadcom/sonic-platform-modules-delta/debian/rules
+++ b/platform/broadcom/sonic-platform-modules-delta/debian/rules
@@ -5,7 +5,7 @@ export INSTALL_MOD_DIR:=extra
 KVERSION   ?= $(shell uname -r)
 KERNEL_SRC :=  /lib/modules/$(KVERSION)
 MOD_SRC_DIR:= $(shell pwd)
-MODULE_DIRS:= ag9032v1
+MODULE_DIRS:= ag9032v1 ag9064 ag5648
 
 %:
 	dh $@ --with=systemd