From patchwork Mon Apr 24 08:36:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Rosin X-Patchwork-Id: 754155 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3wBKSs6Kf0z9sDC for ; Mon, 24 Apr 2017 18:36:45 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=axentiatech.onmicrosoft.com header.i=@axentiatech.onmicrosoft.com header.b="eL4U0b7c"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1166908AbdDXIgm (ORCPT ); Mon, 24 Apr 2017 04:36:42 -0400 Received: from mail-db5eur01on0126.outbound.protection.outlook.com ([104.47.2.126]:19703 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1166849AbdDXIgO (ORCPT ); Mon, 24 Apr 2017 04:36:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axentiatech.onmicrosoft.com; s=selector1-axentia-se; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=iC3MooXAjKoeqnNwr5hGFJ/SJcIYa5g7CxxAY8w1Z2s=; b=eL4U0b7c+R2BwFbwPXy6aNEMVUoyj0GQYdt5r5IznRKvV44/hjzY24DE6FcVqTYAPoRYF69FLEaLj4saKLVZ+GE0Tv4tqn7XTzvmbXEE/ldZzY8bZsTnqB0bousy4+k9jDDlsmfmQZoSo8/mm7yY7/YJaVAVONXpuhu+oNvYN3Y= Authentication-Results: vger.kernel.org; dkim=none (message not signed) header.d=none; vger.kernel.org; dmarc=none action=none header.from=axentia.se; Received: from localhost.localdomain (81.224.171.159) by AM5PR0202MB2548.eurprd02.prod.outlook.com (10.173.89.9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1047.13; Mon, 24 Apr 2017 08:35:35 +0000 From: Peter Rosin To: , Greg Kroah-Hartman CC: Peter Rosin , Wolfram Sang , Rob Herring , Mark Rutland , Jonathan Cameron , Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , Jonathan Corbet , , , , , Andrew Morton , Colin Ian King , Paul Gortmaker , Philipp Zabel , Subject: [PATCH v14 11/11] mux: adg792a: add mux controller driver for ADG792A/G Date: Mon, 24 Apr 2017 10:36:35 +0200 Message-ID: <1493022995-16917-12-git-send-email-peda@axentia.se> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1493022995-16917-1-git-send-email-peda@axentia.se> References: <1493022995-16917-1-git-send-email-peda@axentia.se> MIME-Version: 1.0 X-Originating-IP: [81.224.171.159] X-ClientProxiedBy: DB6PR0501CA0040.eurprd05.prod.outlook.com (10.168.78.154) To AM5PR0202MB2548.eurprd02.prod.outlook.com (10.173.89.9) X-MS-Office365-Filtering-Correlation-Id: c6e2493e-20cd-49e4-4128-08d48aece220 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(201703131423075); SRVR:AM5PR0202MB2548; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0202MB2548; 3:MHiI6t20G4XRA71Z7CRpRVjQW7/ZLglf/PK4LgicLYKmIKTa72rwPUuA9K2C92p70fDB8w0g1asKMx+PVprEwF+LD4mZBURJpg7SDuo4K4fJFTKx5nRRa38kAQWsga6tYiwABj6Z8Qhj5PtWvhIdlKUsUaNBXdA9LOGckaNeegtjZyVnti/pE7N5YUKlMesu4wpdIxO0Cm3FdBauJKiEMvk4O2r2Y0E9oIFsErjRimmzc9FwH+02Q41EoAZR9aQtUyHOZ/rmvhdzBzLBLmWlTVX6iFhrXsz23aF+kyCgqzl8Fxh8yYX5+/iJ6s/MXBvw; 25:vdeJM4LS4ozyBUPmqSWQaNZYMFuhgxfc32W7vLJ7fBLNJhwQlaHXbHPd7rms0DEComPWQzz06gt716DcgTnwldApmIqSR5mNoeCiOi5fIg7vziS/9VJ6vpR9tQsKl0H6vrj3dC2vdQNCYnglYE+fijso4LGL8TINglSYUQTdZcMube2lCXrH+Y8xXb1Vr+l7DBTjbZqcNIkO9M8EnEyNjr2ufM7VxoQDmiR9/iGYndMeyPlx0lmspRpK4QTTh+FxbsyUgHj+BA9hfY7oFvDLOsYZM0apDO95oj5uRyEnkl6qCFV1bvYbK0BwKZQT52adUNzlrbSFKVhZNjrulSerkM+4wP+M2w4qEgrBkWmbwNSQSSK9Rc6jfzUKERL6L1h7y2ObPW4L+UYKvAXVoL4DAOb4MAQOurk31m409UrmdG/tjpsQJup7c6C7k36lN82tZE4ZFeh7sIinNRbW3uxs+A== X-Microsoft-Exchange-Diagnostics: 1; AM5PR0202MB2548; 31:joC/qwFzt2aRkxG5J+qo+35lIzL+0pdItTRwYu3IxaeyZnN/AAfxGkn2ZMqdMTRDdwzNnv7c3eAZ0YDfYp6PY0ipbbgi6ZHe4IbbhGxZP2R3MclIghqst91yuwPu+iPiyFU/e2622NkERQxUkBSZsUmfQW3QcuvZeVpJS6DisQoiHXvclpNcTlSTYMdBDJOD8ynvRJTM0dS+3AcKmN3rvjpiGswqO1XLNObKt69xatyMzp/4TkizXqxG4QMrayv+ X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040450)(601004)(2401047)(5005006)(8121501046)(3002001)(93006095)(93001095)(10201501046)(6041248)(201703131423075)(201702281528075)(201703061421075)(20161123560025)(2016111802025)(20161123562025)(20161123555025)(20161123564025)(6072148)(6043046); SRVR:AM5PR0202MB2548; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0202MB2548; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0202MB2548; 4:fouyFnsjwpP028gTqLaj1z3cL8WOvMMPbbiYIS3bSNy+SuZL4GKa8eyWdOH0JPjwIDWfxqo48NrbNM4wjNa9rzSu6Q8HzvZvNN7BLdYHisLifT36hTQoT1nmVGSYZ0xol9dKHpgCtPWjClyjFvzVwdt7pIMLG4eSRunoNiqRzWDXPjBiFFyUCYIJgl8ghfYHjho0h+9Fzy18XmG+8xUFqjawruB5RorkK29qizrOdiFguxj/qFJj1slRAnlyXJCSCSgbNZ6e6XU39PNbia2IbZ0DJ3eC1Sk/r48nnic6qnwK3nAuCEeuCI4JEyjKBnhp2OSyFtZ8xTY6gFHKngRALwg3ea0zwCzPh+hVR6ZJ6UIBzrBD3Sa97h5ZhfILHqLYJWYHpdqfIj/XNVuZCzT4XLMnCOt5fQWbHjZDyShp0AVj64APMiMy37nhLJ/DAkMr0SYDv9PBzANQPa3O2t6/AhSX51kXPw15USWSqUDrSjzBnzBWW8/39H0soJR99JWNCXQqfUnVGJzdPUVeYO+wXTjA7r3gPoZjGWrOj4njs0rvn51uVFebqhaziVe4GBhdDmgyuK5i8Bx1a2zbvuj8g0N+mDXXwZD4czQanD6/p6c5Pl1UdLiiE1Or/JK9OVYmDuUwR8e6L5bTfUQdOFyoLu9Tp5vXnVeK0myevBbrAWC8me7sPWe2D/LBQefunHDUYv02J1tccXOaHQuwKHnPTF6NEmYucSb3f0Mtcz9sP5rw0ORs3BP6GNKeCgwHC24OV3vN7aUyRv2LNo6SNF6rdg== X-Forefront-PRVS: 0287BBA78D X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(6069001)(39410400002)(39840400002)(39400400002)(39450400003)(2906002)(74482002)(5003940100001)(3846002)(6116002)(33646002)(50226002)(81166006)(8676002)(38730400002)(5660300001)(50466002)(48376002)(6506006)(47776003)(42186005)(4326008)(6486002)(189998001)(66066001)(25786009)(2950100002)(8666007)(54906002)(36756003)(6512007)(53936002)(7736002)(86362001)(305945005)(50986999)(76176999)(7416002)(2004002)(42262002); DIR:OUT; SFP:1102; SCL:1; SRVR:AM5PR0202MB2548; H:localhost.localdomain; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0202MB2548; 23:fmJKCaUSLpeOPdcnjmZmDzFyI9fqNBTVd1il9D4?= =?us-ascii?Q?1zygRejnymfoaOazqf0nlYtlACJWggNTShjPyWrqmcY1IN9Cz1dXIucOE0uI?= =?us-ascii?Q?RLM+qegQg/6PnE5PLoDg1J7cPTQUUCrPP2q2OIorUYrlghtKxUKrSrudapus?= =?us-ascii?Q?KM+UYXcwUNnj65E8zqRS/QBp9dxBj3aT5bPdDs5xl+o2Gg2NKcAfCcsMHkXn?= =?us-ascii?Q?ZPLZcvKZlbCrTX60PE0a7zV6tKtbOegMUQfFfKI1X7a2BJEqJ07iJ0MRlVqJ?= =?us-ascii?Q?RKCGb8wKmp/O3HkrWQuS97ccM7ByNtj9oJhQSE8H8mtj3s4PYEXa3OiH8UTN?= =?us-ascii?Q?+XhRbwUlbMtfmGTE1pt39D7VD+76MprrjJRSSQdjwGiRwh8fd3isLSSQRLG4?= =?us-ascii?Q?qepbwNCOvpKlFGGkoCAiIZt2lL7rCdKkX+3gjXV7ZFJJcxhgVK6cbqiaKU9Y?= =?us-ascii?Q?QUPrdjiq6zfWD16MJFCG7w1TtenOBBbYz1R9EMiQvs7xpUA3D2/CNm+BQ5QI?= =?us-ascii?Q?RHXrxrjHBIGhzNY3t7EwTaGy6HEm8SxicQG6sHAV8RIVH4coj2sdqFZcT/Es?= =?us-ascii?Q?uzDd5F7ZB7tFcEoicI8SPUWcY9mwvSPnLbUNeWbn/t4xXYOJgWri3unIkEna?= =?us-ascii?Q?YponKEtG/0S9Q7UwsYVysUYXBmWOn7n/YZ0QEge30DLF7+COVupntSgrvx2D?= =?us-ascii?Q?pnEsxqIbaMSIvPXw9hyQ/XjFQRFwigkZJiEq2s2RcCLyNFrauO5g2G8ecy3U?= =?us-ascii?Q?bk8c4XsdA8+FZWAj+ygnL1XEWaSO8rd4uJXYt5MMNiTBg282BRYxCOon37/m?= =?us-ascii?Q?VFrZ/bp40Ex1PEjyMPiHpx33cnrP7qk9iX6CIRmHx0wBZa7lc2SvY46nhihK?= =?us-ascii?Q?EDiYE77xNCbmMgtrunSgiuZNJ3OQLoRVrNBvpi3nMjIFVzqS+7XwQxUASJCr?= =?us-ascii?Q?StL7MknQITogfXM7a6nG47Mp0p4YLtpKLTVrwn2kZueg3GLJmqOsTVQSDkX8?= =?us-ascii?Q?rHqAHCiviBe6l5BCV49wh2G7/eiMKa3J+X1udZV3GE7kwJpWxVrvOdrsqfGm?= =?us-ascii?Q?uEJovWMo=3D?= X-Microsoft-Exchange-Diagnostics: 1; AM5PR0202MB2548; 6:d1EZdXSLlJweWQgO/z4boTkNROBp8KX7C9jANuo1opsF2CWamFtT9jMfnjyWIuh2zlPnxY3cg1VSCB6p00jzd6n4rasGhSOA5Hwy+3RfcYySUE7K99AjY+KLdET1c92brSW4TgfssbInxapataTZA46kS4IbwV/wDjthd2W/QIWq6ZmpsWVZNCx/4eMYUowgZPwwPHZEJgY2Y5p8z0LdI7cLLJM2elktP+5/EzajB6gbY/GdoqAvW1BPKLR04PJ8jo86iEkQ9nDPbIP4219oh7iyrUyFuRtudIOYOFHcrcaS8bMV5mjU7Sp6R4B7kldMlBfaSgoRR4OfjE1e9W1hmVkJ0E3kTJCJwAnz+q9Pb4JrG2bw+5E8xn3bw50Z/mI86jTGakDyQE7l6cPRVXM7/M4iZAKZ3DV1wKjg3/ldiP4o1dn1mAKOnIL+N44qKMEPjdbb1YsNWS5UEHqQ0VRbrS1lO7yQeQVRkGQkwMo0VgvVs99IP6W7uohPeBCJbOpU/HGpUnuTbrpTF851G5cO2w==; 5:u0wAts2gxM9AKn5jifLdDlgzczjjrBsSg9m7kBLzxQPZIaX0DJ1kFuguPWkHyXrq/hEZm44+EYmn3+dCSTP2siwgB9WoukcQ/vkZR34HFNrGuVZVhWzjhDRX0lNPg/YGz+YZZM8tts9xSqfxYFStKg==; 24:4xStTF6flLg4SwpePFbSpgmX/Yx60NQlGRSf/nHO0j7DuBgsvI9fJjAlHHYyk0v5AZlgQ5yYjwUp69eea8zavSrN2+mwLGH8B0sjHLuAz6k= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0202MB2548; 7:W0vXZ1mN33kCD1ygne4R7No8FFCAFpjjmc2KTXIQU3eS9ASEFEWYnd4yx+UEAZgUZCJD0QJ7TvlWfMmf5diYipBKH/VJ84GlBqlUldxz8g6SlLNhz3tfhtFoIKkrBy0VO6U8OXhS0G4D8aEMRRgLhA8mX86HEkvAQFia9VoGb+icENpxAZk+ahlQjw4vYkfB20q4QZkkv1bkUFjYKziY174KAhUl3FLraUuSz4x3mwGqYYqYxfie0s3sA/KQJ/CTdADJJ+nvBqK3tJrZ0QohFmbNnaQVvnODL23G2T5enrjuEWpD6hVDSFgCMZSJldqCl+t7V4+gAxHL/i0KYSC6cg== X-OriginatorOrg: axentia.se X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Apr 2017 08:35:35.2699 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0202MB2548 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Analog Devices ADG792A/G is a triple 4:1 mux. Reviewed-by: Jonathan Cameron Signed-off-by: Peter Rosin --- drivers/mux/Kconfig | 12 ++++ drivers/mux/Makefile | 1 + drivers/mux/mux-adg792a.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+) create mode 100644 drivers/mux/mux-adg792a.c diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig index e580c2d028d2..34b8284d6d29 100644 --- a/drivers/mux/Kconfig +++ b/drivers/mux/Kconfig @@ -17,6 +17,18 @@ menuconfig MULTIPLEXER if MULTIPLEXER +config MUX_ADG792A + tristate "Analog Devices ADG792A/ADG792G Multiplexers" + depends on I2C + help + ADG792A and ADG792G Wide Bandwidth Triple 4:1 Multiplexers + + The driver supports both operating the three multiplexers in + parallel and operating them independently. + + To compile the driver as a module, choose M here: the module will + be called mux-adg792a. + config MUX_GPIO tristate "GPIO-controlled Multiplexer" depends on GPIOLIB diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile index bb16953f6290..b00a7d37d2fb 100644 --- a/drivers/mux/Makefile +++ b/drivers/mux/Makefile @@ -3,4 +3,5 @@ # obj-$(CONFIG_MULTIPLEXER) += mux-core.o +obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o obj-$(CONFIG_MUX_GPIO) += mux-gpio.o diff --git a/drivers/mux/mux-adg792a.c b/drivers/mux/mux-adg792a.c new file mode 100644 index 000000000000..12aa221ab90d --- /dev/null +++ b/drivers/mux/mux-adg792a.c @@ -0,0 +1,157 @@ +/* + * Multiplexer driver for Analog Devices ADG792A/G Triple 4:1 mux + * + * Copyright (C) 2017 Axentia Technologies AB + * + * Author: Peter Rosin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#define ADG792A_LDSW BIT(0) +#define ADG792A_RESETB BIT(1) +#define ADG792A_DISABLE(mux) (0x50 | (mux)) +#define ADG792A_DISABLE_ALL (0x5f) +#define ADG792A_MUX(mux, state) (0xc0 | (((mux) + 1) << 2) | (state)) +#define ADG792A_MUX_ALL(state) (0xc0 | (state)) + +static int adg792a_write_cmd(struct i2c_client *i2c, u8 cmd, int reset) +{ + u8 data = ADG792A_RESETB | ADG792A_LDSW; + + /* ADG792A_RESETB is active low, the chip resets when it is zero. */ + if (reset) + data &= ~ADG792A_RESETB; + + return i2c_smbus_write_byte_data(i2c, cmd, data); +} + +static int adg792a_set(struct mux_control *mux, int state) +{ + struct i2c_client *i2c = to_i2c_client(mux->chip->dev.parent); + u8 cmd; + + if (mux->chip->controllers == 1) { + /* parallel mux controller operation */ + if (state == MUX_IDLE_DISCONNECT) + cmd = ADG792A_DISABLE_ALL; + else + cmd = ADG792A_MUX_ALL(state); + } else { + unsigned int controller = mux_control_get_index(mux); + + if (state == MUX_IDLE_DISCONNECT) + cmd = ADG792A_DISABLE(controller); + else + cmd = ADG792A_MUX(controller, state); + } + + return adg792a_write_cmd(i2c, cmd, 0); +} + +static const struct mux_control_ops adg792a_ops = { + .set = adg792a_set, +}; + +static int adg792a_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct device *dev = &i2c->dev; + struct mux_chip *mux_chip; + s32 idle_state[3]; + u32 cells; + int ret; + int i; + + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + return -ENODEV; + + ret = device_property_read_u32(dev, "#mux-control-cells", &cells); + if (ret < 0) + return ret; + if (cells >= 2) + return -EINVAL; + + mux_chip = devm_mux_chip_alloc(dev, cells ? 3 : 1, 0); + if (IS_ERR(mux_chip)) + return PTR_ERR(mux_chip); + + mux_chip->ops = &adg792a_ops; + + ret = adg792a_write_cmd(i2c, ADG792A_DISABLE_ALL, 1); + if (ret < 0) + return ret; + + ret = device_property_read_u32_array(dev, "idle-state", + (u32 *)idle_state, + mux_chip->controllers); + if (ret < 0) { + idle_state[0] = MUX_IDLE_AS_IS; + idle_state[1] = MUX_IDLE_AS_IS; + idle_state[2] = MUX_IDLE_AS_IS; + } + + for (i = 0; i < mux_chip->controllers; ++i) { + struct mux_control *mux = &mux_chip->mux[i]; + + mux->states = 4; + + switch (idle_state[i]) { + case MUX_IDLE_DISCONNECT: + case MUX_IDLE_AS_IS: + case 0 ... 4: + mux->idle_state = idle_state[i]; + break; + default: + dev_err(dev, "invalid idle-state %d\n", idle_state[i]); + return -EINVAL; + } + } + + ret = devm_mux_chip_register(dev, mux_chip); + if (ret < 0) + return ret; + + if (cells) + dev_info(dev, "3x single pole quadruple throw muxes registered\n"); + else + dev_info(dev, "triple pole quadruple throw mux registered\n"); + + return 0; +} + +static const struct i2c_device_id adg792a_id[] = { + { .name = "adg792a", }, + { .name = "adg792g", }, + { } +}; +MODULE_DEVICE_TABLE(i2c, adg792a_id); + +static const struct of_device_id adg792a_of_match[] = { + { .compatible = "adi,adg792a", }, + { .compatible = "adi,adg792g", }, + { } +}; +MODULE_DEVICE_TABLE(of, adg792a_of_match); + +static struct i2c_driver adg792a_driver = { + .driver = { + .name = "adg792a", + .of_match_table = of_match_ptr(adg792a_of_match), + }, + .probe = adg792a_probe, + .id_table = adg792a_id, +}; +module_i2c_driver(adg792a_driver); + +MODULE_DESCRIPTION("Analog Devices ADG792A/G Triple 4:1 mux driver"); +MODULE_AUTHOR("Peter Rosin "); +MODULE_LICENSE("GPL v2");