Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933612AbdCWKed (ORCPT ); Thu, 23 Mar 2017 06:34:33 -0400 Received: from mail-cys01nam02on0053.outbound.protection.outlook.com ([104.47.37.53]:11905 "EHLO NAM02-CY1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754294AbdCWKeC (ORCPT ); Thu, 23 Mar 2017 06:34:02 -0400 Authentication-Results: spf=pass (sender IP is 137.71.25.55) smtp.mailfrom=analog.com; vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=bestguesspass action=none header.from=analog.com; From: To: , , , , , CC: , , , Michael Hennerich Subject: [PATCH] iio/adc/ltc2497: Driver for Linear Technology LTC2497 ADC Date: Thu, 23 Mar 2017 11:35:10 +0100 Message-ID: <1490265310-6162-1-git-send-email-michael.hennerich@analog.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Content-Type: text/plain X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:137.71.25.55;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(39850400002)(39410400002)(39450400003)(39840400002)(39860400002)(2980300002)(438002)(189002)(199003)(8936002)(36756003)(8676002)(38730400002)(107886003)(106466001)(47776003)(77096006)(2906002)(7636002)(305945005)(2876002)(189998001)(6666003)(48376002)(356003)(5660300001)(50466002)(5003940100001)(2201001)(8666007)(86152003)(54906002)(1720100001)(4326008)(6306002)(33646002)(50986999)(86362001)(966004)(562404015);DIR:OUT;SFP:1101;SCL:1;SRVR:BN3PR0301MB0884;H:nwd2mta1.analog.com;FPR:;SPF:Pass;MLV:sfv;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BL2FFO11OLC002;1:6Wy6ekQjbbZB30iz7sx/ZpRgaj4C2S1YetHqVpxeRVWVxUVDOySIEXBePNaVq6nprP4Wup/wnkXKulY6sHW1raIM+odY7PnWm9pUZJLlbQoqLA4X4MpkHizxnFGk61TujWcJq4/wL5Ibsx03+uj0nA3Ktoyjbe8apcuSHvPq5rqboRHvjafXWofUYj+G+1q9vVf1fVjPImZYSHi9XAqOeT8SVG6Lwg+2tCryEFx4QxEnOT6R0j7f1hdi7QXxuFpXxGg2KWKsmTOjeADALW6iNcrPj2I6w+u8mYzEJD47u752mcY1Dh4cVU9pImlODbhOq3MhNPkX8sjY3YJH4P0Ay90jZIwEnTK8ArjxPJjwsz6DLSoWqDM8TK4QzwHpaqxoANlUKmvhpCV6CIyOSeqiihWuh7VrrL2sih+PBxQe+5dMdUdPTKvSvAgqI3HQ7qR+Tnu5sywkksREJBn3ZZ3HwknuIqZmOxQOKbP4tMMQLn86Ev+SUz7w/lYpMbF1wpywemXibWQBWE99H3S95KpHLg+zgNcmAg5IM3t4nisBtalkW7UR++m6AQuXDHoyd4XZQO5FTr+gmHGe2qzLxEJVgdwAzhHYBN4l9YDyayLCgdlmBNzPdmbo40zBrtplOT8X X-MS-Office365-Filtering-Correlation-Id: 8775a39d-433c-47b1-c847-08d471d81b74 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(8251501002)(2017030254075);SRVR:BN3PR0301MB0884; X-Microsoft-Exchange-Diagnostics: 1;BN3PR0301MB0884;3:ztKmCvfKGuuFtlPQTkubiE37Avqnz8WrO8YkO3+ea+b5ywjQzHYMUFI9xlZlJ5Qcw0PRa7G27V04DgnpvBiqld7a4jj+ythftihqFoxGnvW2UM1gOYgR3RGrOGr4Z4rJZHNjWGKqY9tSVXIvWDBSMqgqzJaneDpzpF7q3WKypkaVxdVaD7QvrkFQAuOf8jST7AEtxLuJA4kxc+x7cfcODpOgth8yLOUve0FmIwxTKvrnwvVqumXYonk8+V2g69uHIcTlV45UK1x1njjLvRn6u//0/57B44Tg1ySFsV0Eb1GX5Ox0J8hd9xOvlkhGaZ/G1zN2UUldQ5ZQ852pZom336QX8pBeO47BH5rDsa/RWAqus26/Oz3fP+4lFL17FTmY8hIf2LlpBTXBIGPHzVhWXokV/hPa/QqZ1+fDawPZLa0=;25:kj9xhdqLGld8vxZb+emfxZH7yCRhCeTXZvGQNC6o96zBI+qKO9ClzM5wN7wugH98Y/VIStxTXvyBVZA6DuWoPL4MAs891MrmAiZIYVM+3BAVelB6TNDoE2y4kfIujvEdwfkJpOcbguHgYjo4yA+N22oJULKJgYiBDmCpSNCJ/UOa0mJONGThwDUPhrXYrqLW2vE+BrKR969ptg8V4d2cWFQt9p3hEYC7oFm0i6/Sj97bp2U9f5PytsXIA3IV0mnXPZ68ThgEArCGxS9pHj6uFw/wH5zMywzam3TJehcyKFu2ApVfv46ALMok+igPDRXUUamySkzBiUpRZe4icYECCbBeu7tD3x+L5dV4+HOTv2N3vxlVBbisu2KptbJVqGCnxqSBkqcrlPQY8r3g2MsMiJcN79eqONzs7lYLtolfevPcMI79JGp8zcc0R2KXM2hPgE0wFczElj4K8OcE2C2K1w== X-Microsoft-Exchange-Diagnostics: 1;BN3PR0301MB0884;31:igN8QjGxtqBIR51JA9DzVhtIOH/Yj2/0zsREcCf9pSIovsbyK+1HbVeb31GNLz5jy7yNXerYoxqjFeyBSLJmKCVLFTQxKDAW3GKbkmwUzEP4LGwoRIRcwru10PaO35GXRcHEReaHlrfHHL3CPE2Sy8Pt4/0DKJ5O1g+Mcc3QO30w6bFn6gHVZE++1gWSuyBY6uOphdae437vd/Ty15ZHViHLvaem7U+IuPL6Dl5Uzy27OsNkzdolvrICH8ZodctR+E5jffRvL/d3c+5nN2lUeQ==;20:m6NaGsJZM0BIYeSe33AeGmpFsIMfBnFbFhvbwjF+qcWWjH/O/HZsk+OuTTpaxOlZcitkQ1LTug0z1plOaqU1mII8g52l5LHjIrQS5UZj5uBcDfhDFVUVQInZ3+kAgCXx2nXe3coO1g/7upJiF/vScuLa48VfzZ/TXsc0ML+TiGHrB+fT6H9Q03Nqt5Mbl56mX/Ag06JUzGBd76++AV8BDQI0iHmxJFuZZXOw/QvsP12ohf/vRuJVfS2EVAMBcRISwgtCl/QYNg6ZDDmZLTII4gRouBjxksGrbRhlM9Aed9Os5zaZ7PsTV7h3RUU5eqUiQypsubkyFRvY3n+ZcW1pWDHQnDryzWojvQumOrkfff7sqFU/YdTQDl421/EDJiJ7pHxLit9Fq4tTNm7i770m3I3066d4eTenGH8VIc5gJFGzaH7Ryl0EboAFoXameGg74OkBKZkJ9FGpAddTWdzAfuIbn/t9rid6aEdE6rtRvro+6Z2owhSMMluFBuYdXMWz X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(232431446821674)(170811661138872); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(8121501046)(13017025)(5005006)(13015025)(13018025)(13024025)(13023025)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123560025)(20161123562025)(20161123564025)(20161123558025)(6072148);SRVR:BN3PR0301MB0884;BCL:0;PCL:0;RULEID:;SRVR:BN3PR0301MB0884; X-Microsoft-Exchange-Diagnostics: 1;BN3PR0301MB0884;4:g11nfGPbL5WJCNTqL9j6etBPGAP1M3Y121Gk0v32LoK30fdjJAmAIUaVfUmgFcDmnko9ggcZSbj0XdGX48rCNegPSc7gkYJOslNZ2c4nvyFpAaujpvTy1x49PIWW2a9Fnpm/tGPMDsveZVh+ICEh6/L97HFsGMx1J1ag+3a8D6H+0Qy1bcZeAK5ltYp5Jh0+qxLeSTdix/qk1dd8+XoITBacr+4QHdzrabQQ5rVeVCAq27XEFL00Vp1MimhSsclb9JJbAgohua+JsJ96Pipcg3tXy+QfxQQPY98pSO6uZXYT4sj4f37aMWDasfesTGSRehh7H30fhE7s8RYI8b8wTd0DTJQaNBI7izqf0aWsoHPP/N4OYtkHJosQTP7SIil8hpiNrY4rHnl+rj/DyJFsfxlcS9wxpDKu+ScpyD0r0xGfXjYLprLP4gC0d0FJTeWn4D//PPgHSIQlRZTjjmMW1n03JuRsOCIs6GfsPoywbqNRDu7ct8ulL7bU2ikW+BXB+i0uOVxhkM3CwaEFLtPlrt1CyKRRsEKRKwgnn64WDeUhVtY5RaCVDQdn8+LKDrC56h6ED2Fct3jqddcfHJHaiAPhDsEBZdTWQRyDuVRPmXY01KdmdCMQyL679zfUVWff3KfnSE8vDCVPREopdcG7LXDErTN5gpfTYIW68sbbmytOyxBQ2Vb7QgJx8Q5wDH8pCxC4x9L7VFkVHHl92fC6LaPAenDcKurw2b34B5m2OJuKmLGo+PuXB9j8DYOQE3QkXt/daq6zWZkl+7XiIhXKU6elcSqbujCTvU2vGEf8vuk= X-Forefront-PRVS: 0255DF69B9 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BN3PR0301MB0884;23:wb0LkXAJP0LPtro4BXZG+1K4HAIhiQDalZ7bxDa?= =?us-ascii?Q?7LgEawuT19Dc7EM8UlhGpItsqlusAkssblvguBlQ/uuebDkGTC8gr3cfoKiZ?= =?us-ascii?Q?JL8+lgZSMudaJHZhbSYIIn3L6/HVSm0ugC5iwURZFMoXlqU/P8RYh7j65WmI?= =?us-ascii?Q?CJzmJIpoZav//OqkNaZFT1igns33BQEtcDzUcRNeBqJfNiUiQN6caZ7ywy0u?= =?us-ascii?Q?TJ1Cd8nbK7huxBzB9xxNOomKEH/nyDcCzx9e56DtbQYeGoQz+ARzVkDCNM/+?= =?us-ascii?Q?6caaUHwlCHmsJqgiNrtM+uMRVBmdTdYNAM4WjKDe2KWhEOzTC6tVpZJpMuNP?= =?us-ascii?Q?v7IHFNTDIgMILAsZWUqjPLuZz70W+OjzbY0GI/RhEfxdHAmZirnT9UFsH2R4?= =?us-ascii?Q?5VyVHTN76g0GXIPR161+UaNCXzq5UfWF3/oTWjZ+/oPI8B5DqaadqHQUkyFN?= =?us-ascii?Q?6AemJuMOYwuulyHIrUhgc1bGhUEBoWXyQi+j5LD6UxZ0MVBe3ly6PWjyPPk0?= =?us-ascii?Q?SzC/6cegBwSM6idoO6OFLt8peHiCso/NBHXbIfki8yZ8E9E/HShlA5cEed2k?= =?us-ascii?Q?qtN4i4tjkU/p2Bnzx0enHBnp3w513M0MWkMm15DIvLyOcFeycKn9D6PgDZDR?= =?us-ascii?Q?ff3Jb0N+7NUEfoPep24phN0i6UERYYBJqenHYhb/JGeWmsnGW7oUjqXofd+d?= =?us-ascii?Q?FrBY7d2e2bqmPVrM7jgad27oc7AnYgcAabcTELv2L1mmC68SOTXTCKMG8srq?= =?us-ascii?Q?ykjSyu5VixTkYsqhYhFDqweHHw/mBIi2jB8Fr0+F4Cy1xXoj7XN7XinxaZ2h?= =?us-ascii?Q?VpAT/aOoXfSwIinUDqg9wKPEtmv/xcZo/rg0W2uaUkDpxZnZDYtirOjYuy/s?= =?us-ascii?Q?yziEDbHaGbR3py3mjVLROyPUFDX5EFJ+EgfRKPvgmLf0mybNeahH4kQGt3mD?= =?us-ascii?Q?VWpAHrlreR0ivGjrgu+Hrj9nw6Dp+jG7G0ZDiXA19Jwc3VLVKDAxoVoll1av?= =?us-ascii?Q?YRyVruhhYjMGSJRAC3JTqzQrk?= X-Microsoft-Exchange-Diagnostics: 1;BN3PR0301MB0884;6:iR8Qn1k3WjucLkM+lY3dKSWzE4tjYP5jRL8ytuJgR8532KJfV74RAHTqKa+62gBG6fIm3C+VAm560Ee5eSbJ4cj9gTjfG6oAf1RR4PphLpwyu4/xZX8EDtGKKzilRUuFIkDMWcRrhCmlVUBwyWjULMpZG2WKSABgVlO+WEgAecqTFrXV6oMlnci3dfxHVySzIQF7UIg2SqKRpWhaVod333Aj4YPL92Qm18X4q9XUgUFV/0hnJ4EhpwyuAeagoblLO5wPTX01Gqxg5hoJbxwyb7cL5/yzaShVmgTRirbaG9QUjQaPfSugpRyajnJ+TXmxpg4GW5HLXm01niguFFaq1m2/giuhDY1rMMTwZymFr+3RVA5dE5Ub72MadSluvTt7Mu3/5JuWrazBt23+il14squLZc1pxkvdd2Cx0b8p7Ys=;5:hoHvl5wenJPZWU/DPHr1f3cWF0ALxj86uyHe4Dex7elaG53iH87uDq4hgClCpGuuyvThYPRpaQVy2Q1VZnLm/ZZSDjbsvAg0adpjE6A1/5mPHsrvrkWFRVnklIPr3PJbgcZH6wbzmpnHiES5fuz5gg==;24:ihmNOghjWvBiUOaxLahrZht3FiEeEY3n0KS66wto7bawemZ9RRelMEbkrW4hWakj3ACOJ3JDvYDkTuH+CQzuSBoP0gXmePnXNVZuBZ9Z/mw= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;BN3PR0301MB0884;7:Y4F+lV5cUCYCLPw/DKXdOEm49nHErqyxbrdCRbOFKAr/fuW1T8MuedhI+zTUPNXb1KFqCDuARisOwW618ecZhh+gbcNuwPkmgnJ8FpZmFuzUVa+YVVff0yH5pn6YYMdX2O5AxXOh7n5jfuJqw3Z1BOYWfDDiRmHm7CM8waVHvrUIKZNnXYF5kt4N44auFflsePKf2lg9rXEWiXWTaywkc0oPK2sxb64U7AILoemFULhkD+TLFWHj316WsvMh2/zke4rgRk8x3QqVXx9qXA8MIogt59ICH9amLWdKTFswzU+mRWzK+z8swBNlxvUgyJohxypn3XFEHw88IyR6i5w+4w== X-OriginatorOrg: analog.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Mar 2017 10:33:55.2503 (UTC) X-MS-Exchange-CrossTenant-Id: eaa689b4-8f87-40e0-9c6f-7228de4d754a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=eaa689b4-8f87-40e0-9c6f-7228de4d754a;Ip=[137.71.25.55];Helo=[nwd2mta1.analog.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR0301MB0884 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 9787 Lines: 349 From: Michael Hennerich Signed-off-by: Michael Hennerich --- .../devicetree/bindings/iio/adc/ltc2497.txt | 13 + MAINTAINERS | 1 + drivers/iio/adc/Kconfig | 11 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ltc2497.c | 263 +++++++++++++++++++++ 5 files changed, 289 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/ltc2497.txt create mode 100644 drivers/iio/adc/ltc2497.c diff --git a/Documentation/devicetree/bindings/iio/adc/ltc2497.txt b/Documentation/devicetree/bindings/iio/adc/ltc2497.txt new file mode 100644 index 0000000..c2829c19 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ltc2497.txt @@ -0,0 +1,13 @@ +* Linear Technology / Analog Devices LTC2497 ADC + +Required properties: + - compatible: Should be "lltc,ltc2497" + - reg: Should contain the ADC I2C address + - vref-supply: The regulator supply for ADC reference voltage + +Example: + ltc2497: adc@76 { + compatible = "lltc,ltc2497"; + reg = <0x76>; + vref-supply = <<c2497_reg>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index a7d6f9a..173043c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -813,6 +813,7 @@ W: http://wiki.analog.com/ W: http://ez.analog.com/community/linux-device-drivers S: Supported F: drivers/iio/*/ad* +F: drivers/iio/adc/ltc2497* X: drivers/iio/*/adjd* F: drivers/staging/iio/*/ad* F: drivers/staging/iio/trigger/iio-trig-bfin-timer.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 2268a6f..141cf4a 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -326,6 +326,17 @@ config LTC2485 To compile this driver as a module, choose M here: the module will be called ltc2485. +config LTC2497 + tristate "Linear Technology LTC2497 ADC driver" + depends on I2C + help + Say yes here to build support for Linear Technology LTC2497 + 16-Bit 8-/16-Channel Delta Sigma ADC. + Provides direct access via sysfs + + To compile this driver as a module, choose M here: the module will be + called ltc2497. + config MAX1027 tristate "Maxim max1027 ADC driver" depends on SPI diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 73dbe39..9d626b5 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o obj-$(CONFIG_LTC2485) += ltc2485.o +obj-$(CONFIG_LTC2497) += ltc2497.o obj-$(CONFIG_MAX1027) += max1027.o obj-$(CONFIG_MAX11100) += max11100.o obj-$(CONFIG_MAX1363) += max1363.o diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c new file mode 100644 index 0000000..0452715 --- /dev/null +++ b/drivers/iio/adc/ltc2497.c @@ -0,0 +1,263 @@ +/* + * ltc2497.c - Driver for Linear Technology LTC2497 ADC + * + * Copyright (C) 2017 Analog Devices Inc. + * + * Licensed under the GPL-2. + * + * Datasheet: http://cds.linear.com/docs/en/datasheet/2497fd.pdf + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define LTC2497_ENABLE 0xA0 +#define LTC2497_SGL (1 << 4) +#define LTC2497_DIFF (0 << 4) +#define LTC2497_SIGN (1 << 3) +#define LTC2497_CONFIG_DEFAULT LTC2497_ENABLE +#define LTC2497_CONVERSION_TIME_MS 150ULL + +struct ltc2497_st { + struct i2c_client *client; + struct regulator *ref; + ktime_t time_prev; + u8 addr_prev; +}; + +static int ltc2497_wait_conv(struct ltc2497_st *st) +{ + s64 time_elapsed; + + time_elapsed = ktime_ms_delta(ktime_get(), st->time_prev); + + if (time_elapsed < LTC2497_CONVERSION_TIME_MS) { + /* delay if conversion time not passed + * since last read or write + */ + msleep(LTC2497_CONVERSION_TIME_MS - time_elapsed); + return 0; + } + + if (time_elapsed - LTC2497_CONVERSION_TIME_MS <= 0) { + /* We're in automatic mode - + * so the last reading is stil not outdated + */ + return 0; + } + + return -ETIMEDOUT; +} + +static int ltc2497_read(struct ltc2497_st *st, u8 address, int *val) +{ + struct i2c_client *client = st->client; + __be32 buf = 0; + int ret; + + ret = ltc2497_wait_conv(st); + if (ret < 0 || st->addr_prev != address) { + ret = i2c_smbus_write_byte(st->client, 0xA0 | address); + if (ret < 0) + return ret; + st->addr_prev = address; + msleep(LTC2497_CONVERSION_TIME_MS); + } + ret = i2c_master_recv(client, (char *)&buf, 3); + if (ret < 0) { + dev_err(&client->dev, "i2c_master_recv failed\n"); + return ret; + } + st->time_prev = ktime_get(); + *val = (be32_to_cpu(buf) >> 14) - (1 << 17); + + return ret; +} + +static int ltc2497_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct ltc2497_st *st = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + ret = ltc2497_read(st, chan->address, val); + mutex_unlock(&indio_dev->mlock); + if (ret < 0) + return ret; + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + ret = regulator_get_voltage(st->ref); + if (ret < 0) + return ret; + + *val = ret / 1000; + *val2 = 17; + + return IIO_VAL_FRACTIONAL_LOG2; + + default: + return -EINVAL; + } +} + +#define LTC2497_CHAN(_chan, _addr) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (_chan), \ + .address = (_addr | (_chan / 2) | ((_chan & 1) ? LTC2497_SIGN : 0)), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ +} + +#define LTC2497_CHAN_DIFF(_chan, _addr) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 1 : 0), \ + .channel2 = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 0 : 1),\ + .address = (_addr | _chan), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .differential = 1, \ +} + +static const struct iio_chan_spec ltc2497_channel[] = { + LTC2497_CHAN(0, LTC2497_SGL), + LTC2497_CHAN(1, LTC2497_SGL), + LTC2497_CHAN(2, LTC2497_SGL), + LTC2497_CHAN(3, LTC2497_SGL), + LTC2497_CHAN(4, LTC2497_SGL), + LTC2497_CHAN(5, LTC2497_SGL), + LTC2497_CHAN(6, LTC2497_SGL), + LTC2497_CHAN(7, LTC2497_SGL), + LTC2497_CHAN(8, LTC2497_SGL), + LTC2497_CHAN(9, LTC2497_SGL), + LTC2497_CHAN(10, LTC2497_SGL), + LTC2497_CHAN(11, LTC2497_SGL), + LTC2497_CHAN(12, LTC2497_SGL), + LTC2497_CHAN(13, LTC2497_SGL), + LTC2497_CHAN(14, LTC2497_SGL), + LTC2497_CHAN(15, LTC2497_SGL), + LTC2497_CHAN_DIFF(0, LTC2497_DIFF), + LTC2497_CHAN_DIFF(1, LTC2497_DIFF), + LTC2497_CHAN_DIFF(2, LTC2497_DIFF), + LTC2497_CHAN_DIFF(3, LTC2497_DIFF), + LTC2497_CHAN_DIFF(4, LTC2497_DIFF), + LTC2497_CHAN_DIFF(5, LTC2497_DIFF), + LTC2497_CHAN_DIFF(6, LTC2497_DIFF), + LTC2497_CHAN_DIFF(7, LTC2497_DIFF), + LTC2497_CHAN_DIFF(0, LTC2497_DIFF | LTC2497_SIGN), + LTC2497_CHAN_DIFF(1, LTC2497_DIFF | LTC2497_SIGN), + LTC2497_CHAN_DIFF(2, LTC2497_DIFF | LTC2497_SIGN), + LTC2497_CHAN_DIFF(3, LTC2497_DIFF | LTC2497_SIGN), + LTC2497_CHAN_DIFF(4, LTC2497_DIFF | LTC2497_SIGN), + LTC2497_CHAN_DIFF(5, LTC2497_DIFF | LTC2497_SIGN), + LTC2497_CHAN_DIFF(6, LTC2497_DIFF | LTC2497_SIGN), + LTC2497_CHAN_DIFF(7, LTC2497_DIFF | LTC2497_SIGN), +}; + +static const struct iio_info ltc2497_info = { + .read_raw = ltc2497_read_raw, + .driver_module = THIS_MODULE, +}; + +static int ltc2497_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct iio_dev *indio_dev; + struct ltc2497_st *st; + int ret; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | + I2C_FUNC_SMBUS_WRITE_BYTE)) + return -EOPNOTSUPP; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + st->client = client; + + indio_dev->dev.parent = &client->dev; + indio_dev->name = id->name; + indio_dev->info = <c2497_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ltc2497_channel; + indio_dev->num_channels = ARRAY_SIZE(ltc2497_channel); + + st->ref = devm_regulator_get(&client->dev, "vref"); + if (IS_ERR(st->ref)) + return PTR_ERR(st->ref); + + ret = regulator_enable(st->ref); + if (ret < 0) + return ret; + + ret = i2c_smbus_write_byte(st->client, LTC2497_CONFIG_DEFAULT); + if (ret < 0) + goto err_regulator_disable; + + st->addr_prev = LTC2497_CONFIG_DEFAULT; + st->time_prev = ktime_get(); + + ret = devm_iio_device_register(&client->dev, indio_dev); + if (ret < 0) + goto err_regulator_disable; + + return 0; + +err_regulator_disable: + regulator_disable(st->ref); + + return ret; +} + +static int ltc2497_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ltc2497_st *st = iio_priv(indio_dev); + + regulator_disable(st->ref); + + return 0; +} + +static const struct i2c_device_id ltc2497_id[] = { + { "ltc2497", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ltc2497_id); + +static const struct of_device_id ltc2497_of_match[] = { + { .compatible = "lltc,ltc2497", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ltc2497_of_match); + +static struct i2c_driver ltc2497_driver = { + .driver = { + .name = "ltc2497", + .of_match_table = of_match_ptr(ltc2497_of_match), + }, + .probe = ltc2497_probe, + .remove = ltc2497_remove, + .id_table = ltc2497_id, +}; +module_i2c_driver(ltc2497_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Linear Technology LTC2497 ADC driver"); +MODULE_LICENSE("GPL v2"); -- 2.7.4