From nobody Fri Jul 24 21:30:26 2026 Received: from mail-oa1-f44.google.com (mail-oa1-f44.google.com [209.85.160.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EB40746AF10 for ; Fri, 24 Jul 2026 20:13:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784924032; cv=none; b=rgyk9sPKfhVC59CWoiE0P3yjWQsRhS94UuDrf4tzP7HK1+xSdJ6JCKe+K2NuVIBzHjbZbJ94BOrqkz6z9ZuxBtaH0+2VC6eqvoRjcX3u1gDpYcK/Sm+Uj6ElCfHjmGAJnldoRuK9MUNJ0J50lNiNcgR+9XlLoNGB3Xxjhm5hxYs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784924032; c=relaxed/simple; bh=VwRp5cVL30GJlj3wO3D26AsHQN19yEwSh6UVq6RANXA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pSW1DlXDoRhJ19heoyIao0DTPJzP0H4E0JkutYdQXrzj5sh2Xd9Kn8x8gs2uWtKQ/GezPPtpZjyI2rwoiOyOmHY8ZHMDuWD2hS6mPHmaqeGGiqF0f8kRLeK+vp8t5AxGTPrlHluN3gqqdSOISM+/qKeiz9PJ/Zv9H/aUGMbLcmM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b=nxfpRzCd; arc=none smtp.client-ip=209.85.160.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b="nxfpRzCd" Received: by mail-oa1-f44.google.com with SMTP id 586e51a60fabf-43bf9548df4so462847fac.0 for ; Fri, 24 Jul 2026 13:13:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1784924017; x=1785528817; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=e10cpwXyP0kwYSe5mqmMQqJO1Y4QT7IxpGgJ8dCsjI8=; b=nxfpRzCdiPKRZetDbwiTnyRGhYzDbAA0MqzYzbBCRRgP7Ns2bXTp02Mm18QG0AVYe4 82xsPRz+mXPrvXhqlDQBHWDrcSWoAsifs06Mf9VI78Eyi/JqbbEIaEDm/WuJLIsqRiVn YL4mRYfgA1183P3yD3JC52Jyy+4YvgA/rUnmvg/To8rsBT2g0J4z1r/Gmde+8lNoxgzD njZq7AMCd//DPdhE2oS0L7CXl4B4TzcyVPIkCNQbf7U/9DeaSIsGWrmp1MpATCVSkJaO sFzONEUjIsDmB/tqEGYxqEOHY0Iy6qo/W4Ft7q4p3IQlDBTZPb4hXzV2jULwvNG4LWjh VgnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784924017; x=1785528817; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=e10cpwXyP0kwYSe5mqmMQqJO1Y4QT7IxpGgJ8dCsjI8=; b=RMO1bkDtq59YACypCc4JtC+8XiMdQNyFtA2eZIxebKMwM1oxPeI35y17PECthmAiaw LUu6zCWHOM8s8WaNpLdwaUJ6C3BB2gG/0nZ+9fBzylyRipoeCXWcLhxb7LhR1styDwQ8 prxSVWszgEVvJozpubIEwS7ZC05jS8gEaokuyNMvZ9D5JPGmdoeDU6tcCXbxRJP3v7Dc +ZWaZRn7K6/sw3flKbCE9xtcvKqxOilYrhcz2uAW8DkI2JzFr1YWU2ScGerBb/OsN4zk muqkI9l8BgYkSaGG0EfLqg+wZPEQr+bAkEohMDh6ul6gWNN0Gl/W5kSJiyqPDrfMJrne TGrQ== X-Forwarded-Encrypted: i=1; AHgh+RpmN3dnbmZHjtPqoWZuibeLUfm442mLGkYsfn0auBisFkvZaQYHF/uT3hvhC5/m3SLwpYw1NGmkns1kQVs=@vger.kernel.org X-Gm-Message-State: AOJu0YzmxpH/Re1p7EhX4HnnvNqp2npmd2za/h5Bvz8ag0xfO8efvbmp /baCliMWoZpRACAKGrp4olkc0ttZbKTF+rKKXgwvRK6QBCzf+JK9QFdP1KrjaSC8jnc= X-Gm-Gg: AR+sD126sm0ZiKAS6GQ+CP2pkFoqZQ5q2RjaffpdoTlCQZODt1nyhRWCAu1q+e+W7h6 jDXBlaSkwqaFu6wgzmWlDqtDbDRIBmfYQ+J2XaVULHe2g9rfWnfGx+8Yb8OYS4DzfmGRfNN6Nm7 +kngLiNAGNyB6nztT6wENrx5WIRGUV6R3V10MkyVnAA42udS6P86Rue8i5Xp95s7tO9xSZe7VlE L9ynwA8GqmJJZr0fLTzla/S0SQg17hjK+QSESmfdBpO0k3zNCUgCs6ExKhp3xqb9dfB6nLCah1i oYhLVbbi4eT2U/II0sgcIn3NplAl4Ohb4QsJJGh9oeRMasMv/AiFNvd6tK8YuIR6yrfWpXvmFIR yHNJTGlyqBIL2acK5WfXMsWaJ+oIVfCV9r4x1payU1j+/i8E6RNlZMURt9VnMDssBy0dmm4cAT2 2F1Mbf6ocH68T7PBL5 X-Received: by 2002:a05:6871:3586:b0:434:5c90:9d87 with SMTP id 586e51a60fabf-457a0c7f856mr5713452fac.12.1784924017196; Fri, 24 Jul 2026 13:13:37 -0700 (PDT) Received: from [127.0.1.1] ([2600:8803:e7e4:500:b635:d463:c98:cc75]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-457675260b4sm8309042fac.17.2026.07.24.13.13.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Jul 2026 13:13:36 -0700 (PDT) From: "David Lechner (TI)" Date: Fri, 24 Jul 2026 15:13:10 -0500 Subject: [PATCH 1/2] iio: adc: ti-ads112c14: add DRDY interrupt support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260724-iio-adc-ti-ads112c14-continuous-mode-v1-1-9eb0b7a4f020@baylibre.com> References: <20260724-iio-adc-ti-ads112c14-continuous-mode-v1-0-9eb0b7a4f020@baylibre.com> In-Reply-To: <20260724-iio-adc-ti-ads112c14-continuous-mode-v1-0-9eb0b7a4f020@baylibre.com> To: Jonathan Cameron , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko Cc: Chris Hall , Patrick Edwards , Kurt Borja , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, "David Lechner (TI)" X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=5321; i=dlechner@baylibre.com; h=from:subject:message-id; bh=VwRp5cVL30GJlj3wO3D26AsHQN19yEwSh6UVq6RANXA=; b=owEBbQGS/pANAwAKAcLMIAH/AY/AAcsmYgBqY8dhVqrZO9pH3olcBwoVGpz/yeEXJwvJXx6Oz O2PILXByteJATMEAAEKAB0WIQTsGNmeYg6D1pzYaJjCzCAB/wGPwAUCamPHYQAKCRDCzCAB/wGP wOe/B/4rioD7rZDQIGcwcfJwTigRl1QItuNyThoe/OrIPOBePUKvjznf/j5+wl9NmWSvMKm3Qlg 8qyfghUJVpI9Sc/51ArHntPxqr0hnicAfR4t5UKvn/WOtQuAGlglLUa/YmQGzBFdDOAj61QAwSq CbJ4gJjzICotVpkYex9UJby3dwO/Y/sgCG5lKFUIESEZkDPBkZ6E9VZc7E3+Lr3OO/bECTsBsPf 5xnvdof8dPlzOa26eeGBD3keP8AjPs4oVjmVm2C+dkYxlAi7GdzkTHHbsSAvdXvlwz9NKQPLPsG Z45l19c8Mrawi2/iH+s8M1DeGBKADw5EZuoxYv0TEvr2CQD+ X-Developer-Key: i=dlechner@baylibre.com; a=openpgp; fpr=8A73D82A6A1F509907F373881F8AF88C82F77C03 Add handling for the DRDY interrupt to wait for data ready events rather than polling (only when it is wired up). Signed-off-by: David Lechner (TI) --- Small note: the hard-coded 100 ms timeout will be replaced in a future series with a dynamic value, so I didn't bother with a macro or comments to explain why the value was chosen. And passing indio_dev instead of data to irq is intentional as it will be used in the next patch. --- drivers/iio/adc/ti-ads112c14.c | 82 ++++++++++++++++++++++++++++++++++++++= ---- 1 file changed, 75 insertions(+), 7 deletions(-) diff --git a/drivers/iio/adc/ti-ads112c14.c b/drivers/iio/adc/ti-ads112c14.c index 8ad8caee0ff7..57e301c15314 100644 --- a/drivers/iio/adc/ti-ads112c14.c +++ b/drivers/iio/adc/ti-ads112c14.c @@ -10,6 +10,7 @@ =20 #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -117,9 +119,15 @@ #define ADS112C14_GPIO_CFG_GPIO2_CFG GENMASK(5, 4) #define ADS112C14_GPIO_CFG_GPIO1_CFG GENMASK(3, 2) #define ADS112C14_GPIO_CFG_GPIO0_CFG GENMASK(1, 0) +#define ADS112C14_GPIO_CFG_GPIO_CFG_DISABLED 0 +#define ADS112C14_GPIO_CFG_GPIO_CFG_INPUT 1 +#define ADS112C14_GPIO_CFG_GPIO_CFG_OUTPUT_PUSH_PULL 2 +#define ADS112C14_GPIO_CFG_GPIO_CFG_OUTPUT_OPEN_DRAIN 3 =20 #define ADS112C14_REG_GPIO_DATA_OUTPUT 0x0C #define ADS112C14_GPIO_DATA_OUTPUT_GPIO3_SRC BIT(7) +#define ADS112C14_GPIO_DATA_OUTPUT_GPIO3_SRC_DAT_OUT 0 +#define ADS112C14_GPIO_DATA_OUTPUT_GPIO3_SRC_DRDY 1 #define ADS112C14_GPIO_DATA_OUTPUT_GPIO2_SRC BIT(6) #define ADS112C14_GPIO_DATA_OUTPUT_GPIO3_DAT_OUT BIT(3) #define ADS112C14_GPIO_DATA_OUTPUT_GPIO2_DAT_OUT BIT(2) @@ -251,6 +259,8 @@ struct ads112c14_data { struct regmap *regmap; /* Synchronizes access to register value fields. */ struct mutex lock; + int drdy_irq; + struct completion drdy_completion; bool i2c_crc_enabled; u32 avdd_uV; u32 ext_ref_uV; @@ -265,6 +275,16 @@ struct ads112c14_data { ARRAY_SIZE(ads112c14_sys_mon_channels)); }; =20 +static irqreturn_t ads112c14_drdy_irq_handler(int irq, void *private) +{ + struct iio_dev *indio_dev =3D private; + struct ads112c14_data *data =3D iio_priv(indio_dev); + + complete(&data->drdy_completion); + + return IRQ_HANDLED; +} + static bool ads112c14_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -601,17 +621,33 @@ static int ads112c14_single_conversion(struct ads112c= 14_data *data, return ret; } =20 + if (data->drdy_irq) { + reinit_completion(&data->drdy_completion); + enable_irq(data->drdy_irq); + } + ret =3D regmap_write(data->regmap, ADS112C14_REG_CONVERSION_CTRL, ADS112C14_CONVERSION_CTRL_START); - if (ret) + if (ret) { + if (data->drdy_irq) + disable_irq(data->drdy_irq); return ret; + } =20 - ret =3D regmap_read_poll_timeout(data->regmap, - ADS112C14_REG_STATUS_MSB, reg_val, - FIELD_GET(ADS112C14_STATUS_MSB_DRDY, reg_val), - 1 * USEC_PER_MSEC, 100 * USEC_PER_MSEC); - if (ret) - return ret; + if (data->drdy_irq) { + ret =3D wait_for_completion_timeout(&data->drdy_completion, + msecs_to_jiffies(100)); + disable_irq(data->drdy_irq); + if (ret =3D=3D 0) + return -ETIMEDOUT; + } else { + ret =3D regmap_read_poll_timeout(data->regmap, + ADS112C14_REG_STATUS_MSB, reg_val, + FIELD_GET(ADS112C14_STATUS_MSB_DRDY, reg_val), + 1 * USEC_PER_MSEC, 100 * USEC_PER_MSEC); + if (ret) + return ret; + } =20 /* * When doing buffered read, we don't check the CRC, but rather pass it @@ -1392,6 +1428,38 @@ static int ads112c14_probe(struct i2c_client *client) if (ret) return ret; =20 + if (device_property_present(dev, "interrupts")) { + data->drdy_irq =3D fwnode_irq_get_byname(dev_fwnode(dev), "drdy"); + if (data->drdy_irq < 0) + return dev_err_probe(dev, data->drdy_irq, + "failed to get drdy interrupt\n"); + + /* + * REVISIT: would probably need to implement a pin controller in + * order to support open drain option here. + */ + ret =3D regmap_update_bits(data->regmap, ADS112C14_REG_GPIO_CFG, + ADS112C14_GPIO_CFG_GPIO3_CFG, + FIELD_PREP(ADS112C14_GPIO_CFG_GPIO3_CFG, + ADS112C14_GPIO_CFG_GPIO_CFG_OUTPUT_PUSH_PULL)); + if (ret) + return ret; + + ret =3D regmap_update_bits(data->regmap, ADS112C14_REG_GPIO_DATA_OUTPUT, + ADS112C14_GPIO_DATA_OUTPUT_GPIO3_SRC, + FIELD_PREP(ADS112C14_GPIO_DATA_OUTPUT_GPIO3_SRC, + ADS112C14_GPIO_DATA_OUTPUT_GPIO3_SRC_DRDY)); + if (ret) + return ret; + + init_completion(&data->drdy_completion); + + ret =3D devm_request_irq(dev, data->drdy_irq, ads112c14_drdy_irq_handler, + IRQF_NO_AUTOEN, dev_name(dev), indio_dev); + if (ret) + return ret; + } + ads112c14_populate_tables(data); =20 indio_dev->name =3D info->name; --=20 2.43.0 From nobody Fri Jul 24 21:30:26 2026 Received: from mail-oo1-f46.google.com (mail-oo1-f46.google.com [209.85.161.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF7971DA62E for ; Fri, 24 Jul 2026 20:13:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784924036; cv=none; b=tAqX97lFuf6Al4WSpFQ4llqJedt8wOSoh1fHiFj4rntUnlBfetg3zM3sQAs+vr34TJ/KF/b6R/g3lh9Q/WHAsEE16afCtevD+0N+vhLD59JLasn0Z/FJTq3Q9eoLMw1mNMWJAN7WGNe2vpBywo3H3BLhyCv15w0D2yMVrQ2znmE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784924036; c=relaxed/simple; bh=BPt109iAWgDJXAvgjMvwx0rWb03VUfrCvuRuh/1KsDI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=WhFiNR+nMPaEHKgPS4sttNYj+dDAUDkhjrcqIVxUuDtaZ5K4W5kJlxJkg8naQauN+ChQqf3U9OM833Gj5QTUej42tcNd0rYAomJTddEqx7MixaIEn8bholZtjbq5UMMW4wl0ugDwInb5DAzXs8Qc8tnBt2TGc0jVSIbBLMh5O38= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b=QhV2izri; arc=none smtp.client-ip=209.85.161.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre.com header.i=@baylibre.com header.b="QhV2izri" Received: by mail-oo1-f46.google.com with SMTP id 006d021491bc7-6a38e41d0b5so1112837eaf.1 for ; Fri, 24 Jul 2026 13:13:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre.com; s=google; t=1784924018; x=1785528818; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=x8jCGxO7GFnygrqE3Gh6IjanpH8BBhZPbSBH/qmP5TU=; b=QhV2izriklnO2RVYJwqFAlg5JXXslN/Y1pMC7cG6u6SR4bOqHBV90AFQMhBXUaef7+ RdCWIetq44KaG5WP88zICdRQsnwOA8m2ll4+8OX5B4bwLvQnznB2vOtKsEWecugu49d5 GZqsorpp9rAMS6DZh75Nyms2l4NY1I02AP+kOBdqYxM0LsZrwuc15DiNtHr+gTg8im5V DUv/Ywb24q/U2CLIGgWl6YSQDf26tCAQYwD7Ca8lJnYSbSJT4+Bs9k5EYEQRB82WDsiS obGnTEw69U4tumECxSixCRJUgYGCZ7cwbRBmhWI2RWLe51lR57wyRQrr33F57q8vOM1o I0hA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784924018; x=1785528818; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=x8jCGxO7GFnygrqE3Gh6IjanpH8BBhZPbSBH/qmP5TU=; b=qURr4iZxVwvLDas02vNJIlJATl7oTMvTnws3voTXvdPkTyCJ5IZRr3F/U2jNk0p77H 6vUu8DP3pMnp7CQ01ijwE+nyox4BO+fq6pnlCHUu6/BIUA9cdIuGBzp6Tpo938bJpuCs n4nh3+rIPfXFnP/jrOgIku0850sXG3zqNaX9QcrD/ExvfFv2J7ArxUJdfE9uK/bM7IrV 8IChX/yCHIoGLTpTUbPHTpKFUbKqpDeONrKlsJ6V4ilo77QTwe+QeqthalpIAP05cB6+ mt32dbVN/NLmXIM949pC9mc9sZdS/MQh3HwGyKaIr2lOCHxgj/B5GtZlPjg4D1CydURm HQ1w== X-Forwarded-Encrypted: i=1; AHgh+Rp6o7mf7bbK0PfaA1sF0dRrwZrwVPBLxjDtPNO5xeEVRTVSH5CSsfBZ7+ZZ5s4z2NJtzaVz1w4tdCKnI2U=@vger.kernel.org X-Gm-Message-State: AOJu0YyAg8KhUo3k/Rkwsq0VevSxVIC/mfAHsIO3TAaYHvWzOBQ7vQ87 nA8ItmqJZYvGxb4nti8/nlM6plUIw71zYSOMimzPslJtFBB8igaARP7ZNQ1CMBEAHJo= X-Gm-Gg: AR+sD10ljcBBsGgLThuxzae806MKkHNNtMMO3FGvUYat8kAAazl6W1Sdkr+d+feOcYi ken3o4AVKymv0P8dfxol/V6pggy5DFZfoUUK48Yg6NxIUZgClXXj2OnwTpZpc0wweIu4Hejp67o iwrSDYVOcS8e50AexJUDRzsSDCiP8CyHOf5+X9pnGp7kYj07CVQ2TEuMAZQ/rk6JDPmoUtWYVay +gyUNNDgMe1w6254bdQ1AFC8WNNKE62Nm0lLH98mbegWzlcf1mOsFEmfcQnj/QtoFsfMS7P6Yqw FtYccZXvW8KY2LePDfOd5dnWVymrzroOk232/JS+XVCd+nkJIOC1dkCEdF7DyZXnKZCSwQjMQ6M 9VksVZd0IYNQpvisatrPYXroqHKNEfecdaAW4zBcPJMMGkHRb2emQPYK/4nXZLD8UtiACkRnSPO bk6/xh4A== X-Received: by 2002:a05:6820:4c86:b0:6a3:7816:cbe2 with SMTP id 006d021491bc7-6aaf4658c68mr1808677eaf.35.1784924018163; Fri, 24 Jul 2026 13:13:38 -0700 (PDT) Received: from [127.0.1.1] ([2600:8803:e7e4:500:b635:d463:c98:cc75]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-457675260b4sm8309042fac.17.2026.07.24.13.13.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Jul 2026 13:13:37 -0700 (PDT) From: "David Lechner (TI)" Date: Fri, 24 Jul 2026 15:13:11 -0500 Subject: [PATCH 2/2] iio: adc: ti-ads112c14: add continuous mode support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260724-iio-adc-ti-ads112c14-continuous-mode-v1-2-9eb0b7a4f020@baylibre.com> References: <20260724-iio-adc-ti-ads112c14-continuous-mode-v1-0-9eb0b7a4f020@baylibre.com> In-Reply-To: <20260724-iio-adc-ti-ads112c14-continuous-mode-v1-0-9eb0b7a4f020@baylibre.com> To: Jonathan Cameron , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko Cc: Chris Hall , Patrick Edwards , Kurt Borja , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, "David Lechner (TI)" X-Mailer: b4 0.16-dev X-Developer-Signature: v=1; a=openpgp-sha256; l=9335; i=dlechner@baylibre.com; h=from:subject:message-id; bh=BPt109iAWgDJXAvgjMvwx0rWb03VUfrCvuRuh/1KsDI=; b=owEBbQGS/pANAwAKAcLMIAH/AY/AAcsmYgBqY8doJil6Sdh+THaPJd6VWxh3gK+mJCHEghJoo touFy0p0VaJATMEAAEKAB0WIQTsGNmeYg6D1pzYaJjCzCAB/wGPwAUCamPHaAAKCRDCzCAB/wGP wLTqCAChF72KTMz8OrRdfjQ2ek/HQz7QQTw5/p/HWkOT2Xit/SA2sp/bBzRBF8g0T/kRYIUWXbZ i3198lSrvUgofGTWo5UYoNVbPIGgin6tv3iri6qyi6kdMt2WG1iJyR0yG+kn07/4s/zhC6oHdHl fiTlBA4MMsXWaVwbYYSrk1apaumr7g6uB7Iyqztj/aqWhiAFNxWMuXCdMyPxl2mVJBRIi38s9RS pYOhytO8BnhiV4PAkSSYMJk7qylh449XWQpGImoqBFCI8+elAlOyWwOTehbzc1RQxyDkxaQgLsO xyxki9IrtT3kP2OmEr9+mIHJdV5H3mZk1j8GuUhdM7BfD59q X-Developer-Key: i=dlechner@baylibre.com; a=openpgp; fpr=8A73D82A6A1F509907F373881F8AF88C82F77C03 Add support for continuous mode in the TI ADS112C14 ADC driver. In this mode the ADC itself is starting each conversion, so we add a trigger based on the DRDY interrupt to read each sample. This mode is also limited in that only one channel can be enabled at a time since the chip does not have a sequencer or simultaneous sampling capability. Continuous mode will only be used when this new trigger is the current trigger. Signed-off-by: David Lechner (TI) --- drivers/iio/adc/ti-ads112c14.c | 200 ++++++++++++++++++++++++++++++++++++-= ---- 1 file changed, 178 insertions(+), 22 deletions(-) diff --git a/drivers/iio/adc/ti-ads112c14.c b/drivers/iio/adc/ti-ads112c14.c index 57e301c15314..f3a2eba55362 100644 --- a/drivers/iio/adc/ti-ads112c14.c +++ b/drivers/iio/adc/ti-ads112c14.c @@ -9,6 +9,7 @@ */ =20 #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -257,6 +259,7 @@ struct ads112c14_measurement { struct ads112c14_data { const struct ads112c14_chip_info *chip_info; struct regmap *regmap; + struct iio_trigger *drdy_trig; /* Synchronizes access to register value fields. */ struct mutex lock; int drdy_irq; @@ -280,11 +283,32 @@ static irqreturn_t ads112c14_drdy_irq_handler(int irq= , void *private) struct iio_dev *indio_dev =3D private; struct ads112c14_data *data =3D iio_priv(indio_dev); =20 - complete(&data->drdy_completion); + if (iio_trigger_using_own(indio_dev)) + iio_trigger_poll(data->drdy_trig); + else + complete(&data->drdy_completion); =20 return IRQ_HANDLED; } =20 +static int ads112c14_trigger_set_state(struct iio_trigger *trig, bool stat= e) +{ + struct iio_dev *indio_dev =3D iio_trigger_get_drvdata(trig); + struct ads112c14_data *data =3D iio_priv(indio_dev); + + if (state) + enable_irq(data->drdy_irq); + else + disable_irq(data->drdy_irq); + + return 0; +} + +static const struct iio_trigger_ops ads112c14_trigger_ops =3D { + .set_trigger_state =3D ads112c14_trigger_set_state, + .validate_device =3D iio_trigger_validate_own_device, +}; + static bool ads112c14_writeable_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -601,6 +625,32 @@ static int ads112c14_prepare_sys_mon_channel(struct ad= s112c14_data *data, return 0; } =20 +static int ads112c14_prepare_channel(struct ads112c14_data *data, + const struct iio_chan_spec *chan) +{ + if (chan->channel < ADS112C14_SYS_MON_CHANNEL_BASE) + return ads112c14_prepare_measurement_channel(data, chan); + + return ads112c14_prepare_sys_mon_channel(data, chan); +} + +static int ads112c14_scan_read(struct ads112c14_data *data, u8 *buf) +{ + struct i2c_client *client =3D to_i2c_client(regmap_get_device(data->regma= p)); + int ret; + u8 len; + + len =3D BITS_TO_BYTES(data->chip_info->resolution_bits); + if (data->i2c_crc_enabled) + len +=3D 1; + + ret =3D i2c_smbus_read_i2c_block_data(client, ADS112C14_CMD_RDATA, len, b= uf); + if (ret < 0) + return ret; + + return 0; +} + static int ads112c14_single_conversion(struct ads112c14_data *data, const struct iio_chan_spec *chan, u8 *buf, bool for_scan) @@ -611,15 +661,9 @@ static int ads112c14_single_conversion(struct ads112c1= 4_data *data, =20 guard(mutex)(&data->lock); =20 - if (chan->channel < ADS112C14_SYS_MON_CHANNEL_BASE) { - ret =3D ads112c14_prepare_measurement_channel(data, chan); - if (ret) - return ret; - } else { - ret =3D ads112c14_prepare_sys_mon_channel(data, chan); - if (ret) - return ret; - } + ret =3D ads112c14_prepare_channel(data, chan); + if (ret) + return ret; =20 if (data->drdy_irq) { reinit_completion(&data->drdy_completion); @@ -655,17 +699,8 @@ static int ads112c14_single_conversion(struct ads112c1= 4_data *data, * with CRC errors, but rather leave it to userspace to decide what to * do. */ - if (for_scan) { - u8 len =3D BITS_TO_BYTES(data->chip_info->resolution_bits) + - (data->i2c_crc_enabled ? 1 : 0); - - ret =3D i2c_smbus_read_i2c_block_data(client, ADS112C14_CMD_RDATA, - len, buf); - if (ret < 0) - return ret; - - return 0; - } + if (for_scan) + return ads112c14_scan_read(data, buf); =20 return ads112c14_i2c_read_bytes(client, ADS112C14_CMD_RDATA, buf, BITS_TO_BYTES(data->chip_info->resolution_bits), @@ -934,10 +969,31 @@ static irqreturn_t ads112c14_trigger_handler(int irq,= void *private) struct iio_poll_func *pf =3D private; struct iio_dev *indio_dev =3D pf->indio_dev; struct ads112c14_data *data =3D iio_priv(indio_dev); + unsigned int scan_mask_len =3D iio_get_masklength(indio_dev); u32 offset =3D 0; u32 i; int ret; =20 + if (iio_trigger_using_own(indio_dev)) { + i =3D find_first_bit(indio_dev->active_scan_mask, scan_mask_len); + if (i >=3D scan_mask_len) + goto out; + + ret =3D ads112c14_scan_read(data, (u8 *)&data->scan[0]); + if (ret) { + const struct iio_chan_spec *chan =3D &indio_dev->channels[i]; + + dev_err_once(indio_dev->dev.parent, + "failed to read channel %d: %pe; additional errors will be suppre= ssed\n", + chan->channel, ERR_PTR(ret)); + goto out; + } + + iio_push_to_buffers_with_ts(indio_dev, data->scan, + sizeof(data->scan), pf->timestamp); + goto out; + } + iio_for_each_active_channel(indio_dev, i) { const struct iio_chan_spec *chan =3D &indio_dev->channels[i]; =20 @@ -969,6 +1025,90 @@ static const struct iio_info ads112c14_info =3D { .read_label =3D ads112c14_read_label, }; =20 +static bool ads112c14_using_drdy_trigger(struct iio_dev *indio_dev) +{ + struct ads112c14_data *data =3D iio_priv(indio_dev); + + return data->drdy_trig && indio_dev->trig =3D=3D data->drdy_trig; +} + +static bool ads112c14_validate_scan_mask(struct iio_dev *indio_dev, + const unsigned long *mask) +{ + if (!ads112c14_using_drdy_trigger(indio_dev)) + return true; + + return bitmap_weight(mask, iio_get_masklength(indio_dev)) =3D=3D 1; +} + +static int ads112c14_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ads112c14_data *data =3D iio_priv(indio_dev); + unsigned int scan_mask_len =3D iio_get_masklength(indio_dev); + unsigned int i; + const struct iio_chan_spec *chan; + int ret; + + if (!ads112c14_using_drdy_trigger(indio_dev)) + return 0; + + i =3D find_first_bit(indio_dev->active_scan_mask, scan_mask_len); + if (i >=3D scan_mask_len) + return -EINVAL; + + chan =3D &indio_dev->channels[i]; + + guard(mutex)(&data->lock); + + ret =3D ads112c14_prepare_channel(data, chan); + if (ret) + return ret; + + ret =3D regmap_assign_bits(data->regmap, ADS112C14_REG_DEVICE_CFG, + ADS112C14_DEVICE_CFG_CONV_MODE, + ADS112C14_DEVICE_CFG_CONV_MODE_CONTINUOUS); + if (ret) + return ret; + + ret =3D regmap_write(data->regmap, ADS112C14_REG_CONVERSION_CTRL, + ADS112C14_CONVERSION_CTRL_START); + if (ret) { + regmap_assign_bits(data->regmap, ADS112C14_REG_DEVICE_CFG, + ADS112C14_DEVICE_CFG_CONV_MODE, + ADS112C14_DEVICE_CFG_CONV_MODE_SINGLE_SHOT); + return ret; + } + + return 0; +} + +static int ads112c14_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ads112c14_data *data =3D iio_priv(indio_dev); + int ret, ret2; + + if (!ads112c14_using_drdy_trigger(indio_dev)) + return 0; + + guard(mutex)(&data->lock); + + ret =3D regmap_write(data->regmap, ADS112C14_REG_CONVERSION_CTRL, + ADS112C14_CONVERSION_CTRL_STOP); + ret2 =3D regmap_assign_bits(data->regmap, ADS112C14_REG_DEVICE_CFG, + ADS112C14_DEVICE_CFG_CONV_MODE, + ADS112C14_DEVICE_CFG_CONV_MODE_SINGLE_SHOT); + if (ret2) + return ret2; + + return ret; +} + +static const struct iio_buffer_setup_ops ads112c14_buffer_setup_ops =3D { + .postenable =3D ads112c14_buffer_postenable, + .predisable =3D ads112c14_buffer_predisable, + .validate_scan_mask =3D ads112c14_validate_scan_mask, +}; + static int ads112c14_populate_idac_mag(u32 current_nA, u8 *idac_mag) { u32 current_uA =3D current_nA / (NANO / MICRO); @@ -1458,6 +1598,21 @@ static int ads112c14_probe(struct i2c_client *client) IRQF_NO_AUTOEN, dev_name(dev), indio_dev); if (ret) return ret; + + data->drdy_trig =3D devm_iio_trigger_alloc(dev, "%s-dev%d-drdy", + info->name, + iio_device_id(indio_dev)); + if (!data->drdy_trig) + return -ENOMEM; + + data->drdy_trig->ops =3D &ads112c14_trigger_ops; + iio_trigger_set_drvdata(data->drdy_trig, indio_dev); + + ret =3D devm_iio_trigger_register(dev, data->drdy_trig); + if (ret) + return ret; + + indio_dev->trig =3D iio_trigger_get(data->drdy_trig); } =20 ads112c14_populate_tables(data); @@ -1468,7 +1623,8 @@ static int ads112c14_probe(struct i2c_client *client) =20 ret =3D devm_iio_triggered_buffer_setup(dev, indio_dev, iio_pollfunc_store_time, - ads112c14_trigger_handler, NULL); + ads112c14_trigger_handler, + &ads112c14_buffer_setup_ops); if (ret) return ret; =20 --=20 2.43.0