From patchwork Mon Oct 16 13:54:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Lechner X-Patchwork-Id: 153456 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2908:b0:403:3b70:6f57 with SMTP id ib8csp3476469vqb; Mon, 16 Oct 2023 06:54:55 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH0K2ke4xJ4xZQc1GJg2WO0zG2j4IoM/RUo5K273UkqDNdSopgy3DBIte9Y7WurOYnH1tqB X-Received: by 2002:a05:6359:b9a:b0:14d:2dd5:a777 with SMTP id gf26-20020a0563590b9a00b0014d2dd5a777mr28194398rwb.2.1697464495639; Mon, 16 Oct 2023 06:54:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697464495; cv=none; d=google.com; s=arc-20160816; b=Dhic3bpnoyVtoRKry2dbexQCT/+A8Iu+IE9yj2fIkkWEBOk2xDnb55FiNC0Heq/Inv VWmy1oZwUQ8p+mImuCKGaIkIlaRsd6LCX4L0TidZJKAS9i2x9DOW6dLmFBhSTRPmC4fq EvQRl69a0pqkuIm326i94lFC4VEphMG67JhsXYYSvgO2QMaQs+rFP8EFAHtbuf9vDiGp S2siJJ1zJz7lQ2g57vOaOubcrjxrceS+Y7FqPDGwvz0VljNxwYrDetjFBfDNr5pJnC0U i02orceGP+XqtZrdqPlusorNjgsnxnljjJTHTa5kte1jxzx9STKODePm9/y4J2/IOEA8 dwrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=9Qb3nQOmS4eBZNe2aGjgDsQO1OOhOOIU5vu95mwm6m0=; fh=SEg3ewIEHrV/LWzgkCVfC8f0j4vt9sWgHTe267emX7Y=; b=t+krTyCGrbAsbDovcwPg61uRWjVlRa5Z4uF4wCQ/8K82X1nWzwk/lQBA2pEZ1sGb8S wSPGPD1653CBshK1W2i013aNlrZV0WNG4jSAZ4mswqCYqSxxjLbuLyM4yes0rqT3+Ok1 I9wluYMxab0LkBqheDqq6PlwOE52Q+4dbeWRxh6bXbXv/e9KlEe4tmcjCt33ODoAK3pv c1/F62Xx9xa0dDViJ6Vp1i3bkUL3XbqS2N+BfyFg7ow1kPrjykSVuZds7f790esmFBA/ Z01Ohv5LB+SU/X9+FOdAlUaCNxdrQxPYnS5RZK2Tqvq0qSaTFKVsmAZhjkTActgJS6Ex ooOA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baylibre-com.20230601.gappssmtp.com header.s=20230601 header.b=oN5UaAHd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from pete.vger.email (pete.vger.email. [23.128.96.36]) by mx.google.com with ESMTPS id d17-20020a056a00199100b006bd360e70efsi4177889pfl.349.2023.10.16.06.54.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 06:54:55 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) client-ip=23.128.96.36; Authentication-Results: mx.google.com; dkim=pass header.i=@baylibre-com.20230601.gappssmtp.com header.s=20230601 header.b=oN5UaAHd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 2DFA180AF263; Mon, 16 Oct 2023 06:54:53 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233374AbjJPNya (ORCPT + 18 others); Mon, 16 Oct 2023 09:54:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232445AbjJPNy3 (ORCPT ); Mon, 16 Oct 2023 09:54:29 -0400 Received: from mail-oa1-x35.google.com (mail-oa1-x35.google.com [IPv6:2001:4860:4864:20::35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E651FA for ; Mon, 16 Oct 2023 06:54:26 -0700 (PDT) Received: by mail-oa1-x35.google.com with SMTP id 586e51a60fabf-1e19cb7829bso2867804fac.1 for ; Mon, 16 Oct 2023 06:54:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1697464466; x=1698069266; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=9Qb3nQOmS4eBZNe2aGjgDsQO1OOhOOIU5vu95mwm6m0=; b=oN5UaAHdYMEQR3FpmIEUj1EbL7N0U9fH4G20+5ydgpdeZHK+tMn9aCuX4vys0n+GWs p2gm+CSjGl5mixsLF74olRP20dxV0ri8Ib+sv4ttwKGW0LhWUwd1Mji4bPcI4oaYf6qN /9BwIvybCB2yljexNk975NnY4wxpLgTrg1L/DmdbKHiWBd7Lu0MGSK6dCYk/Y3JMd9ue IZLCVC8hIuri2OYjheVc4KC0D+Vr8JKw4IjqmbGXolRBvheJKIHmdCwvZgLtmTzj2uGx JxH5Bkbu7V2EIVHOAYF/QqYDHSrEq5At+duvwIpmeaFW0dx3wzGaLQaM/gYKf2MSpElv ZB/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697464466; x=1698069266; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=9Qb3nQOmS4eBZNe2aGjgDsQO1OOhOOIU5vu95mwm6m0=; b=bm/yHvtWrwaHCJrhnXGw7Fi5CB0nSnkduYqEV8QY+tmo2HLgpEfPxWrJlMlS60Ymqq AilnpCJWaaJrXUIj+dvacsHX7ufESphCHRSNTvb+szqd+J7MQbLUUnhEb9eg40H+Vj+1 1Qk5uAot9VPeE0bfl6qtuKmYgsRi0ZaXECWmUJkyyTsJoOQRc9UhyyNHdUarjGXRai/j wgcoRgzSWvHwoK2QTBHNWA6AcRPcMlx4qDj3pSv/69yJkVua0NvQMGfDUG9cx8W4IBMY BngBLqZUX7+/8Rx2fCmwacYf2Cb0QN0mil2s61KgkEBX0FcPMMdFzMiNmxu0N7Lpb5xl lYEw== X-Gm-Message-State: AOJu0Yx9wOxPE87D8fYvrytSjhgidQUUtNTMl9hInfINzRe90nJ156Ou sFqhHgSESazo7cFf8a4Fi7J/NQ== X-Received: by 2002:a05:6870:582:b0:1dc:723d:b8d0 with SMTP id m2-20020a056870058200b001dc723db8d0mr41487601oap.27.1697464465724; Mon, 16 Oct 2023 06:54:25 -0700 (PDT) Received: from freyr.lechnology.com (ip98-183-112-25.ok.ok.cox.net. [98.183.112.25]) by smtp.gmail.com with ESMTPSA id zh38-20020a0568716ba600b001e9888ab4e7sm2014399oab.5.2023.10.16.06.54.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Oct 2023 06:54:25 -0700 (PDT) From: David Lechner To: linux-iio@vger.kernel.org Cc: David Lechner , Jonathan Cameron , Michael Hennerich , nuno.sa@analog.com, linux-kernel@vger.kernel.org Subject: [PATCH v2] iio: resolver: ad2s1210: add support for adi,fixed-mode Date: Mon, 16 Oct 2023 08:54:22 -0500 Message-ID: <20231016135423.16808-1-dlechner@baylibre.com> X-Mailer: git-send-email 2.42.0 MIME-Version: 1.0 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Mon, 16 Oct 2023 06:54:53 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1779920530441424439 X-GMAIL-MSGID: 1779920530441424439 It is possible to use the AD2S1210 with hardwired mode pins (A0 and A1). According to the devicetree bindings, in this case the adi,fixed-mode property will specify which of the 3 possible modes the mode pins are hardwired for and the gpio-modes property is not allowed. This adds support for the case where the mode pins are hardwired for config mode. In this configuration, the position and value must be read from the config register. The case of hardwired position or velocity mode is not supported as there would be no way to configure the device. Signed-off-by: David Lechner Reviewed-by: Nuno Sa --- v2 changes: * Use regmap_bulk_read() instead of new local function. * Simplify adi,fixed-mode property error checking. drivers/iio/resolver/ad2s1210.c | 150 +++++++++++++++++++++++++------- 1 file changed, 119 insertions(+), 31 deletions(-) diff --git a/drivers/iio/resolver/ad2s1210.c b/drivers/iio/resolver/ad2s1210.c index 1bd1b950e7cc..7f688bfe2172 100644 --- a/drivers/iio/resolver/ad2s1210.c +++ b/drivers/iio/resolver/ad2s1210.c @@ -141,7 +141,7 @@ struct ad2s1210_state { struct spi_device *sdev; /** GPIO pin connected to SAMPLE line. */ struct gpio_desc *sample_gpio; - /** GPIO pins connected to A0 and A1 lines. */ + /** GPIO pins connected to A0 and A1 lines (optional). */ struct gpio_descs *mode_gpios; /** Used to access config registers. */ struct regmap *regmap; @@ -149,6 +149,8 @@ struct ad2s1210_state { unsigned long clkin_hz; /** Available raw hysteresis values based on resolution. */ int hysteresis_available[2]; + /* adi,fixed-mode property - only valid when mode_gpios == NULL. */ + enum ad2s1210_mode fixed_mode; /** The selected resolution */ enum ad2s1210_resolution resolution; /** Copy of fault register from the previous read. */ @@ -175,6 +177,9 @@ static int ad2s1210_set_mode(struct ad2s1210_state *st, enum ad2s1210_mode mode) struct gpio_descs *gpios = st->mode_gpios; DECLARE_BITMAP(bitmap, 2); + if (!gpios) + return mode == st->fixed_mode ? 0 : -EOPNOTSUPP; + bitmap[0] = mode; return gpiod_set_array_value(gpios->ndescs, gpios->desc, gpios->info, @@ -276,7 +281,8 @@ static int ad2s1210_regmap_reg_read(void *context, unsigned int reg, * parity error. The fault register is read-only and the D7 bit means * something else there. */ - if (reg != AD2S1210_REG_FAULT && st->rx[1] & AD2S1210_ADDRESS_DATA) + if ((reg > AD2S1210_REG_VELOCITY_LSB && reg != AD2S1210_REG_FAULT) + && st->rx[1] & AD2S1210_ADDRESS_DATA) return -EBADMSG; *val = st->rx[1]; @@ -450,21 +456,53 @@ static int ad2s1210_single_conversion(struct iio_dev *indio_dev, ad2s1210_toggle_sample_line(st); timestamp = iio_get_time_ns(indio_dev); - switch (chan->type) { - case IIO_ANGL: - ret = ad2s1210_set_mode(st, MOD_POS); - break; - case IIO_ANGL_VEL: - ret = ad2s1210_set_mode(st, MOD_VEL); - break; - default: - return -EINVAL; + if (st->fixed_mode == MOD_CONFIG) { + unsigned int reg_val; + + switch (chan->type) { + case IIO_ANGL: + ret = regmap_bulk_read(st->regmap, + AD2S1210_REG_POSITION_MSB, + &st->sample.raw, 2); + if (ret < 0) + return ret; + + break; + case IIO_ANGL_VEL: + ret = regmap_bulk_read(st->regmap, + AD2S1210_REG_VELOCITY_MSB, + &st->sample.raw, 2); + if (ret < 0) + return ret; + + break; + default: + return -EINVAL; + } + + ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, ®_val); + if (ret < 0) + return ret; + + st->sample.fault = reg_val; + } else { + switch (chan->type) { + case IIO_ANGL: + ret = ad2s1210_set_mode(st, MOD_POS); + break; + case IIO_ANGL_VEL: + ret = ad2s1210_set_mode(st, MOD_VEL); + break; + default: + return -EINVAL; + } + if (ret < 0) + return ret; + + ret = spi_read(st->sdev, &st->sample, 3); + if (ret < 0) + return ret; } - if (ret < 0) - return ret; - ret = spi_read(st->sdev, &st->sample, 3); - if (ret < 0) - return ret; switch (chan->type) { case IIO_ANGL: @@ -1252,27 +1290,53 @@ static irqreturn_t ad2s1210_trigger_handler(int irq, void *p) ad2s1210_toggle_sample_line(st); if (test_bit(0, indio_dev->active_scan_mask)) { - ret = ad2s1210_set_mode(st, MOD_POS); - if (ret < 0) - goto error_ret; - - ret = spi_read(st->sdev, &st->sample, 3); - if (ret < 0) - goto error_ret; + if (st->fixed_mode == MOD_CONFIG) { + ret = regmap_bulk_read(st->regmap, + AD2S1210_REG_POSITION_MSB, + &st->sample.raw, 2); + if (ret < 0) + goto error_ret; + } else { + ret = ad2s1210_set_mode(st, MOD_POS); + if (ret < 0) + goto error_ret; + + ret = spi_read(st->sdev, &st->sample, 3); + if (ret < 0) + goto error_ret; + } memcpy(&st->scan.chan[chan++], &st->sample.raw, 2); } if (test_bit(1, indio_dev->active_scan_mask)) { - ret = ad2s1210_set_mode(st, MOD_VEL); - if (ret < 0) - goto error_ret; + if (st->fixed_mode == MOD_CONFIG) { + ret = regmap_bulk_read(st->regmap, + AD2S1210_REG_VELOCITY_MSB, + &st->sample.raw, 2); + if (ret < 0) + goto error_ret; + } else { + ret = ad2s1210_set_mode(st, MOD_VEL); + if (ret < 0) + goto error_ret; + + ret = spi_read(st->sdev, &st->sample, 3); + if (ret < 0) + goto error_ret; + } - ret = spi_read(st->sdev, &st->sample, 3); + memcpy(&st->scan.chan[chan++], &st->sample.raw, 2); + } + + if (st->fixed_mode == MOD_CONFIG) { + unsigned int reg_val; + + ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, ®_val); if (ret < 0) - goto error_ret; + return ret; - memcpy(&st->scan.chan[chan++], &st->sample.raw, 2); + st->sample.fault = reg_val; } ad2s1210_push_events(indio_dev, st->sample.fault, pf->timestamp); @@ -1299,9 +1363,24 @@ static const struct iio_info ad2s1210_info = { static int ad2s1210_setup_properties(struct ad2s1210_state *st) { struct device *dev = &st->sdev->dev; + const char *str_val; u32 val; int ret; + ret = device_property_read_string(dev, "adi,fixed-mode", &str_val); + if (ret == -EINVAL) + st->fixed_mode = -1; + else if (ret < 0) + return dev_err_probe(dev, ret, + "failed to read adi,fixed-mode property\n"); + else { + if (strcmp(str_val, "config")) + return dev_err_probe(dev, -EINVAL, + "only adi,fixed-mode=\"config\" is supported\n"); + + st->fixed_mode = MOD_CONFIG; + } + ret = device_property_read_u32(dev, "assigned-resolution-bits", &val); if (ret < 0) return dev_err_probe(dev, ret, @@ -1357,12 +1436,21 @@ static int ad2s1210_setup_gpios(struct ad2s1210_state *st) "failed to request sample GPIO\n"); /* both pins high means that we start in config mode */ - st->mode_gpios = devm_gpiod_get_array(dev, "mode", GPIOD_OUT_HIGH); + st->mode_gpios = devm_gpiod_get_array_optional(dev, "mode", + GPIOD_OUT_HIGH); if (IS_ERR(st->mode_gpios)) return dev_err_probe(dev, PTR_ERR(st->mode_gpios), "failed to request mode GPIOs\n"); - if (st->mode_gpios->ndescs != 2) + if (!st->mode_gpios && st->fixed_mode == -1) + return dev_err_probe(dev, -EINVAL, + "must specify either adi,fixed-mode or mode-gpios\n"); + + if (st->mode_gpios && st->fixed_mode != -1) + return dev_err_probe(dev, -EINVAL, + "must specify only one of adi,fixed-mode or mode-gpios\n"); + + if (st->mode_gpios && st->mode_gpios->ndescs != 2) return dev_err_probe(dev, -EINVAL, "requires exactly 2 mode-gpios\n");