From patchwork Sun May 6 13:30:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Nazzareno Trimarchi X-Patchwork-Id: 10382793 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B6EAA60318 for ; Sun, 6 May 2018 13:30:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 968CA28B03 for ; Sun, 6 May 2018 13:30:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8558A28B3D; Sun, 6 May 2018 13:30:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 38A8B28B03 for ; Sun, 6 May 2018 13:30:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751187AbeEFNaw (ORCPT ); Sun, 6 May 2018 09:30:52 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:35378 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751180AbeEFNav (ORCPT ); Sun, 6 May 2018 09:30:51 -0400 Received: by mail-wr0-f195.google.com with SMTP id i14-v6so22154654wre.2 for ; Sun, 06 May 2018 06:30:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=from:to:cc:subject:date:message-id; bh=0EL3gKJN2TMbhCvNaM3vWH6+evDdNOPfb4IkxtxW55Y=; b=WyNpgtF41nBd25hdWGpeRbP2NeZS33O+fUPY7lGWAbJh9vFYYiVR6EajQjr5xfsKNZ TtMBL7EBQ3IPOJig5KWzUMq4L45+aLFlFpYW+jQfdmpJArN7vOoKWNXW6nr+WC6gqnkx J72+ah2U0v1SKmJmx/4mOp6qq0FBxjJiMQ54g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=0EL3gKJN2TMbhCvNaM3vWH6+evDdNOPfb4IkxtxW55Y=; b=IUDB/hOk10tRpB0llsjrkq8fhyRNvdAWaBXl48q1MwtVmqMjOyOFFIWeIraea1h4eq s/byIbTygXPKWleczbBqOVnoAO/1Wm5OIFKuQCOEDUMFhyUqmWaSzV3evSAtPsVYbeOY BgoyiFxw3b/+Sl2OWyVhWvTjUCUgcuX5rS5MHlmkgxskjxc1L0an+LgWG3SxWRSQ2l+0 MuzGEn0AOGnSX8qgr2pd7+0d8vZp5no96dfuilQxTi3mppMn/Y6aRrvWSZ83OFu4e79b n4ITQ9+Rc0hqmwYMv+7e0KMIg7doDwF6tfYl/S88ZZPW2Qev7IPzI0IWCF4nnye3vCy6 t4fg== X-Gm-Message-State: ALQs6tAbOzid+NebibTcXqai3F3lpYdUioqYz4njBT55ixHpawdXme8/ X9kZW0rp9u4u8g1tF/Di09tc4g== X-Google-Smtp-Source: AB8JxZpR7F5AQMzslzOrlbXyyVnQI08/YLK24E3sZUESMxeSNbbiF0WZBEjhiaoO4LTHZeE0X1/e1g== X-Received: by 2002:adf:9ae5:: with SMTP id a92-v6mr25394203wrc.180.1525613449507; Sun, 06 May 2018 06:30:49 -0700 (PDT) Received: from localhost.localdomain ([151.64.48.169]) by smtp.gmail.com with ESMTPSA id l37-v6sm35686718wrl.83.2018.05.06.06.30.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 06 May 2018 06:30:48 -0700 (PDT) From: Michael Trimarchi To: Jonathan Cameron Cc: Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , linux-iio@vger.kernel.org, Michael Trimarchi Subject: [PATCH] iio: potentiometer: add driver for Maxim Integrated DS1807 Date: Sun, 6 May 2018 15:30:47 +0200 Message-Id: <1525613447-32734-1-git-send-email-michael@amarulasolutions.com> X-Mailer: git-send-email 2.7.4 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The following functions are supported: - write, read potentiometer value Value are exported in DBm because it's used as an audio attenuator Datasheet: https://datasheets.maximintegrated.com/en/ds/DS1807.pdf Change-Id: I24f6b33cfa92ce16f489ff763f1df26126a1a7f2 Signed-off-by: Michael Trimarchi --- .../bindings/iio/potentiometer/ds1807.txt | 17 +++ drivers/iio/potentiometer/Kconfig | 10 ++ drivers/iio/potentiometer/Makefile | 1 + drivers/iio/potentiometer/ds1807.c | 156 +++++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/potentiometer/ds1807.txt create mode 100644 drivers/iio/potentiometer/ds1807.c diff --git a/Documentation/devicetree/bindings/iio/potentiometer/ds1807.txt b/Documentation/devicetree/bindings/iio/potentiometer/ds1807.txt new file mode 100644 index 0000000..3e30f4c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/potentiometer/ds1807.txt @@ -0,0 +1,17 @@ +* Maxim Integrated DS1807 digital potentiometer driver + +The node for this driver must be a child node of a I2C controller, hence +all mandatory properties for your controller must be specified. See directory: + + Documentation/devicetree/bindings/i2c + +for more details. + +Required properties: + - compatible: "maxim,ds1807", + +Example: +ds1807: ds1807@1 { + reg = <0x28>; + compatible = "maxim,ds1807"; +}; diff --git a/drivers/iio/potentiometer/Kconfig b/drivers/iio/potentiometer/Kconfig index 79ec2eb..92e5a6b 100644 --- a/drivers/iio/potentiometer/Kconfig +++ b/drivers/iio/potentiometer/Kconfig @@ -25,6 +25,16 @@ config DS1803 To compile this driver as a module, choose M here: the module will be called ds1803. +config DS1807 + tristate "Maxim Integrated DS1807 Digital Potentiometer driver" + depends on I2C + help + Say yes here to build support for the Maxim Integrated DS1807 + digital potentiometer chip. Value are reported back in DBm + + To compile this driver as a module, choose M here: the + module will be called ds1807. + config MAX5481 tristate "Maxim MAX5481-MAX5484 Digital Potentiometer driver" depends on SPI diff --git a/drivers/iio/potentiometer/Makefile b/drivers/iio/potentiometer/Makefile index 4af6578..3c409bb 100644 --- a/drivers/iio/potentiometer/Makefile +++ b/drivers/iio/potentiometer/Makefile @@ -6,6 +6,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AD5272) += ad5272.o obj-$(CONFIG_DS1803) += ds1803.o +obj-$(CONFIG_DS1807) += ds1807.o obj-$(CONFIG_MAX5481) += max5481.o obj-$(CONFIG_MAX5487) += max5487.o obj-$(CONFIG_MCP4018) += mcp4018.o diff --git a/drivers/iio/potentiometer/ds1807.c b/drivers/iio/potentiometer/ds1807.c new file mode 100644 index 0000000..acb4884 --- /dev/null +++ b/drivers/iio/potentiometer/ds1807.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Maxim Integrated DS1807 digital potentiometer driver + * Copyright (c) 2018 Michael Trimarchi + * + * Datasheet: https://datasheets.maximintegrated.com/en/ds/DS1807.pdf + * + * DEVID #Wipers #Positions Resistor Opts (kOhm) i2c address + * ds1807 2 65 45 0101xxx + * + */ + +#include +#include +#include +#include +#include +#include + +#define DS1807_MAX_VALUE 64 +#define DS1807_MUTE -90 +#define DS1807_WRITE(chan) (0xa8 | ((chan) + 1)) + +#define DS1807_CHANNEL(ch) { \ + .type = IIO_CHAN_INFO_HARDWAREGAIN, \ + .indexed = 1, \ + .output = 1, \ + .channel = (ch), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN), \ +} + +static const struct iio_chan_spec ds1807_channels[] = { + DS1807_CHANNEL(0), + DS1807_CHANNEL(1), +}; + +struct ds1807_data { + struct i2c_client *client; +}; + +static int ds1807_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct ds1807_data *data = iio_priv(indio_dev); + int pot = chan->channel; + int ret; + u8 result[ARRAY_SIZE(ds1807_channels)]; + + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + ret = i2c_master_recv(data->client, result, + indio_dev->num_channels); + if (ret < 0) + return ret; + + *val2 = 0; + if (result[pot] == DS1807_MAX_VALUE) + *val = DS1807_MUTE; + else + *val = -result[pot]; + + return IIO_VAL_INT_PLUS_MICRO_DB; + } + + return -EINVAL; +} + +static int ds1807_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct ds1807_data *data = iio_priv(indio_dev); + int pot = chan->channel; + + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + if (val2 != 0 || val < DS1807_MUTE || val > 0) + return -EINVAL; + break; + default: + return -EINVAL; + } + + val = (val == DS1807_MUTE) ? DS1807_MAX_VALUE : -val; + + return i2c_smbus_write_byte_data(data->client, DS1807_WRITE(pot), val); +} + +static const struct iio_info ds1807_info = { + .read_raw = ds1807_read_raw, + .write_raw = ds1807_write_raw, +}; + +static int ds1807_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct ds1807_data *data; + struct iio_dev *indio_dev; + int channel, ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + i2c_set_clientdata(client, indio_dev); + + data = iio_priv(indio_dev); + data->client = client; + + indio_dev->dev.parent = dev; + indio_dev->info = &ds1807_info; + indio_dev->channels = ds1807_channels; + indio_dev->num_channels = ARRAY_SIZE(ds1807_channels); + indio_dev->name = client->name; + + /* reset device gain */ + for (channel = 0; channel < indio_dev->num_channels; channel++) { + ret = i2c_smbus_write_byte_data(client, DS1807_WRITE(channel), + DS1807_MUTE); + if (ret < 0) + return -ENODEV; + } + + return devm_iio_device_register(dev, indio_dev); +} + +#if defined(CONFIG_OF) +static const struct of_device_id ds1807_dt_ids[] = { + { .compatible = "maxim,ds1807", }, + {} +}; +MODULE_DEVICE_TABLE(of, ds1807_dt_ids); +#endif /* CONFIG_OF */ + +static const struct i2c_device_id ds1807_id[] = { + { "ds1807", }, + {} +}; +MODULE_DEVICE_TABLE(i2c, ds1807_id); + +static struct i2c_driver ds1807_driver = { + .driver = { + .name = "ds1807", + .of_match_table = of_match_ptr(ds1807_dt_ids), + }, + .probe = ds1807_probe, + .id_table = ds1807_id, +}; + +module_i2c_driver(ds1807_driver); + +MODULE_AUTHOR("Michael Trimarchi "); +MODULE_DESCRIPTION("DS1807 digital potentiometer"); +MODULE_LICENSE("GPL v2");