Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp1270075pxb; Fri, 21 Jan 2022 13:57:51 -0800 (PST) X-Google-Smtp-Source: ABdhPJwWeTISoG2i+EjnNDL+5pkRX1goWnUZ7aTsKenSuiEyi29s7480P3PGBg/B9BruIeBvDU2I X-Received: by 2002:a17:903:187:b0:14a:6ee7:682c with SMTP id z7-20020a170903018700b0014a6ee7682cmr5680334plg.105.1642802271343; Fri, 21 Jan 2022 13:57:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642802271; cv=none; d=google.com; s=arc-20160816; b=vJx4pY3EYPWYNHHl1gFDFhEMGlyk1bvMWf3UZIzCMQmu0n8rQzPiPshYwqTfmojEO5 0lMtls+kSwXAOfAWl8faM7A9Zm0KWDONknldhUsHFsWajcb1eO/CzKAqK/h4gKz59W5l Mq+tEn4tOu2LfHLOhg++lQfGKhIWBvlotsw0EimT75i1S3TWJNESz3TItOy9tqC+ZHiU OUnauk7ydCu3iiGvzpAhzNB0h98RO5OFh64DcouuCrFk1EstxkMWq4hDKIOKgbsAg8yi GRt4zVdIT6FuXGQR9Xe4yrx8rIlmwiimIWRNHKkSZQucM4RwstviW/csVe+fgyQmL8i9 d6pw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=O0k8KhFMdBtBZFFVKWcjCSCyxGIr4s4QCXxRmW6v5O8=; b=ERKB2UZO107nrc4JHPB3knIh7E4w/1kOFTnviOM1Anlv14yrlIYmbwo1vPjlkBdSXB hCBbVZ/rrl3BZUPeg2Jrn0OigInG4/tT6orfoyLgZH2cWczXp43bcInw3mCN8q5lGYR7 y7XLJ/KqvB8NakO5pwFCXHRItg9HOj2C4G8/ddGGoTFMN2g0WRAixo2PdoF59P0N/+ZD dz4Z+3raT577yhzCCDztyvgcKZZFOJz8xcXwMCAdjd4qLspD6MIXSqiLghpcOmSwYXf9 xetvg+hd1eJmFzsCOL32BaHqajbp0O9AbrPwjuHtfA5x8ihdLPe7FrEs9o6jvLDpkUUS hNiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@9elements.com header.s=google header.b=Y6lanlwL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=9elements.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mw12si16304595pjb.135.2022.01.21.13.57.39; Fri, 21 Jan 2022 13:57:51 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@9elements.com header.s=google header.b=Y6lanlwL; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=9elements.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233736AbiATMOn (ORCPT + 99 others); Thu, 20 Jan 2022 07:14:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232861AbiATMOZ (ORCPT ); Thu, 20 Jan 2022 07:14:25 -0500 Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 71DEEC061401 for ; Thu, 20 Jan 2022 04:14:24 -0800 (PST) Received: by mail-wm1-x32c.google.com with SMTP id az27-20020a05600c601b00b0034d2956eb04so13183133wmb.5 for ; Thu, 20 Jan 2022 04:14:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=9elements.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=O0k8KhFMdBtBZFFVKWcjCSCyxGIr4s4QCXxRmW6v5O8=; b=Y6lanlwLN0MAxX37X4Zsde4MHqeCIF0i68zTNHrcRYOhCojL8/XCjWWNxs3lOGlOLN hMoOEh8bfcX7UyqgnF08D3V/XmBG9FoDbvpiTEU2ohFcpGur8fn7wCRQGLJ4GJ958e3h 06mStnVAwCGDP8ZwHYtPgsSu7bmsv/Djv1ykuCQzX5Wx7Q5lD/Fa2hdlLd195VuXTKG5 8xhPezUppbOoWa5WYEF6mFDrbrzCNiTBVBHrRLmIlxlfEe0F6Adl0qT7hcuvRzCFsJtk fDFROLAJdKcyIRXKD0snN3pzxVTf8P8LQ1LclPwbINMpOOFZcyeUa6sjDE9kqG9/n5ij jmhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=O0k8KhFMdBtBZFFVKWcjCSCyxGIr4s4QCXxRmW6v5O8=; b=pVp35Hd6+7EXR4CCtceO0OLi/Ufcx1aNhlJUxnpe+/IoqYlYW2RGgl5MnWRVOKMaLY yaPMl+U7adPTH74CWlcDR629XygN9ywVbfwV00ubULxT6Bo9+G1E0s4PMiSODY6UEdCB xbdzPQDNlSEDGPYkT+l2PR3EEaCRsQCk9MG/J5vgR6cJy5vblpq4ITPOGv553E14N314 ZVdG+OMbz/d+xffNrILtaZ5uaFxDgA1LNbtfQX59YQjbbR2PofiLdmh+ZLCblMLZ7xos SaSKKCRsewWd1+a0IOepLgHTQS4o8fQGd8kNVJp8GkuZOySINxaljmOR24vvnqSCvyg7 ww6Q== X-Gm-Message-State: AOAM530DXMmJOoRxETxP1L+Wyd1ZKcMPXYiuc1QcpDEFRrgyyOR52eGk RLld7hcizH1f/pLo5czwbXqYew== X-Received: by 2002:a05:6000:18a3:: with SMTP id b3mr11283836wri.470.1642680862932; Thu, 20 Jan 2022 04:14:22 -0800 (PST) Received: from fedora.sec.9e.network (ip-088-153-139-166.um27.pools.vodafone-ip.de. [88.153.139.166]) by smtp.gmail.com with ESMTPSA id x4sm2853863wrp.13.2022.01.20.04.14.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Jan 2022 04:14:22 -0800 (PST) From: Patrick Rudolph To: Peter Rosin Cc: Patrick Rudolph , linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [v3 2/3] i2c: muxes: pca954x: Add MAX735x/MAX736x support Date: Thu, 20 Jan 2022 13:13:12 +0100 Message-Id: <20220120121314.463944-3-patrick.rudolph@9elements.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220120121314.463944-1-patrick.rudolph@9elements.com> References: <20220120121314.463944-1-patrick.rudolph@9elements.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add support for the following Maxim chips using the existing PCA954x driver: - MAX7356 - MAX7357 - MAX7358 - MAX7367 - MAX7368 - MAX7369 All added Maxim chips behave like the PCA954x, where a single SMBUS byte write selects up to 8 channels to be bridged to the primary bus. The MAX7357 exposes 6 additional registers at Power-On-Reset and is configured to: - Disabled interrupts on bus locked up detection - Enable bus locked-up clearing - Disconnect only locked bus instead of all channels While the MAX7357/MAX7358 have interrupt support, they don't act as interrupt controller like the PCA9545 does. Thus don't enable IRQ support and handle them like the PCA9548. Tested using the MAX7357 and verified that the stalled bus is disconnected while the other channels remain operational. Signed-off-by: Patrick Rudolph --- drivers/i2c/muxes/Kconfig | 4 +- drivers/i2c/muxes/i2c-mux-pca954x.c | 92 +++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index 1708b1a82da2..2ac99d044199 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -65,11 +65,11 @@ config I2C_MUX_PCA9541 will be called i2c-mux-pca9541. config I2C_MUX_PCA954x - tristate "NXP PCA954x and PCA984x I2C Mux/switches" + tristate "NXP PCA954x/PCA984x and Maxim MAX735x/MAX736x I2C Mux/switches" depends on GPIOLIB || COMPILE_TEST help If you say yes here you get support for the NXP PCA954x - and PCA984x I2C mux/switch devices. + and PCA984x and Maxim MAX735x/MAX736x I2C mux/switch devices. This driver can also be built as a module. If so, the module will be called i2c-mux-pca954x. diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index 4ad665757dd8..33b9a6a1fffa 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -4,6 +4,7 @@ * * Copyright (c) 2008-2009 Rodolfo Giometti * Copyright (c) 2008-2009 Eurotech S.p.A. + * Copyright (c) 2022 Patrick Rudolph * * This module supports the PCA954x and PCA984x series of I2C multiplexer/switch * chips made by NXP Semiconductors. @@ -11,6 +12,12 @@ * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547, * PCA9548, PCA9846, PCA9847, PCA9848 and PCA9849. * + * It's also compatible to Maxims MAX735x I2C switch chips, which are controlled + * as the NXP PCA9548 and the MAX736x chips that act like the PCA9544. + * + * This includes the: + * MAX7356, MAX7357, MAX7358, MAX7367, MAX7368 and MAX7369 + * * 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 @@ -50,7 +57,30 @@ #define PCA954X_IRQ_OFFSET 4 +/* + * MAX7357 exposes 7 registers on POR which allow to configure additional + * features. Disable interrupts, enable bus locked-up clearing, + * isolate only the locked channel instead of all channels. + */ +#define MAX7357_CONF_INT_ENABLE BIT(0) +#define MAX7357_CONF_FLUSH_OUT BIT(1) +#define MAX7357_CONF_RELEASE_INT BIT(2) +#define MAX7357_CONF_LOCK_UP_CLEAR BIT(3) +#define MAX7357_CONF_DISCON_SINGLE_CHAN BIT(4) +#define MAX7357_CONF_BUS_LOCKUP_DETECTION BIT(5) +#define MAX7357_CONF_ENABLE_BASIC_MODE BIT(6) +#define MAX7357_CONF_PRECONNECT_TEST BIT(7) + +#define MAX7357_CONF_DEFAULTS (MAX7357_CONF_FLUSH_OUT | \ + MAX7357_CONF_DISCON_SINGLE_CHAN) + enum pca_type { + max_7367, + max_7368, + max_7369, + max_7356, + max_7357, + max_7358, pca_9540, pca_9542, pca_9543, @@ -69,6 +99,7 @@ struct chip_desc { u8 nchans; u8 enable; /* used for muxes only */ u8 has_irq; + u8 max7357; enum muxtype { pca954x_ismux = 0, pca954x_isswi @@ -90,8 +121,42 @@ struct pca954x { raw_spinlock_t lock; }; -/* Provide specs for the PCA954x types we know about */ +/* Provide specs for the PCA954x and MAX735x types we know about */ static const struct chip_desc chips[] = { + [max_7356] = { + .nchans = 8, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [max_7357] = { + .nchans = 8, + .muxtype = pca954x_isswi, + .max7357 = 1, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [max_7358] = { + .nchans = 8, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [max_7367] = { + .nchans = 4, + .muxtype = pca954x_isswi, + .has_irq = 1, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [max_7368] = { + .nchans = 4, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [max_7369] = { + .nchans = 4, + .enable = 0x4, + .muxtype = pca954x_ismux, + .has_irq = 1, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, [pca_9540] = { .nchans = 2, .enable = 0x4, @@ -177,6 +242,12 @@ static const struct chip_desc chips[] = { }; static const struct i2c_device_id pca954x_id[] = { + { "max7356", max_7356 }, + { "max7357", max_7357 }, + { "max7358", max_7358 }, + { "max7367", max_7367 }, + { "max7368", max_7368 }, + { "max7369", max_7369 }, { "pca9540", pca_9540 }, { "pca9542", pca_9542 }, { "pca9543", pca_9543 }, @@ -194,6 +265,12 @@ static const struct i2c_device_id pca954x_id[] = { MODULE_DEVICE_TABLE(i2c, pca954x_id); static const struct of_device_id pca954x_of_match[] = { + { .compatible = "maxim,max7356", .data = &chips[max_7356] }, + { .compatible = "maxim,max7357", .data = &chips[max_7357] }, + { .compatible = "maxim,max7358", .data = &chips[max_7358] }, + { .compatible = "maxim,max7367", .data = &chips[max_7367] }, + { .compatible = "maxim,max7368", .data = &chips[max_7368] }, + { .compatible = "maxim,max7369", .data = &chips[max_7369] }, { .compatible = "nxp,pca9540", .data = &chips[pca_9540] }, { .compatible = "nxp,pca9542", .data = &chips[pca_9542] }, { .compatible = "nxp,pca9543", .data = &chips[pca_9543] }, @@ -401,9 +478,16 @@ static int pca954x_init(struct i2c_client *client, struct pca954x *data) else data->last_chan = 0; /* Disconnect multiplexer */ - ret = i2c_smbus_write_byte(client, data->last_chan); - if (ret < 0) - data->last_chan = 0; + if (data->chip->max7357) { + ret = i2c_smbus_write_byte_data(client, data->last_chan, + MAX7357_CONF_DEFAULTS); + if (ret < 0) + data->last_chan = 0; + } else { + ret = i2c_smbus_write_byte(client, data->last_chan); + if (ret < 0) + data->last_chan = 0; + } return ret; } -- 2.34.1