From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757100AbcK2KNI (ORCPT ); Tue, 29 Nov 2016 05:13:08 -0500 Received: from mail-db5eur01on0138.outbound.protection.outlook.com ([104.47.2.138]:61712 "EHLO EUR01-DB5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1756862AbcK2KMY (ORCPT ); Tue, 29 Nov 2016 05:12:24 -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 , Arnd Bergmann , Greg Kroah-Hartman , , , , Subject: [PATCH v5 9/9] misc: mux-adg792a: add mux controller driver for ADG792A/G Date: Tue, 29 Nov 2016 11:10:45 +0100 Message-ID: <1480414245-14034-10-git-send-email-peda@axentia.se> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1480414245-14034-1-git-send-email-peda@axentia.se> References: <1480414245-14034-1-git-send-email-peda@axentia.se> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [217.210.101.82] X-ClientProxiedBy: HE1PR06CA0051.eurprd06.prod.outlook.com (10.164.28.147) To AM5PR0201MB2308.eurprd02.prod.outlook.com (10.169.243.7) X-MS-Office365-Filtering-Correlation-Id: d5cd1568-7fbf-40ae-ea14-08d418403399 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:AM5PR0201MB2308; X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;3:9vlmQ10/5iGZHqXiaRas/8VDRScKxalb0bHQvL1Zwi+CaCLPUKugI64H3Ype29rs8lW0rb4ZA/LKkmVH/hjz0XhC9FDaYI1NjeWHryYk6flAosGv9zqD//rsGjmkUSIPHGTVDa1urvHz8YIs8nfViZ2joWqFgXYY5GImIGLYMuRakEhgXr1lyJPIGnwSr+vNSHOeEpxhY42gDlwZ1hIBhDaQnPMQ6ORuAYRKFX+ep1BJu5GqzTrRzflB5N6QnFFYiBc2N8MEOEthDX4RTBKZUA==;25:TX3SfxU26dKMyRqRZtCXicJ+LEFttogF2QP5JzGm299UllCiBoegw1H4b97eZoIAKXWTNNtCMbbBgJP52VY+zuwcTlQUdcTJfqaiBz+us1yy0Fv6tZee/Tp6sj99bSI8K2kh3IUsQt4B4Nm4ydnP+9M1wC7zrzwbPqm+QqAYAdYLLVHzt2+OgJA22YGEkKyH3fWx1LAyTxDdD6jQiqdhxvKXV4h6+8r9UdPXCTxwCNotNmPPlFGtFYzb9MgpTcXpBS4Yrm44mfTvqsUqMVHQe0C+Jw8y+6D1gkCAXPy2Qib2vnmJk503+uJd0DbbL8kXqr1s2HcjGxHinKDCkjvOw9HwEWziMUFpXvHlMWO9pFM4AGOroKrdQtasi5NZHv+4o3Lp75w74TV+NJxXwuLCZHBgNyYYSP3LsWH21YjPs42mLbwq1pa0nhwBRjfe3XzUNvxuQMWbdkXqPGjhDbkiwA== X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;31:w1PiGoQB/QwcoQ6KTywzL+8TOCFpOllcKrmHeC0WentVpu8bj7wJxA/NoS1CWghxpn/VzMaYTWKvQDvT9YybANVUo0YWurT2qUVxhtCvDnCVeYmIBEhZjDVwX/ckubVCNcuQ7vmhZbpLkw08lEA3w38SbmQO3vYv895tK0Goqfl2uKupWSNDU0P1eh1FSLwQ61RWcLEO5slp2IciQEkJosfMxfJBZcBXxw5yi8xeLkYi7R5Dzj8AjoPO3LlmDiSSewKo9gkLM7vNp7esWZ9BTg== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6060326)(6040361)(6045199)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6061324)(6041248)(20161123562025)(20161123555025)(20161123560025)(20161123564025)(2016111802025)(6043046);SRVR:AM5PR0201MB2308;BCL:0;PCL:0;RULEID:;SRVR:AM5PR0201MB2308; X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;4:YNISMf2lGEyNcx+qLyu6g0b4F0EEP9efKNWMo0al2F0d+l/j2EMVwmPjuNLxJXzxgCbtMq83Gso40snGnUJ75ewrAMRl2C1VF/sCmTRCdoaslL1sBb/VFuRqPmuS4CfGtZ+8EuFzbygllc0d+UcigD3/iqO2+RpMnkDzh3sq5qDYtRwjcVsZrnMnJ3fU1YvrRDUfHU7fliaET1drpF2RNPgN9PF/N2gGxOH8FRpRYLzDZvMN54YTfoGV2oIewLj6izMumN5dQUZjV14+oF3190PYwAQHCAyQH5Y8iVBnrqoZYc6k7b6FIQqPpK3a99xGSxT6tCGFVPc7M8slAULjSrVWfuOGkcaZEx4u8rBU+ZKX7iwc9jwbryG1L2XE7d6PFqJIxphAJWApPZdZjJwFd22Cokz7mB63Ybci48vkppIeZa9Ep/cS9fiCUoMYKhLoOw9BA+qSOoAClrZVW3UD9h1YEU0WH9/POgjcZhIYSjE3AZPfD04ZvcuQD6OK56UArb8Wmy9RRKyK6CgywUeDWvIzOa0qqAs/+5TLDOjY0+PHhF6QeEiQ5cp9R7zmAgmOLX+Difnv2hZWTigeHcWVOehu51s6Tfpe4+amYlk0jVS3WaUKaleyi0aIbgAMvettyLcarg0BJ55ojL9HaMkoHDy1O2mgoetuF5UjcS/67WM= X-Forefront-PRVS: 01415BB535 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(6069001)(6009001)(7916002)(199003)(189002)(39450400002)(74482002)(39400400001)(39410400001)(8676002)(7416002)(39380400001)(106356001)(86362001)(42186005)(50466002)(48376002)(101416001)(6666003)(105586002)(6486002)(733004)(6916009)(5003940100001)(50986999)(2351001)(81166006)(81156014)(8666005)(97736004)(92566002)(6116002)(36756003)(76176999)(2950100002)(7736002)(189998001)(4326007)(5660300001)(66066001)(68736007)(50226002)(2906002)(110136003)(47776003)(33646002)(7846002)(38730400001)(3846002)(305945005)(7059030)(2004002)(42262002);DIR:OUT;SFP:1102;SCL:1;SRVR:AM5PR0201MB2308;H:localhost.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM5PR0201MB2308;23:aAonn8yqdw7OuTEltTjRGS390A8gq+Lp+ZG76Y7?= =?us-ascii?Q?4dGHCkIYVrVrtGPULDFllD3kf5w8UF4H92Zj1M6bLX8s7sFmqhnnQmxHWTs0?= =?us-ascii?Q?bWCQ+5rULUeQR0sdJlmcTa2NKWRUfisyJ0dPE0RcHCxpnqQAiDwviLwGeH52?= =?us-ascii?Q?fBHiq/DwbfPvxh+ElAjHtwnbC0UOLtKe9wHdfHcyTzQf6mui6pl0k5WwKBWq?= =?us-ascii?Q?9lbEh+jfF2HqdzXDFrhyhZBV5zVkoZicqFTU3F1RNCZT2KApR/Ehc7OpC3Re?= =?us-ascii?Q?yMe3kqOpYCSLf58QyzaPyvtCCw0cIbtCk7sSTLyOOjltcbqIjwWaXVs0goUT?= =?us-ascii?Q?WIvnndYjzJ57YKGpxNJK3g5ck75WM3E8u991u9aMoGsualw1eYxNoqaBa2Gv?= =?us-ascii?Q?dJrsklhi/Z+q+aNNXUVI5eNLftiVp2VGVG9MqDIYJsrLhq2m4GJQ4DwrAs7f?= =?us-ascii?Q?wIOZwkUHEPmKhFH5jsASbMB9gqLI1bVQvZuhvg4CmYiDfUjN26blw/nJpi6W?= =?us-ascii?Q?5ISL18StW6S2FPeeNjAUjBm2/K/sqADCPmvczxUxSlwrKCdSI0n7Xsjn10Kv?= =?us-ascii?Q?GWHz1HRk16+kNxCWr2CwXbb8PdhdgJGiI8P3QKoFH92br53aNwnJqlm4d0Kw?= =?us-ascii?Q?zrwzUtNtif54Bd0DS9nDG6v1lzJcMtO4EDrS/3oMpHIw3gCSmZFtUl7IFg2N?= =?us-ascii?Q?dahL2ITLHeW9KzWaZ54j8hCCi9OhrlFJYbRTMOrV6SxkTGX3D3EeBViYJmnn?= =?us-ascii?Q?wZbYIzzpvs5T642goxViKCXoiQEWXC4Ozy97MFSrxJc/fHtvL6h1ZNv5bthB?= =?us-ascii?Q?8Q1v2sIJW+X6lMwM3QyMQaRO9vzLxIEI7QPDQSHydKrFsfd/l4bCyby6wXN8?= =?us-ascii?Q?Taee1POHKDZmlexzYPdohYlEqQUNlwce6mWYIi0iLlb0sFo/J4vGfRpYbXHm?= =?us-ascii?Q?Yg0lUIjM1vpPmyQwCyYK1SU7G6hP8TSu3DJDutxoKZMaqGPpzDxLq+yvwa/l?= =?us-ascii?Q?ERANWceC1V40LUASAxy+PtgW1ppgORczKg0975Q3zLathoouGHqttms37aP6?= =?us-ascii?Q?aTPk2qvXZie+QYTsiGUETRfA55rfC6hnq1H+a+yJg47zHhFZAeHfKsA6F1bA?= =?us-ascii?Q?DBojq29jCBjQq+0HSGd66j92HJYJiM1eMlWqluQ5JKFujRBI3k0cKVuLZNkI?= =?us-ascii?Q?EX7NLo2BaAViMS0+Y/ydviyJiW2XLZClGKIH42T9xvTslef1K/AY67ctU9Cq?= =?us-ascii?Q?wq3NiqxxZ8iujvVO1vMpPYrwqUSPLkSLWupahAcWTjoXBTa+MFDlPmrYQOlO?= =?us-ascii?Q?gKA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;6:9lU0j15bIFzmYFel7oZBgIUl5709gcygCJKRhoTgaCCJQlmmk/akAeRDjl3zsiDeX3UpgY4aQBlGGJGt7VLr2C34q1XfNfhACUlui65Tx0dvqKtebKXK2YQSfKultuaEZBel0KxcOP5cnrCvqzctZlEwmFfxodvbNwQSfWFjVYFpwbyNRTOSbgqHGZ+IDnL9pYrLQ/YG60DtQPdnQPVfxJhSfT4nyYPx488t8eOfvqoj0atsouw2BZUDoUEYlR2hCRz3THVG0K/1NXmUMMPOB7Hu3pnJkX6zPWGY3OgX7z69mmXejvijLotFlM6HXvlRdc605XLz5jCjQJmONeNWrlSxVtKTU1iWoPMkYGiZvcdONC8QEolUop6PKuerc7CII+I8nk1beOiDQR8y4fFAi39vGZCjpXczoT0m/kuFBRzX3noLb2E3C+WiGYlFps2fMUKNOaDlI6zX530/6gAR0MUq9zOiNiY8fGT8K6MvVtM=;5:fXERLQUR1vHzEVBRp1ZR9yP/7MIUWt0X9JIlHiaD66xxWHIKA79jtlp9Hkk7MlxZkHQa60YNCpNO+npNyU8QDHzRBsIK8edo5loiZmR+3pj0arQIqYHpHqivjA1EjX/YRZVIqtKjMNGrYOyYZ9NAWA==;24:ZxmysoyY80cAap3rUuPjoJnjS8cdparHfTdJ3a9CDfO6hzWFkEv9NuknXUyIgS++oc/hNJviIJZCbo/5pcFDjMyHwAZVCwiqP9RqUSUQSY4= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;AM5PR0201MB2308;7:Fu30F4MC600uYNLFB0b/iAIsuglLn7qkE++flQFG9OW2HWWLEIGYOeoyGTL8scrZ/IfvieorpFrny0K0N2DTZbY2lfLpU2FItlp/RFxo47u/eESoJpd1QhI4Bkd8BBhaygD2lCAGgE/PrlPPIYCz4xuFQBO8utI3yED7uZ30Bxo2k/cPByZDKtJFu0cj3CnIgTskor6W92Ama55Nhi/jgXeHfsZ9JrxPHBNBQzxx7qjGoqvxbolKE0XquI3Ohz5B6P4JuJIrzAAF08+rIUG2o5fRVMH/katLY2CA2rSez7lkF6akRDBux0B0GYLmmZW50WZFcNC7xwrnP23qLLuSKEgEA1QAaGjMQ3K/1+4nVJeV82eSkmzTUArnPoYDeXp11dqxiGzuC10ErGJb8GVb1c0DPQCbaRBlRsCJj0aaQHLR4JE0lv2p1HU6j+P0RKm0No/sZJH8a1OYOYFLmDOOlw== X-OriginatorOrg: axentia.se X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Nov 2016 10:12:17.1826 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0201MB2308 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. Signed-off-by: Peter Rosin --- drivers/misc/Kconfig | 12 ++++ drivers/misc/Makefile | 1 + drivers/misc/mux-adg792a.c | 154 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 drivers/misc/mux-adg792a.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 2ce675e410c5..45567a444bbf 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -780,6 +780,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 + parellel 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/misc/Makefile b/drivers/misc/Makefile index 0befa2bba762..10ab8d34c9e5 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o obj-$(CONFIG_CXL_BASE) += cxl/ obj-$(CONFIG_PANEL) += panel.o obj-$(CONFIG_MULTIPLEXER) += mux-core.o +obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o obj-$(CONFIG_MUX_GPIO) += mux-gpio.o lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o diff --git a/drivers/misc/mux-adg792a.c b/drivers/misc/mux-adg792a.c new file mode 100644 index 000000000000..279dcf381695 --- /dev/null +++ b/drivers/misc/mux-adg792a.c @@ -0,0 +1,154 @@ +/* + * Multiplexer driver for Analog Devices ADG792A/G Triple 4:1 mux + * + * Copyright (C) 2016 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)) + +#define ADG792A_DISABLE_STATE (4) +#define ADG792A_KEEP_STATE (5) + +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 == ADG792A_DISABLE_STATE) + cmd = ADG792A_DISABLE_ALL; + else + cmd = ADG792A_MUX_ALL(state); + } else { + unsigned int controller = mux_control_get_index(mux); + + if (state == ADG792A_DISABLE_STATE) + 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; + bool parallel; + int ret; + int i; + + parallel = of_property_read_bool(i2c->dev.of_node, "adi,parallel"); + + mux_chip = mux_chip_alloc(dev, parallel ? 1 : 3, 0); + if (!mux_chip) + return -ENOMEM; + + mux_chip->ops = &adg792a_ops; + dev_set_drvdata(dev, mux_chip); + + ret = i2c_smbus_write_byte_data(i2c, ADG792A_DISABLE_ALL, + ADG792A_RESET | ADG792A_LDSW); + if (ret < 0) + goto free_mux_chip; + + for (i = 0; i < mux_chip->controllers; ++i) { + struct mux_control *mux = &mux_chip->mux[i]; + u32 idle_state; + + mux->states = 4; + + ret = of_property_read_u32_index(i2c->dev.of_node, + "adi,idle-state", i, + &idle_state); + if (ret >= 0) { + if (idle_state > ADG792A_KEEP_STATE) { + dev_err(dev, "invalid idle-state %u\n", + idle_state); + ret = -EINVAL; + goto free_mux_chip; + } + if (idle_state != ADG792A_KEEP_STATE) + mux->idle_state = idle_state; + } + } + + ret = mux_chip_register(mux_chip); + if (ret < 0) { + dev_err(dev, "failed to register mux-chip\n"); + goto free_mux_chip; + } + + if (parallel) + dev_info(dev, "1 triple 4-way mux-controller registered\n"); + else + dev_info(dev, "3 4-way mux-controllers registered\n"); + + return 0; + +free_mux_chip: + mux_chip_free(mux_chip); + return ret; +} + +static int adg792a_remove(struct i2c_client *i2c) +{ + struct mux_chip *mux_chip = to_mux_chip(&i2c->dev); + + mux_chip_unregister(mux_chip); + mux_chip_free(mux_chip); + + 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, + .remove = adg792a_remove, + .id_table = adg792a_id, +}; +module_i2c_driver(adg792a_driver); + +MODULE_DESCRIPTION("Analog Devices ADG792A/G Triple 4:1 mux driver"); +MODULE_AUTHOR("Peter Rosin