From d3f0b3fe7e9c257884c6227d9e52068b8fba1b05 Mon Sep 17 00:00:00 2001 From: jjangmua Date: Thu, 14 Oct 2021 11:48:21 +0700 Subject: [PATCH] Update Dell z9332f platform modules for Bullseye and 5.10 kernel. Signed-off-by: Jakkapan Jangmuang --- .../debian/control | 2 +- .../z9332f/modules/Makefile | 1 + .../z9332f/modules/cls-i2c-mux-pca954x.c | 579 ++++++++++++++++++ .../z9332f/modules/cls-i2c-ocore.c | 4 +- .../z9332f/modules/cls-pca954x.h | 44 ++ .../z9332f/modules/cls-switchboard.c | 80 +-- .../z9332f/modules/mc24lc64t.c | 2 +- .../z9332f/scripts/z9332f_platform.sh | 9 +- 8 files changed, 675 insertions(+), 46 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-mux-pca954x.c create mode 100644 platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-pca954x.h diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/control b/platform/broadcom/sonic-platform-modules-dell/debian/control index 2920602fcd60..e794bab29a1a 100644 --- a/platform/broadcom/sonic-platform-modules-dell/debian/control +++ b/platform/broadcom/sonic-platform-modules-dell/debian/control @@ -37,7 +37,7 @@ Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-z9332f Architecture: amd64 -Depends: linux-image-4.19.0-12-2-amd64-unsigned +Depends: linux-image-5.10.0-8-2-amd64-unsigned Description: kernel modules for platform devices such as fan, led, sfp Package: platform-modules-s5296f diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile index bb71bb0d9185..d83845f5748c 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/Makefile @@ -1,4 +1,5 @@ obj-m += cls-switchboard.o obj-m += cls-i2c-ocore.o +obj-m += cls-i2c-mux-pca954x.o obj-m += mc24lc64t.o diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-mux-pca954x.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-mux-pca954x.c new file mode 100644 index 000000000000..71b635f32645 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-mux-pca954x.c @@ -0,0 +1,579 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * I2C multiplexer + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This module supports the PCA954x and PCA984x series of I2C multiplexer/switch + * chips made by NXP Semiconductors. + * This includes the: + * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547, + * PCA9548, PCA9846, PCA9847, PCA9848 and PCA9849. + * + * These chips are all controlled via the I2C bus itself, and all have a + * single 8-bit register. The upstream "parent" bus fans out to two, + * four, or eight downstream busses or channels; which of these + * are selected is determined by the chip type and register contents. A + * mux can select only one sub-bus at a time; a switch can select any + * combination simultaneously. + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cls-pca954x.h" + +#define PCA954X_MAX_NCHANS 8 + +#define PCA954X_IRQ_OFFSET 4 + +enum pca_type { + pca_9540, + pca_9542, + pca_9543, + pca_9544, + pca_9545, + pca_9546, + pca_9547, + pca_9548, + pca_9846, + pca_9847, + pca_9848, + pca_9849, +}; + +struct chip_desc { + u8 nchans; + u8 enable; /* used for muxes only */ + u8 has_irq; + enum muxtype { + pca954x_ismux = 0, + pca954x_isswi + } muxtype; + struct i2c_device_identity id; +}; + +struct pca954x { + const struct chip_desc *chip; + + u8 last_chan; /* last register value */ + /* MUX_IDLE_AS_IS, MUX_IDLE_DISCONNECT or >= 0 for channel */ + s32 idle_state; + + struct i2c_client *client; + + struct irq_domain *irq; + unsigned int irq_mask; + raw_spinlock_t lock; +}; + +/* Provide specs for the PCA954x types we know about */ +static const struct chip_desc chips[] = { + [pca_9540] = { + .nchans = 2, + .enable = 0x4, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9542] = { + .nchans = 2, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9543] = { + .nchans = 2, + .has_irq = 1, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9544] = { + .nchans = 4, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9545] = { + .nchans = 4, + .has_irq = 1, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9546] = { + .nchans = 4, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9547] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9548] = { + .nchans = 8, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9846] = { + .nchans = 4, + .muxtype = pca954x_isswi, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x10b, + }, + }, + [pca_9847] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x108, + }, + }, + [pca_9848] = { + .nchans = 8, + .muxtype = pca954x_isswi, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x10a, + }, + }, + [pca_9849] = { + .nchans = 4, + .enable = 0x4, + .muxtype = pca954x_ismux, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x109, + }, + }, +}; + +static const struct i2c_device_id pca954x_id[] = { + { "cls_pca9540", pca_9540 }, + { "cls_pca9542", pca_9542 }, + { "cls_pca9543", pca_9543 }, + { "cls_pca9544", pca_9544 }, + { "cls_pca9545", pca_9545 }, + { "cls_pca9546", pca_9546 }, + { "cls_pca9547", pca_9547 }, + { "cls_pca9548", pca_9548 }, + { "cls_pca9846", pca_9846 }, + { "cls_pca9847", pca_9847 }, + { "cls_pca9848", pca_9848 }, + { "cls_pca9849", pca_9849 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pca954x_id); + +static const struct of_device_id pca954x_of_match[] = { + { .compatible = "nxp,cls_pca9540", .data = &chips[pca_9540] }, + { .compatible = "nxp,cls_pca9542", .data = &chips[pca_9542] }, + { .compatible = "nxp,cls_pca9543", .data = &chips[pca_9543] }, + { .compatible = "nxp,cls_pca9544", .data = &chips[pca_9544] }, + { .compatible = "nxp,cls_pca9545", .data = &chips[pca_9545] }, + { .compatible = "nxp,cls_pca9546", .data = &chips[pca_9546] }, + { .compatible = "nxp,cls_pca9547", .data = &chips[pca_9547] }, + { .compatible = "nxp,cls_pca9548", .data = &chips[pca_9548] }, + { .compatible = "nxp,cls_pca9846", .data = &chips[pca_9846] }, + { .compatible = "nxp,cls_pca9847", .data = &chips[pca_9847] }, + { .compatible = "nxp,cls_pca9848", .data = &chips[pca_9848] }, + { .compatible = "nxp,cls_pca9849", .data = &chips[pca_9849] }, + {} +}; +MODULE_DEVICE_TABLE(of, pca954x_of_match); + +/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() + for this as they will try to lock adapter a second time */ +static int pca954x_reg_write(struct i2c_adapter *adap, + struct i2c_client *client, u8 val) +{ + union i2c_smbus_data dummy; + + return __i2c_smbus_xfer(adap, client->addr, client->flags, + I2C_SMBUS_WRITE, val, + I2C_SMBUS_BYTE, &dummy); +} + +static u8 pca954x_regval(struct pca954x *data, u8 chan) +{ + /* We make switches look like muxes, not sure how to be smarter. */ + if (data->chip->muxtype == pca954x_ismux) + return chan | data->chip->enable; + else + return 1 << chan; +} + +static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + u8 regval; + int ret = 0; + + regval = pca954x_regval(data, chan); + /* Only select the channel if its different from the last channel */ + if (data->last_chan != regval) { + ret = pca954x_reg_write(muxc->parent, client, regval); + data->last_chan = ret < 0 ? 0 : regval; + } + + return ret; +} + +static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + s32 idle_state; + + idle_state = READ_ONCE(data->idle_state); + if (idle_state >= 0) + /* Set the mux back to a predetermined channel */ + return pca954x_select_chan(muxc, idle_state); + + if (idle_state == MUX_IDLE_DISCONNECT) { + /* Deselect active channel */ + data->last_chan = 0; + return pca954x_reg_write(muxc->parent, client, + data->last_chan); + } + + /* otherwise leave as-is */ + + return 0; +} + +static ssize_t idle_state_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + + return sprintf(buf, "%d\n", READ_ONCE(data->idle_state)); +} + +static ssize_t idle_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + int val; + int ret; + + ret = kstrtoint(buf, 0, &val); + if (ret < 0) + return ret; + + if (val != MUX_IDLE_AS_IS && val != MUX_IDLE_DISCONNECT && + (val < 0 || val >= data->chip->nchans)) + return -EINVAL; + + i2c_lock_bus(muxc->parent, I2C_LOCK_SEGMENT); + + WRITE_ONCE(data->idle_state, val); + /* + * Set the mux into a state consistent with the new + * idle_state. + */ + if (data->last_chan || val != MUX_IDLE_DISCONNECT) + ret = pca954x_deselect_mux(muxc, 0); + + i2c_unlock_bus(muxc->parent, I2C_LOCK_SEGMENT); + + return ret < 0 ? ret : count; +} + +static DEVICE_ATTR_RW(idle_state); + +static irqreturn_t pca954x_irq_handler(int irq, void *dev_id) +{ + struct pca954x *data = dev_id; + unsigned long pending; + int ret, i; + + ret = i2c_smbus_read_byte(data->client); + if (ret < 0) + return IRQ_NONE; + + pending = (ret >> PCA954X_IRQ_OFFSET) & (BIT(data->chip->nchans) - 1); + for_each_set_bit(i, &pending, data->chip->nchans) + handle_nested_irq(irq_linear_revmap(data->irq, i)); + + return IRQ_RETVAL(pending); +} + +static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type) +{ + if ((type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_LOW) + return -EINVAL; + return 0; +} + +static struct irq_chip pca954x_irq_chip = { + .name = "i2c-mux-pca954x", + .irq_set_type = pca954x_irq_set_type, +}; + +static int pca954x_irq_setup(struct i2c_mux_core *muxc) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int c, irq; + + if (!data->chip->has_irq || client->irq <= 0) + return 0; + + raw_spin_lock_init(&data->lock); + + data->irq = irq_domain_add_linear(client->dev.of_node, + data->chip->nchans, + &irq_domain_simple_ops, data); + if (!data->irq) + return -ENODEV; + + for (c = 0; c < data->chip->nchans; c++) { + irq = irq_create_mapping(data->irq, c); + if (!irq) { + dev_err(&client->dev, "failed irq create map\n"); + return -EINVAL; + } + irq_set_chip_data(irq, data); + irq_set_chip_and_handler(irq, &pca954x_irq_chip, + handle_simple_irq); + } + + return 0; +} + +static void pca954x_cleanup(struct i2c_mux_core *muxc) +{ + struct pca954x *data = i2c_mux_priv(muxc); + int c, irq; + + if (data->irq) { + for (c = 0; c < data->chip->nchans; c++) { + irq = irq_find_mapping(data->irq, c); + irq_dispose_mapping(irq); + } + irq_domain_remove(data->irq); + } + i2c_mux_del_adapters(muxc); +} + +static int pca954x_init(struct i2c_client *client, struct pca954x *data) +{ + int ret; + + if (data->idle_state >= 0) + data->last_chan = pca954x_regval(data, data->idle_state); + else + data->last_chan = 0; /* Disconnect multiplexer */ + + ret = i2c_smbus_write_byte(client, data->last_chan); + if (ret < 0) + data->last_chan = 0; + + return ret; +} + +/* + * I2C init/probing/exit functions + */ +static int pca954x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = client->adapter; + struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); + struct device *dev = &client->dev; + struct gpio_desc *gpio; + struct i2c_mux_core *muxc; + struct pca954x *data; + int num, force; + int ret; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + + muxc = i2c_mux_alloc(adap, dev, PCA954X_MAX_NCHANS, sizeof(*data), 0, + pca954x_select_chan, pca954x_deselect_mux); + if (!muxc) + return -ENOMEM; + data = i2c_mux_priv(muxc); + + i2c_set_clientdata(client, muxc); + data->client = client; + + /* Reset the mux if a reset GPIO is specified. */ + gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + if (gpio) { + udelay(1); + gpiod_set_value_cansleep(gpio, 0); + /* Give the chip some time to recover. */ + udelay(1); + } + + data->chip = device_get_match_data(dev); + if (!data->chip) + data->chip = &chips[id->driver_data]; + + if (data->chip->id.manufacturer_id != I2C_DEVICE_ID_NONE) { + struct i2c_device_identity id; + + ret = i2c_get_device_id(client, &id); + if (ret && ret != -EOPNOTSUPP) + return ret; + + if (!ret && + (id.manufacturer_id != data->chip->id.manufacturer_id || + id.part_id != data->chip->id.part_id)) { + dev_warn(dev, "unexpected device id %03x-%03x-%x\n", + id.manufacturer_id, id.part_id, + id.die_revision); + return -ENODEV; + } + } + + data->idle_state = MUX_IDLE_AS_IS; + if (device_property_read_u32(dev, "idle-state", &data->idle_state)) { + if (device_property_read_bool(dev, "i2c-mux-idle-disconnect")) + data->idle_state = MUX_IDLE_DISCONNECT; + } + + /* + * Write the mux register at addr to verify + * that the mux is in fact present. This also + * initializes the mux to a channel + * or disconnected state. + */ + ret = pca954x_init(client, data); + if (ret < 0) { + dev_warn(dev, "probe failed\n"); + return -ENODEV; + } + + ret = pca954x_irq_setup(muxc); + if (ret) + goto fail_cleanup; + + /* Now create an adapter for each channel */ + for (num = 0; num < data->chip->nchans; num++) { + force = 0; /* dynamic adap number */ + if (pdata) { + if (num < pdata->num_modes) { + /* force static number */ + force = pdata->modes[num].adap_id; + } else + /* discard unconfigured channels */ + break; + } + + ret = i2c_mux_add_adapter(muxc, force, num, 0); + if (ret) + goto fail_cleanup; + } + + if (data->irq) { + ret = devm_request_threaded_irq(dev, data->client->irq, + NULL, pca954x_irq_handler, + IRQF_ONESHOT | IRQF_SHARED, + "pca954x", data); + if (ret) + goto fail_cleanup; + } + + /* + * The attr probably isn't going to be needed in most cases, + * so don't fail completely on error. + */ + device_create_file(dev, &dev_attr_idle_state); + + dev_info(dev, "registered %d multiplexed busses for I2C %s %s\n", + num, data->chip->muxtype == pca954x_ismux + ? "mux" : "switch", client->name); + + return 0; + +fail_cleanup: + pca954x_cleanup(muxc); + return ret; +} + +static int pca954x_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + device_remove_file(&client->dev, &dev_attr_idle_state); + + pca954x_cleanup(muxc); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int pca954x_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + int ret; + + ret = pca954x_init(client, data); + if (ret < 0) + dev_err(&client->dev, "failed to verify mux presence\n"); + + return ret; +} +#endif + +static SIMPLE_DEV_PM_OPS(pca954x_pm, NULL, pca954x_resume); + +static struct i2c_driver pca954x_driver = { + .driver = { + .name = "cls_pca954x", + .pm = &pca954x_pm, + .of_match_table = pca954x_of_match, + }, + .probe = pca954x_probe, + .remove = pca954x_remove, + .id_table = pca954x_id, +}; + +module_i2c_driver(pca954x_driver); + +MODULE_AUTHOR("Rodolfo Giometti "); +MODULE_DESCRIPTION("PCA954x I2C mux/switch driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c index c80757e6619d..fe3c241f6702 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-i2c-ocore.c @@ -722,7 +722,7 @@ static int ocores_i2c_probe(struct platform_device *pdev) init_waitqueue_head(&i2c->wait); - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_optional(pdev, 0); if (irq == -ENXIO) { i2c->flags |= OCORES_FLAG_POLL; } else { @@ -758,7 +758,7 @@ static int ocores_i2c_probe(struct platform_device *pdev) /* add in known devices to the bus */ if (pdata) { for (i = 0; i < pdata->num_devices; i++) - i2c_new_device(&i2c->adap, pdata->devices + i); + i2c_new_client_device(&i2c->adap, pdata->devices + i); } return 0; diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-pca954x.h b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-pca954x.h new file mode 100644 index 000000000000..15b9fe414677 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-pca954x.h @@ -0,0 +1,44 @@ +/* + * + * cls-pca954x.h - I2C multiplexer/switch support + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * Michael Lawnick + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef _LINUX_I2C_PCA954X_H +#define _LINUX_I2C_PCA954X_H + +/* Platform data for the PCA954x I2C multiplexers */ + +/* Per channel initialisation data: + * @adap_id: bus number for the adapter. 0 = don't care + * + */ +struct pca954x_platform_mode { + int adap_id; +}; + +/* Per mux/switch data, used with i2c_register_board_info */ +struct pca954x_platform_data { + struct pca954x_platform_mode *modes; + int num_modes; +}; + +#endif /* _LINUX_I2C_PCA954X_H */ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c index dc1cf8874e39..80d0ef9021d8 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/cls-switchboard.c @@ -21,14 +21,14 @@ #include #include #include -#include #include "cls-i2c-ocore.h" +#include "cls-pca954x.h" -#define MOD_VERSION "2.1.0-1" +#define MOD_VERSION "2.2.0" #define DRV_NAME "cls-switchboard" -#define I2C_MUX_CHANNEL(_ch, _adap_id, _deselect) \ - [_ch] = { .adap_id = _adap_id, .deselect_on_exit = _deselect } +#define I2C_MUX_CHANNEL(_ch, _adap_id) \ + [_ch] = { .adap_id = _adap_id } #define FPGA_PCIE_DEVICE_ID 0x7021 #define MMIO_BAR 0 @@ -72,47 +72,47 @@ struct switchbrd_priv { // NOTE: Silverstone i2c channel mapping is very wierd!!! /* PCA9548 channel config on MASTER BUS 3 */ static struct pca954x_platform_mode i2c_mux_70_modes[] = { - I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 23, true), - I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 26, true), - I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 27, true), - I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 28, true), - I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 29, true), - I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 30, true), - I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 31, true), - I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 32, true), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 23), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 26), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 27), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 28), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 29), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 30), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 31), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 32), }; static struct pca954x_platform_mode i2c_mux_71_modes[] = { - I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 1, true), - I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 2, true), - I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 3, true), - I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 4, true), - I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 5, true), - I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 6, true), - I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 15, true), - I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 8, true), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 1), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 2), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 3), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 4), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 5), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 6), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 15), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 8), }; static struct pca954x_platform_mode i2c_mux_72_modes[] = { - I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 17, true), - I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 18, true), - I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 19, true), - I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 20, true), - I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 21, true), - I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 22, true), - I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 25, true), - I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 24, true), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 17), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 18), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 19), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 20), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 21), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 22), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 25), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 24), }; static struct pca954x_platform_mode i2c_mux_73_modes[] = { - I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 9, true), - I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 10, true), - I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 11, true), - I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 12, true), - I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 13, true), - I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 14, true), - I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 7, true), - I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 16, true), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 9), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 10), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 11), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 12), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 13), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 14), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 7), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 16), }; static struct pca954x_platform_data om_muxes[] = { @@ -137,19 +137,19 @@ static struct pca954x_platform_data om_muxes[] = { /* Optical Module bus 3 i2c muxes info */ static struct i2c_board_info i2c_info_3[] = { { - I2C_BOARD_INFO("pca9548", 0x70), + I2C_BOARD_INFO("cls_pca9548", 0x70), .platform_data = &om_muxes[0], }, { - I2C_BOARD_INFO("pca9548", 0x71), + I2C_BOARD_INFO("cls_pca9548", 0x71), .platform_data = &om_muxes[1], }, { - I2C_BOARD_INFO("pca9548", 0x72), + I2C_BOARD_INFO("cls_pca9548", 0x72), .platform_data = &om_muxes[2], }, { - I2C_BOARD_INFO("pca9548", 0x73), + I2C_BOARD_INFO("cls_pca9548", 0x73), .platform_data = &om_muxes[3], }, }; diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c index a391056d09a7..002172f587e8 100644 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/modules/mc24lc64t.c @@ -94,7 +94,7 @@ static int mc24lc64t_probe(struct i2c_client *client, sizeof(struct mc24lc64t_data), GFP_KERNEL))) return -ENOMEM; - drvdata->fake_client = i2c_new_dummy(client->adapter, client->addr + 1); + drvdata->fake_client = i2c_new_dummy_device(client->adapter, client->addr + 1); if (!drvdata->fake_client) return -ENOMEM; diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh index a5f8a2e6d62e..5300cf7be281 100755 --- a/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh +++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/scripts/z9332f_platform.sh @@ -185,7 +185,7 @@ init_devnum if [ "$1" == "init" ]; then modprobe i2c-dev - modprobe i2c-mux-pca954x force_deselect_on_exit=1 + modprobe cls-i2c-mux-pca954x modprobe ipmi_devintf modprobe ipmi_si kipmid_max_busy_us=1000 modprobe cls-i2c-ocore @@ -201,12 +201,17 @@ if [ "$1" == "init" ]; then platform_firmware_versions get_reboot_cause echo 1000 > /sys/module/ipmi_si/parameters/kipmid_max_busy_us + # Set the PCA9548 mux behavior + echo -2 > /sys/bus/i2c/drivers/cls_pca954x/3-0070/idle_state + echo -2 > /sys/bus/i2c/drivers/cls_pca954x/3-0071/idle_state + echo -2 > /sys/bus/i2c/drivers/cls_pca954x/3-0072/idle_state + echo -2 > /sys/bus/i2c/drivers/cls_pca954x/3-0073/idle_state elif [ "$1" == "deinit" ]; then sys_eeprom "delete_device" switch_board_qsfp "delete_device" switch_board_sfp "delete_device" - modprobe -r i2c-mux-pca954x + modprobe -r cls-i2c-mux-pca954x modprobe -r i2c-dev modprobe -r ipmi_devintf modprobe -r ipmi_si