From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751482AbdBHSbG (ORCPT ); Wed, 8 Feb 2017 13:31:06 -0500 Received: from mail-db5eur01on0094.outbound.protection.outlook.com ([104.47.2.94]:28367 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751055AbdBHSbD (ORCPT ); Wed, 8 Feb 2017 13:31:03 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=peda@axentia.se; From: Peter Rosin To: CC: Peter Rosin , Wolfram Sang , "Rob Herring" , Mark Rutland , "Jonathan Cameron" , Hartmut Knaack , "Lars-Peter Clausen" , Peter Meerwald-Stadler , Jonathan Corbet , , , , , Andrew Morton Subject: [PATCH v9 10/10] mux: adg792a: add mux controller driver for ADG792A/G Date: Wed, 8 Feb 2017 16:41:57 +0100 Message-ID: <1486568517-6997-11-git-send-email-peda@axentia.se> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1486568517-6997-1-git-send-email-peda@axentia.se> References: <1486568517-6997-1-git-send-email-peda@axentia.se> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [217.210.101.82] X-ClientProxiedBy: DB5PR08CA0069.eurprd08.prod.outlook.com (10.166.166.165) To HE1PR0202MB2555.eurprd02.prod.outlook.com (10.168.184.8) X-MS-Office365-Filtering-Correlation-Id: 1febed4a-0630-4669-aa9a-08d450395c1a X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:HE1PR0202MB2555; X-Microsoft-Exchange-Diagnostics: 1;HE1PR0202MB2555;3:EsT6u2AbN1mM1nPGVSLdLwJzfjddoBQVOvz841vtnZsDiPmm1FFHXMI5P/AICJqZO6Byc9UkW9FmDKRPI/CJeRsFGyH3mkZZb5kDLKbCjbPTGNLyyD5g8PKthqGZ2rHhMKMv19LfQcu1D5vuUcX4GhL42orYW67aa6EuAtxix7HKAEf8Zj2Iga4+Ww0khm9ojdZLjnVR+CPgneOlkZ15r2SDGEXz2/jPxq2jUNVeWSokkYNmiZRDDJ0wqeBdQ5bFMLbPEVjqK1VNrrkn2dtTqg==;25:8/wZSqWlQYEQXNlTtEVImFZYZVhuoBMItLaCs+3Wq/QQ+yhxeCHicHcvax97TBoFPvYVNvtOSUmyRM6SWP+m1p0UTmUmgORApUO3eZ0CceRjn6GYFq1fxnEa/blRBni9S9odDNgmyjlsjKJMRF9q7Ix0mE+FcMfT88t6LMwIJkUn2LMCBDxaiJM/OiJzPSt9PxRPxsYgzsJB3qC19DdDrxa79H0fHxypMQ9kRoYd6ZBZ9CBywI3BqAXlKSXo1UW/zblOLfGUMbIH5rAaEOiDz8rydh1cgkdzOj/C/u0um/vfeIWmgsMbUWlmp5iwhg1u0TDCVqMS/tU7zdwtzfJxCyJqkIZVbRhxMnqSnLAWfpWNIpUNUdM1MGPzHMRXLCmC1Zd+ADw0UvTL4Zr5+ufN/3RiGHasqcPI1unu23aweIUiqL+jqkDzF4TVlxHEQnbaAJPqA9TEHMeKe6uU3uHeTQ== X-Microsoft-Exchange-Diagnostics: 1;HE1PR0202MB2555;31:5MxQ5xARHBI9wzS09LksFEOPqiiva9skYv7uEzl3NiSsd38LWWSq2bAWo9a+RUHCYWE2VQzM4dz37eYEVz+UL7YJFkzyXUaGh/i4aK6netTCUcXNxxQlBvT1x45tsy1j/30BkCOpwP/F+zTQmHZOeMJHSddx070JXrlrQ2FteXXSMTY26AQy0T2T3uQ+9w2QjC3jW8hxayiZnMx+StO28Zx0vYWpzybyyRviah1vwGRZ+mGfodm7WeNGfkL7ujng X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(5005006)(2017020702029)(8121501046)(20170203043)(3002001)(10201501046)(6041248)(2016111802025)(20161123564025)(20161123560025)(20161123558025)(20161123562025)(20161123555025)(6043046)(6072148);SRVR:HE1PR0202MB2555;BCL:0;PCL:0;RULEID:;SRVR:HE1PR0202MB2555; X-Microsoft-Exchange-Diagnostics: 1;HE1PR0202MB2555;4:iI8rWAhbFgTNZq4B+1+haP6m8j1kiTOEqGR5Wcm8DvN0rL6/88zH/inzQdz9gIzpxeYVBha6S8MclReVGp7FKxXNEzZAVLySaBgRL12iREmKkiqq8+OsXewtEChpg04DZqnzHkCD/JZRiAWZnybRyWmueqZQlbmKy1ow4rTddvMTDbz6Mh6PbyCV315Q7Oad60fOrXwUkVjsY+p6jfGqI5P8qPFhq9K+zXTgHQRKAMtN6p+wDdlE+hE/oeo3VNXjC1lImBO7mZU52qEjumhNie1uM9WjCTxJWSaFgpUhnu4oJ7fI4afrb6/MLz/MLH+ogcFGXMkaCqiidnUYcklIBjKzu+/jmSG3X/ixq1X4Blny76pygGZHTyJVgHRiQeYoI/6R21N1W+8zKrUPgOkgAqN2bdd9hRK7Rrx/zHHSXMY3JGdEALgp/0pZG2bjrc5y8quXftqEY6ijwaRlCz1nBuzvzymt76ubp2lUgECxo3VY+jRbkiDjbdZ6VUAqtUkWtskZuXT1+ZQCXEzVOi8OMvuaii9Ot3jZph35Cm+9tNFDHZ1LxBUEhaskdiL4mPROT603mTTyY6Jub+HL2pkPUO/gljZOeZuxXYYsVUast/zw+xc621gkSolxHssGVaGKY1h9i3pqiztHddiTbxidx26Eq5WznVz7Ig1eP4L5zJop2EjciTNEjwKYQSR/ZHCiQClSyhc8DV3aBoNoUFnALA== X-Forefront-PRVS: 0212BDE3BE X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6009001)(6069001)(7916002)(39840400002)(39450400003)(39410400002)(199003)(189002)(6116002)(3846002)(7736002)(50466002)(2351001)(38730400002)(74482002)(2906002)(101416001)(305945005)(97736004)(48376002)(8676002)(47776003)(110136004)(81166006)(76176999)(50986999)(81156014)(4326007)(6512007)(53936002)(6486002)(66066001)(86362001)(6506006)(33646002)(92566002)(7416002)(50226002)(6666003)(105586002)(42186005)(36756003)(5660300001)(189998001)(6916009)(25786008)(106356001)(2950100002)(5003940100001)(8666007)(54906002)(68736007)(2004002)(42262002);DIR:OUT;SFP:1102;SCL:1;SRVR:HE1PR0202MB2555;H:localhost.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;HE1PR0202MB2555;23:P4t+BQEOoA8GPRtpd5SqrrxbUIfeh8lkNddfMCE?= =?us-ascii?Q?tYOAQfc4mYVBEJvFI1iEEccBm9bFTIvivAyJPI8Dj44zsDzic9UhBUW3tXOe?= =?us-ascii?Q?pt+q91+NAxcw+vXUnUet1mhxB9bHjwgWorbe/whKWePvDZtWM5MT8goe4GGC?= =?us-ascii?Q?1AHZOJkVWszh+uIwCwwOB8DcTcLlSa4AAqKsltEBPZ1sWz471D2Vm/nJOyhA?= =?us-ascii?Q?CTIbKm46bm1+A61GTsZatDde+7Lo3PNGMhtwRmVH1sG09SekyV6RivX8BOsi?= =?us-ascii?Q?KzAE2/Lle4z+sVZD5EbdSLO5mTUHjTp0Gkp84K+th/wsdyOy4MfZpBZp0Vdp?= =?us-ascii?Q?0wbrFhsTg2FR22uY4lfbpdWvdF0gCoFrlbEdTCqR614bn58dc2lASsgahYbk?= =?us-ascii?Q?3RA4S5qs9+Yk+FQc3KwY0dsiXfxo0zR4syswEC1ilewUeRqV8Z2ZbO3WNxaP?= =?us-ascii?Q?A3NRhpEpdvMMIqFSUhfE8bUyNF2nG3EPt44QYV1jU6IrWuf3rpjKj8yqmxfv?= =?us-ascii?Q?lLNKQ3V9aNX08jZs7drrADHwdhvoS8x3991fjDnvJlikFaF5UMVSbJVk6eQp?= =?us-ascii?Q?WsJZGslY08Xngd7GDVdFeEo8B4+vTt2pdC3twA8L+XrKnmOaO+OPTzRGA0eG?= =?us-ascii?Q?9aM23sHF43spghFsb8almcy/4e+tEm5I6Yyu0WLHMoRKA7GgenuASl5MrPMF?= =?us-ascii?Q?//3PSdyYmvJb3x8/KuQCx6Qz7JMQCDN3X9T2oIOm1ZjuFpJYfOgvRLXu7MLM?= =?us-ascii?Q?QitfXPfzBZvnU20LzlwT29jLH40hzjvlqc6CfNXKz6QA1k8P0HuMBpPH0I24?= =?us-ascii?Q?MC3JgRkE84oX0vDPUQi4lYpS6J2AG7EYttDqVkMt/P3/hfPPw2K4yfrI1OLw?= =?us-ascii?Q?Z+F4bhbcJRFln4hjxTh96iZGa0vqlUVcDPEmg+DEvYW5N41mFTLATDdQtF4j?= =?us-ascii?Q?6F80MEF3ewCG3HhkQYhV2PIdQ03lvhtyb8jiPodW7VGHBiS7zmFfhIyGLwhk?= =?us-ascii?Q?nJaWqPcjlm+rFGfcNL6VDdRhrsxGc4wG8QXUOwuGB9TrKYfhoqxY35kIK1gY?= =?us-ascii?Q?0W/kK/3c1QIebHdWVZ4ZPzbgfbevnmJEbcZ+iL0YLFirzt0K+ulqESkAAK1T?= =?us-ascii?Q?xYuiQxiGnNYRTKwTjgY2IG2DSWbRFhIvHofwTcaGn665VuCoxtExa/l44aRr?= =?us-ascii?Q?6UUCPEQ49yG+9KJsk+9ecSp2el4QF4WmLiENV7XAjtSfMrzLY3jViUlxVTE/?= =?us-ascii?Q?VI5kcBmNmhz5k/h2aggkRgCxfRb+gCqx0jQY8GLRW1q6H9MJZIZv0PeH487h?= =?us-ascii?Q?Bi3IVQMXkpM1phAD1dIzGfac=3D?= X-Microsoft-Exchange-Diagnostics: 1;HE1PR0202MB2555;6:BrkUnvqH7WUlxMUzjrgLH7cdQxIpaHH7rHjfQ8wENCEKPLiDAqngWH6mih9iw4BUY/mU1SvFvJtPJVhkAsO0OZL7JlLJUSViOgPJRRWJA/eUpj+/2isueua+d2yEWPr+9VzKuI+zFa7uAaraow3MLK0S2qb++nW0GQCZs6lP5T1RdosqNA/ZYKRmo4GoTq8dHrlyCao7ZD3JX9brHqlxwTBMbW58OLNVvP87RCMqzyNO9kwHCabiXqfqfGSNpyudBBR/17qhUjca2+md8c0kziNgpNhxsDgZjAy1e8m8oWHJ41kbmnEtDiwhLed3rd3LKbDzU1mlMC6bNYlF7jRTAsADArBq6oGyu98xtrU2v3L+xLPFu9W648DjYirtgHQFJ1tPUnvI6aHr0NbL2euexQ==;5:TRBkEPjR+5/1uvLaFMqQmp94CNjiBQM/fXPydFf7eqz27OmH2USgVVNgJ9uXTvgJ5GKgKRSj65CelykL4kxc0q2eBwCgXgilJR08qsE7DSpgywAnmk61qSwKXEid/9XDD4cA8r0LhgDm3p1NgeTx+Q==;24:ddXSGTaPcpdME9Vdg/v67siggjE7t6vTSGYKm5RqO9kg9cyQ8C+NTyD+zo8SW1PHlyN/qRiK+LSKS4RXFZXClcm5Ms4ADFW4ftDjVG55Jp8= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;HE1PR0202MB2555;7:uCYhmTwK+c5/YJJLA1VMzREP7PflFgZUSmFYlPvj0YQCoxf9efS6wMNqKm5G2NKUAIVSFjCMGtgGBl5BAEYueTkFAznVaOcjRo9SpNMWElEVd6BcyEPV7OBM3eyhq/Ug7Do/w1xg/q2nX1ZoFlMmCWqDazN+aeRjy4iiiwP4nqsajZjfsyR6qfoMoZ/wGWMvY4+h8E3ywf6Ih/u7ZUFtcvaDlTVKcaGDdfp+d54qOREkNi4g5RE5dpIjWueuLlelItRZ37wynWmHybfahj1IMtVtEVICd5QCQRWcj1sO7zoYveOOF7IBXKqV2L47TJXsr0VCWOt2NSNNAS6PzYIa+7dB0XunO0L2pYnJUxFmjTTr0OnNNbDa8wjxqFqQ3VHdJMNBBhqgNj99/bdRelVqbxjgJy6fNWm0oHhkx1ODaDqMS7gpBsgaDdl+QTTHWX4C/Xe7C/kv/SoWnJiEa4S3kkevWBwy0YBW+iGXtDiEVKtMzxpK+C0GeAOShYfEQNODdkohKVhKS1qpYCuXNCiaLw== X-OriginatorOrg: axentia.se X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Feb 2017 15:44:23.2563 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0202MB2555 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@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 | 140 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 drivers/mux/mux-adg792a.c diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig index 57e6f4e5fda9..d13fcf98958e 100644 --- a/drivers/mux/Kconfig +++ b/drivers/mux/Kconfig @@ -16,6 +16,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 OF && GPIOLIB diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile index facc43da3648..fddbb073fc77 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..d58971641fdc --- /dev/null +++ b/drivers/mux/mux-adg792a.c @@ -0,0 +1,140 @@ +/* + * 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 + +#define ADG792A_LDSW BIT(0) +#define ADG792A_RESET 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_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 i2c_smbus_write_byte_data(i2c, cmd, ADG792A_LDSW); +} + +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; + u32 cells; + int ret; + int i; + + ret = of_property_read_u32(dev->of_node, "#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 (!mux_chip) + return -ENOMEM; + + mux_chip->ops = &adg792a_ops; + + ret = i2c_smbus_write_byte_data(i2c, ADG792A_DISABLE_ALL, + ADG792A_RESET | ADG792A_LDSW); + if (ret < 0) + return ret; + + for (i = 0; i < mux_chip->controllers; ++i) { + struct mux_control *mux = &mux_chip->mux[i]; + s32 idle_state; + + mux->states = 4; + + ret = of_property_read_u32_index(dev->of_node, "idle-state", i, + (s32 *)&idle_state); + if (ret < 0) + continue; + + switch (idle_state) { + case 0 ... 4: + case MUX_IDLE_DISCONNECT: + mux_chip->mux[i].idle_state = idle_state; + break; + case MUX_IDLE_AS_IS: + break; + default: + dev_err(dev, "invalid idle-state %d\n", idle_state); + 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