From nobody Thu May 14 11:19:26 2026 Received: from mail-pf1-f177.google.com (mail-pf1-f177.google.com [209.85.210.177]) (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 6B31E33CEA7 for ; Wed, 13 May 2026 04:50:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778647819; cv=none; b=TLXCJp9Klnic/kTKpaPEexw+UqiYOy+U+ItDxta0OIYDQk4rX692Jtwxa0O1xW1FQ81V8T2Ximh0Ahb8SGRvK9c79wEbFDlEmetiTN7+tFb6+IEb58YI4/movXfmV019sI22KvjyePLl2HQKn0dXUdbnUO2gvR9mWkAQBUao5/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778647819; c=relaxed/simple; bh=tE0vkv4AeNf9uXj69TTohvhoxtlDeJ+vneLAz78H2GM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pMuGqfbsc3mSrqKkmF4N2SJRyR9zAjMFn7bj4BhddE/U+XqKbotxwSakWSk9dgQPKV8kru9E/XEIUgntIP/zeoo3TRKaZWBicIO/2G9NExmSeOxpchC6NnFt53qwZ+kAcD0sVFVBaG2szWM9MchD1gqJ77vYLH4Y0l99KbrNyeE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=aKS/CRqA; arc=none smtp.client-ip=209.85.210.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="aKS/CRqA" Received: by mail-pf1-f177.google.com with SMTP id d2e1a72fcca58-836ebdeb969so2956448b3a.3 for ; Tue, 12 May 2026 21:50:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778647818; x=1779252618; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=7zlpa7Ke4ytx6XPVc5PZ6mNxC3kCRBVIMOI9TKDTTjQ=; b=aKS/CRqAo10wmFosk25zcB2iHvTml4vYTy0c3zNV/6yCSPYHNTMUXNrKZpUMQAKnNu crH6KTz8TEAPAplRaw0kVFKiXBGgveqsF1DCbmr8u1kb+jhjPdtu2PjaNVc7SKcH5lJr Nek4Wys/n1AAzjajXM0qHZYoY/iDsSS3m2KMHiMlMT1AQerPG3WlIdzY/3Y06rEuS6vW dB7Fd2mvprA6SGVemRcGggOu1zBEQFfLvJzSZdipxYp3s4UZpJOej39fwkNgp1yG3LuG baCCcIQ2ybbhdvLWaF4KgLExvFnhDYUV8UkCOs7ZhJ4FGNRqVxZJRqiMHArIFTtxWQQ/ SvHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778647818; x=1779252618; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=7zlpa7Ke4ytx6XPVc5PZ6mNxC3kCRBVIMOI9TKDTTjQ=; b=V+7sH7GeCVOBkqM0xvS5ZjUMwodzVvxzRBQLwehYj+kDUZGi7aJy4mkRjRumlmSkU4 /51fUfQ9tTwyukpLFYgH/mT9L5zIKMMdu5hRJSnBuFEYnWHit53od3ZlknPcuc9VOny8 7stcNQ7SHyB/Im4pvBYfnMsjFbAsXl7NE44wIxzqnCMbLIeDPqhlTYPuKYV6M5OohSji NTwTc9sP7DrPuDFdeV7K8bAsr31Kt3OX/xWIkIbFYVks12S8lA9sHEh8nDHfeHJeKirw 7nKJwKdv3OH/nDCbPS46eUUH6swYn2tqowybZbCE3ThhwLeSVX8qlc+jjY6DPCt7KXiu X2AQ== X-Forwarded-Encrypted: i=1; AFNElJ8aMjKZhoZonGX40InNvBjbQhShM/4g1lZWtARbL+mYfz0uavih/o1ObbxOVKBtLZrGIxLx9i4+tVAc2KA=@vger.kernel.org X-Gm-Message-State: AOJu0YydDeQSQcU+U4ygT4HDHAXfBryRiZY0c1uuDMA5VOAoD1103ZaK M5oGy2RXewYiM0pK4l4tZdStt09c6Hkh27XnVNg6TwFfpzDVWFr1o+wt X-Gm-Gg: Acq92OE1+Fadn+GgVQLziirIT0GOOWRnuSdK/U4CHvuehTsZ3CCm9cxMhXpFSFRasQm CNIx3Dfz/u61qoID8mPzctI2m0Mn749/ogKTVlrO4JzxurjaVYJCjcwLjwtQQeTyISOwuwTrK0s QIC7SvgIHs/NAgjA14nZVqjMEHrTzv4qov+NWnU04ducnO+Bk38NaUaDY0SF4hBL0U3AIyZ/yyC Dy5M7KxoyKCTZ/71fvPr1o2CBqi6hVSor1a9F3s8LGtrJ0UvYNJqP97HCy6vHOfVaNNHWYT8puy F1ZGbNyOVlGVHc8l2aFm1vNgVEfhEJk2Ut9qs+z1zitbNQQhnVbqlrgmBXl5DghCPFR+VGEEEi2 +udClotWDKMoxcBDczvyxCyRmSE/M3Mo+UCoVP4rIduPmjwAPdUlzUKdFDgzFa2zNPj5b6QLLYP T8KnQBA4mCnXwI6FLfVrxDkA9NwtY1DgjRNHgl X-Received: by 2002:a05:6a00:800a:b0:834:e15a:19f7 with SMTP id d2e1a72fcca58-83f05d5ff3bmr1328113b3a.44.1778647817871; Tue, 12 May 2026 21:50:17 -0700 (PDT) Received: from [127.0.1.1] ([203.99.159.230]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-83965c30ddasm32311914b3a.21.2026.05.12.21.50.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 21:50:17 -0700 (PDT) From: Javier Carrasco Date: Wed, 13 May 2026 17:49:41 +1300 Subject: [PATCH v2 1/4] iio: light: veml6030: remove unnecessary read of IT index 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: <20260513-veml6031x00-v2-1-4703ca661a1d@gmail.com> References: <20260513-veml6031x00-v2-0-4703ca661a1d@gmail.com> In-Reply-To: <20260513-veml6031x00-v2-0-4703ca661a1d@gmail.com> To: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Rishi Gupta , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Matti Vaittinen Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Javier Carrasco , Jonathan Cameron X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778647803; l=1095; i=javier.carrasco.cruz@gmail.com; s=20260111; h=from:subject:message-id; bh=tE0vkv4AeNf9uXj69TTohvhoxtlDeJ+vneLAz78H2GM=; b=ISt3NzjRzb7KhHFzYzU7B2y1enxR6T8lMuDXUlrcwUAm960i6bB641ld75uErc1Haoe7q5PCx UGoUQFOdwnoCTbsG/rQYhHSBEbsZ7VkkHKCRH2y45BPImcvpL4WwIx6 X-Developer-Key: i=javier.carrasco.cruz@gmail.com; a=ed25519; pk=Lge8w8xidNSf/INy7JAIbAW+Hezkp3nsBh2OjKL7lLU= This is dead code as the IT index is not used by gts to set the new scale. In its current form, the value is read but not used afterward. Remove the dead code. Fixes: 22eaca4283b2 ("iio: light: veml6030: fix scale to conform to ABI") Signed-off-by: Javier Carrasco Reviewed-by: Andy Shevchenko --- drivers/iio/light/veml6030.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c index 6bcacae3863c..745cf3ad7092 100644 --- a/drivers/iio/light/veml6030.c +++ b/drivers/iio/light/veml6030.c @@ -521,13 +521,9 @@ static int veml6030_write_persistence(struct iio_dev *= indio_dev, =20 static int veml6030_set_scale(struct iio_dev *indio_dev, int val, int val2) { - int ret, gain_sel, it_idx, it_sel; + int ret, gain_sel, it_sel; struct veml6030_data *data =3D iio_priv(indio_dev); =20 - ret =3D regmap_field_read(data->rf.it, &it_idx); - if (ret) - return ret; - ret =3D iio_gts_find_gain_time_sel_for_scale(&data->gts, val, val2, &gain_sel, &it_sel); if (ret) --=20 2.43.0 From nobody Thu May 14 11:19:26 2026 Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) (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 EF36735DD1C for ; Wed, 13 May 2026 04:50:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778647827; cv=none; b=qCSeplH6xXvhwgvrHhQJFaRk3R51VY2uYHR6lU5woeVxaclmKfN+SOUmmkGhN3HMgTukRloj6XAru7Muqjn1J0+sSxGwtjKF4W/BdMeUjUSeIdci2vXOL6X60PxWTWG6PuaTfSujrOPfcH9uTJIm7VgVCIbmT4t0JbYkI4QasHg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778647827; c=relaxed/simple; bh=/vOOXoRFd80rf12YbVI8A9vnK+2w6WdrvOSLeNdAIU8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uTvXSfAA3L3B61OlYYS8zUwHr9dbuND6bhr6AUL77LAKxsBC1wLD6DlRDzigRYT1PnReAz/KUBop3JQBl0nrPq0uXnIKhmH34eY2jclWwsW27lgBG1fA/iH5s/mStJMOMbc+rRCU21u7M6n3GFrXxQun6Ym3jH7kQ5OV0HZoNxA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=jynYSsDS; arc=none smtp.client-ip=209.85.215.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jynYSsDS" Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-c80227b1f6cso2676387a12.1 for ; Tue, 12 May 2026 21:50:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778647825; x=1779252625; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=qBRBa2zjJe16rT7hXzyvRJvpoMNnm7ChCgpZnCI8ZZU=; b=jynYSsDSu4hOqre0wPTLOFuVR/8xS7EbYy12ci3oa+PtEeJGQs/AxlPlrObHTBxq40 1g8bTM5pLjiwr6peGInKBey2iCwRwJN36RRd7bAAf/DXhNfyqHFqo1lAkvAznPQQIJMD zpFgb5aALZU1Ek+4WRpkhVHng/RUfH3HIrqZp3h6fi2AW6sImTDEPZ/A3ElMxecjxL2Y Eu6gRSJouD77MrXycQ7LF0w/+30XXwObB7XXYFMYd67FuZFG6v3dXmYF2Pf+Jdo0qTxO W6LhNntmiIAFSkmEyLtsi5hsgmacq9spoTcYG+i8lNg9kJMCXvpLDr7L8v5dUz5MQdPV 1vkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778647825; x=1779252625; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=qBRBa2zjJe16rT7hXzyvRJvpoMNnm7ChCgpZnCI8ZZU=; b=XCqFuTd0YpfIe6tdQl62SsC4aWQTmD4jE1jAti0Aa3MEq0DCIY7gnnfTIhLRTdQo1C mMTSUm4I176aBWrJGF8yDkrUTAIl+zr5z5p5+I1f923UIwjsW4E098GDvbwiBhOZwGHL ILD57ZWz3xHwYh4Utam/Tdy40jBYKdjfxThb5aWp2N+dX9g8a5n58qjoqvqJtl79Qi2a EG6ljaefIu+AOcxZa/rOxN8ElRxbDMlRUIEhv1ZMPBGuoKsaX6TwpYk1ttHT7lkXBnv7 vy5D4QdAqHlQeelCwCob7tmec30C3H7x4LGNuN+rQ/C/23glsuufu1NFoAT5YLsu8u7+ dVFw== X-Forwarded-Encrypted: i=1; AFNElJ+J58LbXiqsxmr2/pqhbU+ELEjeSy9yiDV3KUulkgIn41G+GCHDD0a2loJbFIASv2TSomgdStYmZ6Xudok=@vger.kernel.org X-Gm-Message-State: AOJu0YxQygcvc5g2/OHl8LAQHw2vCRcl2NifyBEV+s/nlA2b+YLAfzvr xtFM6F1CCuERIDaYAFJduYyu/I1PYCbhHzKhhFsK6RSvtJSeE4J67l+6cbQW26az X-Gm-Gg: Acq92OEoU0Qi6Hco4KD3S/YlU8px2Jf+cfjxJTNK+gudJvM1hdyP6qY+3oGBDe7tYkj bT//nCGm0Yo79DKqovUFXMszEpTUPbGe7vLPAA5JabiYenZo434KlCkc5h90GC//CLqz1uOy4gZ dnV13xLkCv5sPCIuME6uKIJObyTENPz4GkFdJidaDJ9HGGIdV/WqFoNuwa/kI5p3SbnhziArWfS fU/E65YUvp5XfVxtGMDH62LZ3zoB08bW/Vujo2p9aSzE7tJTTWDG8UZVa+5NZy8MbxXkn8XYDDm VUNM5Fwe3/ks2zhf069Q0VjNIpeMBfCGhUAhl+S5WIESEbkDhvfTzkUTcgOTqq8NCmlNmNFi+xx kXVWK6QXsKBtgLl43jmmtTjr/P/p6g+0vXYCkvMo77KsAgGZiXL0aV1x9UglC1XQ5YAxnCZluxU Xm6GXDrfdNl7ge1W/TtzHD5ezk7fUMWR90w9sj X-Received: by 2002:a05:6a21:6d8d:b0:3a3:171f:6b23 with SMTP id adf61e73a8af0-3af7bafc5aamr1960301637.0.1778647825262; Tue, 12 May 2026 21:50:25 -0700 (PDT) Received: from [127.0.1.1] ([203.99.159.230]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-83965c30ddasm32311914b3a.21.2026.05.12.21.50.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 21:50:25 -0700 (PDT) From: Javier Carrasco Date: Wed, 13 May 2026 17:49:42 +1300 Subject: [PATCH v2 2/4] iio: light: veml6030: fix channel type when pushing events 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: <20260513-veml6031x00-v2-2-4703ca661a1d@gmail.com> References: <20260513-veml6031x00-v2-0-4703ca661a1d@gmail.com> In-Reply-To: <20260513-veml6031x00-v2-0-4703ca661a1d@gmail.com> To: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Rishi Gupta , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Matti Vaittinen Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Javier Carrasco , Jonathan Cameron X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778647803; l=1072; i=javier.carrasco.cruz@gmail.com; s=20260111; h=from:subject:message-id; bh=/vOOXoRFd80rf12YbVI8A9vnK+2w6WdrvOSLeNdAIU8=; b=NviQAiylJep8PRpUWH8EY2+WSWxuAH4EX3+6hnYB0Z0SKlewQlVxXH+YnbKX6ybxZKpHrZvqz BYJ/iJUp5DKBXTOJFz1Sn5XLlq+oadtMrJT8ZWiQrrSYv70Lx+s3f0l X-Developer-Key: i=javier.carrasco.cruz@gmail.com; a=ed25519; pk=Lge8w8xidNSf/INy7JAIbAW+Hezkp3nsBh2OjKL7lLU= The events are registered for IIO_LIGHT and not for IIO_INTENSITY. Use the correct channel type. This bug was introduced in the first version of the driver. When at it, fix minor checkpatch code style warning (alignment). Signed-off-by: Javier Carrasco --- drivers/iio/light/veml6030.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c index 745cf3ad7092..855f052b60c2 100644 --- a/drivers/iio/light/veml6030.c +++ b/drivers/iio/light/veml6030.c @@ -871,9 +871,11 @@ static irqreturn_t veml6030_event_handler(int irq, voi= d *private) else evtdir =3D IIO_EV_DIR_FALLING; =20 - iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, - 0, IIO_EV_TYPE_THRESH, evtdir), - iio_get_time_ns(indio_dev)); + iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_LIGHT, + 0, + IIO_EV_TYPE_THRESH, + evtdir), + iio_get_time_ns(indio_dev)); =20 return IRQ_HANDLED; } --=20 2.43.0 From nobody Thu May 14 11:19:26 2026 Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) (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 B1CCE30B53F for ; Wed, 13 May 2026 04:50:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778647835; cv=none; b=B1eVGrO+8qK4+jr3L2NayVXP+n4w0qe7fIGCW5Kio46xT1a/0lxEG38efI8FPwrMIuCsLq4/e906obsu7TK3S/NB0Ex9TBvkjVqRNnCIdGsmQjLK2Ogo5JFn7vwzrU8nZU+VUEGbB0O8bX9pf4lQKWvx0lwb3aFYPNYgi3OfJ0w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778647835; c=relaxed/simple; bh=+ccVjW/jqDGXe+Kpx9slzAPr+lCSpT3yVLJ5GehwNBs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=te0Wh7g1YeCSfnP6s1aD7J4eJdLxWTnHPb/T8NtlmGkvEVrQQgLmx6MnEMXO9OIr+DRBlK+op94yhi1Xf5kLy7O8AiXDXblKyrG14vfzCEfHQTolC2QgrWUBKtbyuatlXYhv2fLL46MqKhLA6RC82wkKJ+mtiqz95GF20zeE9Ww= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=MzEb02HB; arc=none smtp.client-ip=209.85.210.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MzEb02HB" Received: by mail-pf1-f176.google.com with SMTP id d2e1a72fcca58-82748257f5fso4575012b3a.1 for ; Tue, 12 May 2026 21:50:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778647833; x=1779252633; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=+AkLS3ikcXWyd0nEsg1ckmOLpbRPjWnuu6CMO4iUAjs=; b=MzEb02HBErtYTHwwwDgjQSY/If1qJdS8SuLjpr2Qs8q6V2hL/gtbmp/SVnWDYDUS2h uBq+nVKkJn64BTyIAP8v56MzwfQS1WsELH8sfaU/055Y6Rshn4xWbETm/4IUKyOiGITo JGOJA605uReDyeRbZ/eNboBLVr7hNGhZ9oF4m3NAkqjh4PxyQ6jg4wtWRAM6WDnteY9N QH9OArrm1Mnnuqeo2MSa1ALMS4jBvtsIlaWzZb07WhqZIzs1fX7+ODHL+t2Kh0vqWB1D IYOlKo27OcwWm/lHfaHHZIq0Etm7nwgDZILGKJg2P6fSH1UhF3EcL5v8n6fpQAZxXYkp g0SA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778647833; x=1779252633; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=+AkLS3ikcXWyd0nEsg1ckmOLpbRPjWnuu6CMO4iUAjs=; b=JgUV93h1ay9xnNfPy2BYl3L4Oz2EXib6QNGdKN4cY5KbVuKieAWz0pfgTV08fSg1F/ /b4tpYobXtuDHNkHyl0/e6mIdO46VwIGNUHAGJSsPRYtCPCt/sFzL3oPAlU26q7AJLYS 0Q0QW7wsyTZndYa+pQcNSQkab4ZiozP8UCjjxBRph6fJVasr0kHbNouOVbOFbBs9KBTi PprNdFhuFPPLGPQ81BqxDumC3NuaS9gbL5SCKf2+9/G/x/kcvrGepys+EvJHp/4SqBav 1NgepEG3QH70vYI6166L6w5RXyTcFQHewZ/2eRAmlxCPGYMpHsZNxazx0YNv5hjBAyMl jwyg== X-Forwarded-Encrypted: i=1; AFNElJ/kcjsQakRTp5/C2udBw11iw9rxSWRrVXTlaGD3QhAdEEpVNSSrQS11WrZBXyKd6SwitiN3biWF2ZhJR3s=@vger.kernel.org X-Gm-Message-State: AOJu0Yw/eR3H/HGOXy7s3YYmIsWiAzPZ7b6J1Dl9b5GJiYiwdaulX8Cj xMUcWkqNa9YtRGOfVGMHTIm/mqvLOgzVm1V7scoCDt0eru6jzR9BLKLj X-Gm-Gg: Acq92OEKHIPRhH5A06BXnNzZQQCKcP4o3b8o75/dafv5tMRAJbt2GtlQDrhve0fCE2F UINFmg9gRCbSWQQ3zCaXYkrvAob3+lO9831l+0snBU/4C0WjlELNEeiJR5CuRhFppRIA4gpygCq nPIED8d29ybdXTI04xhQy2ZMeEpUBcjUpRVKeP2t4PiO/W0RG8r/AgW5/Tv3tANsVCzo0OK+jEl 0zM0LJY/9PH3/nLSRrYbgx6R5YPZBiZca3FpZ4Eev5EBxogUYg9sz1TOyP+yIhEz+yDn9R958Cb WsNLH1FlA+2OyR0WB5WbKqXK+xl6jYtre1oabD5aX0HQBgQ7NS9C5I7dA/7PqbNyqoGlKjJ9eS/ UE8IwaNjzf7en57r7Mjw99OTGePHU9tU9elL3wlLZgTmQ0Nudu3qaac+MIL5TsVBCQ6b/lmH1iZ 0or0cmTNXTmnS4IpogSbmvVS6ReRrXQMhLo31Z X-Received: by 2002:a05:6a00:2e85:b0:82f:7762:3eb2 with SMTP id d2e1a72fcca58-83ee83ab8d8mr6611338b3a.17.1778647832891; Tue, 12 May 2026 21:50:32 -0700 (PDT) Received: from [127.0.1.1] ([203.99.159.230]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-83965c30ddasm32311914b3a.21.2026.05.12.21.50.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 21:50:32 -0700 (PDT) From: Javier Carrasco Date: Wed, 13 May 2026 17:49:43 +1300 Subject: [PATCH v2 3/4] dt-bindings: iio: light: veml6030: add veml6031x00 ALS series 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: <20260513-veml6031x00-v2-3-4703ca661a1d@gmail.com> References: <20260513-veml6031x00-v2-0-4703ca661a1d@gmail.com> In-Reply-To: <20260513-veml6031x00-v2-0-4703ca661a1d@gmail.com> To: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Rishi Gupta , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Matti Vaittinen Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Javier Carrasco , Jonathan Cameron , Krzysztof Kozlowski X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778647803; l=2675; i=javier.carrasco.cruz@gmail.com; s=20260111; h=from:subject:message-id; bh=+ccVjW/jqDGXe+Kpx9slzAPr+lCSpT3yVLJ5GehwNBs=; b=EDok/p/DvyVNEPOElCZ4OUVjZIwbNbKHzGBiYvurGsYsbvYh3hhg8Kntf+FBZ58lQbBQpwzYC uG1WhK6e1j+CCXI47GnaYWGs1gAtqj0ahFbdkUzTxdvXy5/jwsUMZqx X-Developer-Key: i=javier.carrasco.cruz@gmail.com; a=ed25519; pk=Lge8w8xidNSf/INy7JAIbAW+Hezkp3nsBh2OjKL7lLU= These ambient light sensors share their properties with the ones from the same manufacturer that are supported by this bindings. Note that only two datasheets are provided as every one of them covers two devices (veml6031x00/veml60311x00 and veml6031x01/veml60311x01). Reviewed-by: Krzysztof Kozlowski Signed-off-by: Javier Carrasco --- .../bindings/iio/light/vishay,veml6030.yaml | 23 ++++++++++++++++++= +++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/light/vishay,veml6030.ya= ml b/Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml index 4ea69f1fdd63..e01e8747e47c 100644 --- a/Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml +++ b/Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml @@ -4,7 +4,9 @@ $id: http://devicetree.org/schemas/iio/light/vishay,veml6030.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# =20 -title: VEML3235, VEML6030, VEML6035 and VEML7700 Ambient Light Sensors (AL= S) +title: + VEML3235, VEML6030, VEML6031x00 series, VEML6035 and VEML7700 Ambient + Light Sensors (ALS) =20 maintainers: - Rishi Gupta @@ -22,12 +24,18 @@ description: | Specifications about the sensors can be found at: https://www.vishay.com/docs/80131/veml3235.pdf https://www.vishay.com/docs/84366/veml6030.pdf + https://www.vishay.com/docs/80007/veml6031x00.pdf + https://www.vishay.com/docs/80008/veml6031x01.pdf https://www.vishay.com/docs/84889/veml6035.pdf https://www.vishay.com/docs/84286/veml7700.pdf =20 properties: compatible: enum: + - vishay,veml6031x00 + - vishay,veml6031x01 + - vishay,veml60311x00 + - vishay,veml60311x01 - vishay,veml3235 - vishay,veml6030 - vishay,veml6035 @@ -67,6 +75,8 @@ allOf: properties: compatible: enum: + - vishay,veml6031x00 + - vishay,veml6031x01 - vishay,veml6035 then: properties: @@ -79,12 +89,23 @@ allOf: compatible: enum: - vishay,veml3235 + - vishay,veml60311x00 + - vishay,veml60311x01 - vishay,veml7700 then: properties: reg: enum: - 0x10 + + - if: + properties: + compatible: + enum: + - vishay,veml3235 + - vishay,veml7700 + then: + properties: interrupts: false =20 additionalProperties: false --=20 2.43.0 From nobody Thu May 14 11:19:26 2026 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) (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 7449D36F433 for ; Wed, 13 May 2026 04:50:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778647844; cv=none; b=EBcaFNanuZviFCbHh2jqRNvTe1uC5lkOEGXhDW7vlaCopuRdmjwrNun9EaE5eFfJxstaZ1tN7ymLBjwdPRvImEO9Wcj79a193hjczzLQQ0+PgGUhx6VzD7fwwwp3NvJ9nyKu1qp/Hkto7mG/2FYNf0zhNb6emVT0nGx9MdvmENc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778647844; c=relaxed/simple; bh=cvTs1n2sPa+E3ZhXZBr9BC7sH1tYAtYHPZZTk5ec8Ho=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UTqYrpan2vsEXN0gL5oR90moelY0K5cpASKvV7l/jCXKbQC3NlGtBhftkIg6iqz6iim2CU8TZAhiPDh/P/AhLZDR1Kzf8KyjabUi3kW1SHoNsst7eRyDz8DVBiZhdHatpKuva1FO7eafQhp8h+AksCqsOl6Fvdj4YKTKiawwaNk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=iYNKqrL7; arc=none smtp.client-ip=209.85.210.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="iYNKqrL7" Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-836ebdeb969so2956575b3a.3 for ; Tue, 12 May 2026 21:50:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778647841; x=1779252641; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=bKXwJb+LssX9P49yFim1pRUPEBYZl2twCLYbgVax7rY=; b=iYNKqrL7qjMH5xTC0H1Dq/rvVPCag7XA7WvScf3g315VZTQk1qcv6xJ388r2RE1MOE 6nMvesst0jeMxK6rK4u8jH6NjBqzvza9BtZ/w7ZuAYIH1pyKbq3zeYIUmDfG8DIXZmca cXDOKU+mRwmxT6K2IWiDR7/kW+l6XhqIGiDH5cwNKcKJskXzF/YYSrZbfkqMGwT0Jc66 dc7lWpJSSLxygiSqMKIgZmGRlAG7Q7jgG7gzmQYmPiMkegbHW4BmR5LZFogNuV24aOnU aon7cY0wb3is+mtv+GJPOwoCxkaHZr4ZDxi9YFHJ4cD1EZwK7/jORj4gQoPfD4/leiRN BdaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778647841; x=1779252641; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=bKXwJb+LssX9P49yFim1pRUPEBYZl2twCLYbgVax7rY=; b=NXGHFoxrQhzE4B8v7DSuKtlq301i2+sOl7iAXpoLNGSoju+pQDITt3dNRJIaiywJEc g/I0Mesij1JAQM7942mo9Y4Hzn8EIbfoAmGb9Guo2QT2hpUltDD9xVI7PlmL5jqDV0dz qFALkjVqHSIpQhKZjdRu5owiwIehM3m009labZm/R9gGhot3u3/kKU5DEaj7Bt0rx5uj tpJBkCw01tVEI5LFCpW58KZ5XubhJm7TIRomBUDFkeN3leBTsIBCXA9W1bE7l+7eVSdm Ob9nY3WXXZlYDyerDPEZOXmU1XNMxp23ykhAC3+r3Ha+V3PPkNGAmx+r8B3g6GF9hQe3 w2+Q== X-Forwarded-Encrypted: i=1; AFNElJ9YmQwqJfMl0O62O9WjYOwjyQ/TPo+uZlAjI3reRrWNHwOikVGy2thkCNBmjWfRyfBxLCVF+AsCLgKm6tU=@vger.kernel.org X-Gm-Message-State: AOJu0YzbLH7wxqvvL5OFQNp6rqawhlVdVgjZMGLrqGpk1tVagzZTrRXW JIveX4WFzUIuWwfJ3c188ah0qBQMn1Du+32tFxy/ceww6oFs4qFkuB6qvDZZVa/8 X-Gm-Gg: Acq92OFUwBW21ETm7pdGKhKnkVuI5dZHOix9OHRWvawE4HoYiWL5LwWu0EuMHgb+TLP fWmaEQ28SNR8I1nrTDMSYkaPgIE/Yi4R9mREoVi0BBt7+xqZqcl2jWR/AujL/CECj3hxWmBPeyq 1s7uHADaEYrVotiCCNxc+pkcfXtymKwkblk1C7m2tENV/larr3tQcAHOJw90RiBv5EvO+iDZ9KI K0i/cmQVpxf1sSAZxf1LNQ0avVjKYTQShV1QoFZHzQDgwO7HIzofihhAh3TE41t1el6uFCRD/aS Msr4FLQ4CiT2LO/8RksuNLLTcp2oNotshUM4+oWghkzcHMu9KYQljE0EGjU2F+PI00vL3mtQFtZ d4mlZzddzOQ5Nq4o82v0Y51pxRcYnxLWFsrLc3lNOMe432tlx8cx3qXFfWRNFd0bFFCXXFGaO+G 8YT8GsvBYXhwnBo+Z0htF6gAKP9FLuuLXAkrqq8wdhOxkLn6U= X-Received: by 2002:a05:6a00:a203:b0:837:8c8f:8f51 with SMTP id d2e1a72fcca58-83f05d62ebcmr1289731b3a.47.1778647840539; Tue, 12 May 2026 21:50:40 -0700 (PDT) Received: from [127.0.1.1] ([203.99.159.230]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-83965c30ddasm32311914b3a.21.2026.05.12.21.50.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 21:50:40 -0700 (PDT) From: Javier Carrasco Date: Wed, 13 May 2026 17:49:44 +1300 Subject: [PATCH v2 4/4] iio: light: add support for veml6031x00 ALS series 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: <20260513-veml6031x00-v2-4-4703ca661a1d@gmail.com> References: <20260513-veml6031x00-v2-0-4703ca661a1d@gmail.com> In-Reply-To: <20260513-veml6031x00-v2-0-4703ca661a1d@gmail.com> To: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Rishi Gupta , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Matti Vaittinen Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Javier Carrasco , Jonathan Cameron X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778647803; l=35871; i=javier.carrasco.cruz@gmail.com; s=20260111; h=from:subject:message-id; bh=cvTs1n2sPa+E3ZhXZBr9BC7sH1tYAtYHPZZTk5ec8Ho=; b=eftVHI3j/nSelvmsbBHEuJuXS/IJYomO/ETTCO5lVcIxd5WlDe2fluRHJw3cuHkpRCeIqK3ry p38IGayGQ5WAA1TvNt/dniG4aYJhtEqzyMA8dUn6Lh3k4GiIHpLYbi5 X-Developer-Key: i=javier.carrasco.cruz@gmail.com; a=ed25519; pk=Lge8w8xidNSf/INy7JAIbAW+Hezkp3nsBh2OjKL7lLU= These sensors provide two light channels (ALS and IR), I2C communication and a multiplexed interrupt line to signal data ready and configurable threshold alarms. Signed-off-by: Javier Carrasco --- MAINTAINERS | 6 + drivers/iio/light/Kconfig | 14 + drivers/iio/light/Makefile | 1 + drivers/iio/light/veml6031x00.c | 1193 +++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 1214 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 2fb1c75afd16..47da46717c16 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -28381,6 +28381,12 @@ S: Maintained F: Documentation/devicetree/bindings/iio/light/vishay,veml6046x00.yaml F: drivers/iio/light/veml6046x00.c =20 +VISHAY VEML6031X00 AMBIENT LIGHT SENSOR DRIVER +M: Javier Carrasco +S: Maintained +F: Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml +F: drivers/iio/light/veml6031x00.c + VISHAY VEML6075 UVA AND UVB LIGHT SENSOR DRIVER M: Javier Carrasco S: Maintained diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index eff33e456c70..b99f4e8d9a70 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -713,6 +713,20 @@ config VEML6030 To compile this driver as a module, choose M here: the module will be called veml6030. =20 +config VEML6031X00 + tristate "VEML6031X00 ambient light sensor series" + select REGMAP_I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select IIO_GTS_HELPER + depends on I2C + help + Say Y here if you want to build a driver for the Vishay VEML6031X00 + ambient light sensor series. + + To compile this driver as a module, choose M here: the + module will be called veml6031x00. + config VEML6040 tristate "VEML6040 RGBW light sensor" select REGMAP_I2C diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index c0048e0d5ca8..a8cc03cfb6c2 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_VCNL4000) +=3D vcnl4000.o obj-$(CONFIG_VCNL4035) +=3D vcnl4035.o obj-$(CONFIG_VEML3235) +=3D veml3235.o obj-$(CONFIG_VEML6030) +=3D veml6030.o +obj-$(CONFIG_VEML6031X00) +=3D veml6031x00.o obj-$(CONFIG_VEML6040) +=3D veml6040.o obj-$(CONFIG_VEML6046X00) +=3D veml6046x00.o obj-$(CONFIG_VEML6070) +=3D veml6070.o diff --git a/drivers/iio/light/veml6031x00.c b/drivers/iio/light/veml6031x0= 0.c new file mode 100644 index 000000000000..c7808768f45a --- /dev/null +++ b/drivers/iio/light/veml6031x00.c @@ -0,0 +1,1193 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * VEML6031X00 Ambient Light Sensor + * + * Copyright (c) 2026, Javier Carrasco + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Device registers */ +#define VEML6031X00_REG_CONF0 0x00 +#define VEML6031X00_REG_CONF1 0x01 +#define VEML6031X00_REG_WH_L 0x04 +#define VEML6031X00_REG_WH_H 0x05 +#define VEML6031X00_REG_WL_L 0x06 +#define VEML6031X00_REG_WL_H 0x07 +#define VEML6031X00_REG_ALS_L 0x10 +#define VEML6031X00_REG_ALS_H 0x11 +#define VEML6031X00_REG_IR_L 0x12 +#define VEML6031X00_REG_IR_H 0x13 +#define VEML6031X00_REG_ID_L 0x14 +#define VEML6031X00_REG_ID_H 0x15 +#define VEML6031X00_REG_INT 0x17 + +/* Bit masks for specific functionality */ +#define VEML6031X00_ALL_CH_MASK GENMASK(1, 0) +#define VEML6031X00_CONF0_SD BIT(0) +#define VEML6031X00_CONF0_AF_TRIG BIT(2) +#define VEML6031X00_CONF0_AF BIT(3) +#define VEML6031X00_CONF1_IR_SD BIT(7) +#define VEML6031X00_INT_TH_H BIT(1) +#define VEML6031X00_INT_TH_L BIT(2) +#define VEML6031X00_INT_DRDY BIT(3) +#define VEML6031X00_INT_MASK (VEML6031X00_INT_TH_L | \ + VEML6031X00_INT_TH_H | \ + VEML6031X00_INT_DRDY) + +/* Autosuspend delay */ +#define VEML6031X00_AUTOSUSPEND_MS 2000 + +enum veml6031x00_scan { + VEML6031X00_SCAN_ALS, + VEML6031X00_SCAN_IR, + VEML6031X00_SCAN_TIMESTAMP, +}; + +struct veml6031x00_rf { + struct regmap_field *gain; + struct regmap_field *int_en; + struct regmap_field *it; + struct regmap_field *pd_div4; + struct regmap_field *pers; +}; + +struct veml6031x00_chip { + const char *name; + const int part_id; +}; + +struct veml6031x00_data { + struct device *dev; + struct iio_gts gts; + struct regmap *regmap; + struct iio_trigger *trig; + struct veml6031x00_rf rf; + const struct veml6031x00_chip *chip; + /* serialize access to irq enable/disable by events and trigger */ + struct mutex lock; + atomic_t int_users; + bool ev_en; + bool trig_en; +}; + +static const struct iio_itime_sel_mul veml6031x00_it_sel[] =3D { + GAIN_SCALE_ITIME_US(3125, 0, 1), + GAIN_SCALE_ITIME_US(6250, 1, 2), + GAIN_SCALE_ITIME_US(12500, 2, 4), + GAIN_SCALE_ITIME_US(25000, 3, 8), + GAIN_SCALE_ITIME_US(50000, 4, 16), + GAIN_SCALE_ITIME_US(100000, 5, 32), + GAIN_SCALE_ITIME_US(200000, 6, 64), + GAIN_SCALE_ITIME_US(400000, 7, 128), +}; + +/* + * The gain selector encodes (PD_D4 << 2) | GAIN to identify each gain set= ting. + * Gains are multiplied by 8 to work with integers. The values in the iio-= gts + * tables don't need corrections because the maximum value of the scale re= fers + * to GAIN =3D x1, and the rest of the values are obtained from the result= ing + * linear function. + * TODO: add support for MILLI_GAIN_X165 and MILLI_GAIN_X660 + */ +#define VEML6031X00_SEL_MILLI_GAIN_X125 0x07 +#define VEML6031X00_SEL_MILLI_GAIN_X250 0x04 +#define VEML6031X00_SEL_MILLI_GAIN_X500 0x03 +#define VEML6031X00_SEL_MILLI_GAIN_X1000 0x00 +#define VEML6031X00_SEL_MILLI_GAIN_X2000 0x01 +static const struct iio_gain_sel_pair veml6031x00_gain_sel[] =3D { + GAIN_SCALE_GAIN(1, VEML6031X00_SEL_MILLI_GAIN_X125), + GAIN_SCALE_GAIN(2, VEML6031X00_SEL_MILLI_GAIN_X250), + GAIN_SCALE_GAIN(4, VEML6031X00_SEL_MILLI_GAIN_X500), + GAIN_SCALE_GAIN(8, VEML6031X00_SEL_MILLI_GAIN_X1000), + GAIN_SCALE_GAIN(16, VEML6031X00_SEL_MILLI_GAIN_X2000), +}; + +static IIO_CONST_ATTR(in_illuminance_thresh_either_period_available, "1 2 = 4 8"); + +static struct attribute *veml6031x00_event_attributes[] =3D { + &iio_const_attr_in_illuminance_thresh_either_period_available.dev_attr.at= tr, + NULL +}; + +static const struct attribute_group veml6031x00_event_attr_group =3D { + .attrs =3D veml6031x00_event_attributes, +}; + +/* + * Two shutdown bits (SD and ALS_IR_SD) must be cleared to power on + * the device. + */ +static int veml6031x00_als_power_on(struct veml6031x00_data *data) +{ + int ret; + + ret =3D regmap_clear_bits(data->regmap, VEML6031X00_REG_CONF0, + VEML6031X00_CONF0_SD); + if (ret) + return ret; + + return regmap_clear_bits(data->regmap, VEML6031X00_REG_CONF1, + VEML6031X00_CONF1_IR_SD); +} + +/* + * Two shutdown bits (SD and ALS_IR_SD) must be set to power off + * the device. + */ +static int veml6031x00_als_shutdown(struct veml6031x00_data *data) +{ + int ret; + + ret =3D regmap_set_bits(data->regmap, VEML6031X00_REG_CONF0, + VEML6031X00_CONF0_SD); + if (ret) + return ret; + + return regmap_set_bits(data->regmap, VEML6031X00_REG_CONF1, + VEML6031X00_CONF1_IR_SD); +} + +static void veml6031x00_als_shutdown_action(void *data) +{ + veml6031x00_als_shutdown(data); +} + +static const struct iio_event_spec veml6031x00_event_spec[] =3D { + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_RISING, + .mask_separate =3D BIT(IIO_EV_INFO_VALUE), + }, { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_FALLING, + .mask_separate =3D BIT(IIO_EV_INFO_VALUE), + }, { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_EITHER, + .mask_separate =3D BIT(IIO_EV_INFO_PERIOD) | + BIT(IIO_EV_INFO_ENABLE), + }, +}; + +static const struct iio_chan_spec veml6031x00_channels[] =3D { + { + .type =3D IIO_LIGHT, + .address =3D VEML6031X00_REG_ALS_L, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all =3D BIT(IIO_CHAN_INFO_INT_TIME), + .info_mask_shared_by_all_available =3D BIT(IIO_CHAN_INFO_INT_TIME), + .info_mask_separate_available =3D BIT(IIO_CHAN_INFO_SCALE), + .event_spec =3D veml6031x00_event_spec, + .num_event_specs =3D ARRAY_SIZE(veml6031x00_event_spec), + .scan_index =3D VEML6031X00_SCAN_ALS, + .scan_type =3D { + .sign =3D 'u', + .realbits =3D 16, + .storagebits =3D 16, + .endianness =3D IIO_LE, + }, + }, + { + .type =3D IIO_INTENSITY, + .address =3D VEML6031X00_REG_IR_L, + .modified =3D 1, + .channel2 =3D IIO_MOD_LIGHT_IR, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all =3D BIT(IIO_CHAN_INFO_INT_TIME), + .info_mask_shared_by_all_available =3D BIT(IIO_CHAN_INFO_INT_TIME), + .scan_index =3D VEML6031X00_SCAN_IR, + .scan_type =3D { + .sign =3D 'u', + .realbits =3D 16, + .storagebits =3D 16, + .endianness =3D IIO_LE, + }, + }, + IIO_CHAN_SOFT_TIMESTAMP(VEML6031X00_SCAN_TIMESTAMP), +}; + +static const struct regmap_range veml6031x00_readable_ranges[] =3D { + regmap_reg_range(VEML6031X00_REG_CONF0, VEML6031X00_REG_CONF1), + regmap_reg_range(VEML6031X00_REG_WH_L, VEML6031X00_REG_WL_H), + regmap_reg_range(VEML6031X00_REG_ALS_L, VEML6031X00_REG_ID_H), + regmap_reg_range(VEML6031X00_REG_INT, VEML6031X00_REG_INT), +}; + +static const struct regmap_access_table veml6031x00_readable_table =3D { + .yes_ranges =3D veml6031x00_readable_ranges, + .n_yes_ranges =3D ARRAY_SIZE(veml6031x00_readable_ranges), +}; + +static const struct regmap_range veml6031x00_writable_ranges[] =3D { + regmap_reg_range(VEML6031X00_REG_CONF0, VEML6031X00_REG_WL_H), +}; + +static const struct regmap_access_table veml6031x00_writable_table =3D { + .yes_ranges =3D veml6031x00_writable_ranges, + .n_yes_ranges =3D ARRAY_SIZE(veml6031x00_writable_ranges), +}; + +static const struct regmap_range veml6031x00_volatile_ranges[] =3D { + regmap_reg_range(VEML6031X00_REG_ALS_L, VEML6031X00_REG_IR_H), + regmap_reg_range(VEML6031X00_REG_INT, VEML6031X00_REG_INT), +}; + +static const struct regmap_access_table veml6031x00_volatile_table =3D { + .yes_ranges =3D veml6031x00_volatile_ranges, + .n_yes_ranges =3D ARRAY_SIZE(veml6031x00_volatile_ranges), +}; + +static const struct regmap_range veml6031x00_precious_ranges[] =3D { + regmap_reg_range(VEML6031X00_REG_INT, VEML6031X00_REG_INT), +}; + +static const struct regmap_access_table veml6031x00_precious_table =3D { + .yes_ranges =3D veml6031x00_precious_ranges, + .n_yes_ranges =3D ARRAY_SIZE(veml6031x00_precious_ranges), +}; + +static const struct regmap_config veml6031x00_regmap_config =3D { + .name =3D "veml6031x00_regmap", + .reg_bits =3D 8, + .val_bits =3D 8, + .rd_table =3D &veml6031x00_readable_table, + .wr_table =3D &veml6031x00_writable_table, + .volatile_table =3D &veml6031x00_volatile_table, + .precious_table =3D &veml6031x00_precious_table, + .max_register =3D VEML6031X00_REG_INT, + .cache_type =3D REGCACHE_MAPLE, +}; + +static const struct reg_field veml6031x00_rf_int_en =3D + REG_FIELD(VEML6031X00_REG_CONF0, 1, 1); + +static const struct reg_field veml6031x00_rf_it =3D + REG_FIELD(VEML6031X00_REG_CONF0, 4, 6); + +static const struct reg_field veml6031x00_rf_pers =3D + REG_FIELD(VEML6031X00_REG_CONF1, 1, 2); + +static const struct reg_field veml6031x00_rf_gain =3D + REG_FIELD(VEML6031X00_REG_CONF1, 3, 4); + +static const struct reg_field veml6031x00_rf_pd_div4 =3D + REG_FIELD(VEML6031X00_REG_CONF1, 6, 6); + +static int veml6031x00_regfield_init(struct veml6031x00_data *data) +{ + struct regmap *regmap =3D data->regmap; + struct device *dev =3D data->dev; + struct regmap_field *rm_field; + struct veml6031x00_rf *rf =3D &data->rf; + + rm_field =3D devm_regmap_field_alloc(dev, regmap, veml6031x00_rf_gain); + if (IS_ERR(rm_field)) + return PTR_ERR(rm_field); + rf->gain =3D rm_field; + + rm_field =3D devm_regmap_field_alloc(dev, regmap, veml6031x00_rf_int_en); + if (IS_ERR(rm_field)) + return PTR_ERR(rm_field); + rf->int_en =3D rm_field; + + rm_field =3D devm_regmap_field_alloc(dev, regmap, veml6031x00_rf_it); + if (IS_ERR(rm_field)) + return PTR_ERR(rm_field); + rf->it =3D rm_field; + + rm_field =3D devm_regmap_field_alloc(dev, regmap, veml6031x00_rf_pd_div4); + if (IS_ERR(rm_field)) + return PTR_ERR(rm_field); + rf->pd_div4 =3D rm_field; + + rm_field =3D devm_regmap_field_alloc(dev, regmap, veml6031x00_rf_pers); + if (IS_ERR(rm_field)) + return PTR_ERR(rm_field); + rf->pers =3D rm_field; + + return 0; +} + +static int veml6031x00_get_it(struct veml6031x00_data *data, int *val, int= *val2) +{ + int ret, it_idx; + + ret =3D regmap_field_read(data->rf.it, &it_idx); + if (ret) + return ret; + + ret =3D iio_gts_find_int_time_by_sel(&data->gts, it_idx); + if (ret < 0) + return ret; + + *val2 =3D ret; + *val =3D 0; + + return IIO_VAL_INT_PLUS_MICRO; +} + +static int veml6031x00_set_it(struct iio_dev *iio, int val, int val2) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + int ret, gain_sel, gain_reg, pd_div4, it_idx, new_gain, prev_gain, prev_i= t; + bool in_range; + + if (val || !iio_gts_valid_time(&data->gts, val2)) + return -EINVAL; + + ret =3D regmap_field_read(data->rf.it, &it_idx); + if (ret) + return ret; + + ret =3D regmap_field_read(data->rf.gain, &gain_reg); + if (ret) + return ret; + + ret =3D regmap_field_read(data->rf.pd_div4, &pd_div4); + if (ret) + return ret; + + prev_it =3D iio_gts_find_int_time_by_sel(&data->gts, it_idx); + if (prev_it < 0) + return prev_it; + + if (prev_it =3D=3D val2) + return 0; + + prev_gain =3D iio_gts_find_gain_by_sel(&data->gts, (pd_div4 << 2) | gain_= reg); + if (prev_gain < 0) + return prev_gain; + + ret =3D iio_gts_find_new_gain_by_gain_time_min(&data->gts, prev_gain, pre= v_it, + val2, &new_gain, &in_range); + if (ret) + return ret; + + if (!in_range) + dev_dbg(data->dev, "Optimal gain out of range\n"); + + ret =3D iio_gts_find_sel_by_int_time(&data->gts, val2); + if (ret < 0) + return ret; + + ret =3D regmap_field_write(data->rf.it, ret); + if (ret) + return ret; + + gain_sel =3D iio_gts_find_sel_by_gain(&data->gts, new_gain); + if (gain_sel < 0) + return gain_sel; + + ret =3D regmap_field_write(data->rf.pd_div4, gain_sel >> 2); + if (ret) + return ret; + + return regmap_field_write(data->rf.gain, gain_sel & 0x03); +} + +static int veml6031x00_read_period(struct iio_dev *iio, int *val) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + int ret, reg; + + ret =3D regmap_field_read(data->rf.pers, ®); + if (ret) + return ret; + + *val =3D 1 << reg; + + return IIO_VAL_INT; +} + +static int veml6031x00_write_period(struct iio_dev *iio, int val) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + + if (val > 8 || hweight8(val) !=3D 1) + return -EINVAL; + + return regmap_field_write(data->rf.pers, ffs(val) - 1); +} + +static int veml6031x00_set_scale(struct iio_dev *iio, int val, int val2) +{ + int gain_sel, it_sel, ret; + struct veml6031x00_data *data =3D iio_priv(iio); + + ret =3D iio_gts_find_gain_time_sel_for_scale(&data->gts, val, val2, + &gain_sel, &it_sel); + if (ret) + return ret; + + ret =3D regmap_field_write(data->rf.it, it_sel); + if (ret) + return ret; + + ret =3D regmap_field_write(data->rf.pd_div4, gain_sel >> 2); + if (ret) + return ret; + + return regmap_field_write(data->rf.gain, gain_sel & 0x03); +} + +static int veml6031x00_get_scale(struct veml6031x00_data *data, int *val, + int *val2) +{ + int gain, it, gain_reg, pd_div4, it_reg, ret, sel; + + ret =3D regmap_field_read(data->rf.gain, &gain_reg); + if (ret) + return ret; + + ret =3D regmap_field_read(data->rf.pd_div4, &pd_div4); + if (ret) + return ret; + + sel =3D (pd_div4 << 2) | gain_reg; + gain =3D iio_gts_find_gain_by_sel(&data->gts, sel); + if (gain < 0) + return gain; + + ret =3D regmap_field_read(data->rf.it, &it_reg); + if (ret) + return ret; + + it =3D iio_gts_find_int_time_by_sel(&data->gts, it_reg); + if (it < 0) + return it; + + ret =3D iio_gts_get_scale(&data->gts, gain, it, val, val2); + if (ret) + return ret; + + return IIO_VAL_INT_PLUS_NANO; +} + +static int veml6031x00_read_th(struct iio_dev *iio, int *val, int *val2, i= nt dir) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + __le16 reg; + int ret; + + if (dir =3D=3D IIO_EV_DIR_RISING) + ret =3D regmap_bulk_read(data->regmap, VEML6031X00_REG_WH_L, + ®, sizeof(reg)); + else + ret =3D regmap_bulk_read(data->regmap, VEML6031X00_REG_WL_L, + ®, sizeof(reg)); + if (ret) + return ret; + + *val =3D le16_to_cpu(reg); + + return IIO_VAL_INT; +} + +static int veml6031x00_write_th(struct iio_dev *iio, int val, int val2, in= t dir) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + struct device *dev =3D data->dev; + __le16 reg =3D cpu_to_le16(val); + int ret; + + if (val < 0 || val > U16_MAX || val2) + return -EINVAL; + + if (dir =3D=3D IIO_EV_DIR_RISING) { + ret =3D regmap_bulk_write(data->regmap, VEML6031X00_REG_WH_L, + ®, sizeof(reg)); + if (ret) + dev_dbg(dev, "Failed to set high threshold %d\n", ret); + } else { + ret =3D regmap_bulk_write(data->regmap, VEML6031X00_REG_WL_L, + ®, sizeof(reg)); + if (ret) + dev_dbg(dev, "Failed to set low threshold %d\n", ret); + } + + return ret; +} + +static int veml6031x00_single_read(struct iio_dev *iio, enum iio_chan_type= type, + int *val) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + int addr, it_sec, it_usec, ret; + __le16 reg; + + switch (type) { + case IIO_LIGHT: + addr =3D VEML6031X00_REG_ALS_L; + break; + case IIO_INTENSITY: + addr =3D VEML6031X00_REG_IR_L; + break; + default: + return -EINVAL; + } + + ret =3D pm_runtime_resume_and_get(data->dev); + if (ret) + return ret; + + ret =3D veml6031x00_get_it(data, &it_sec, &it_usec); + if (ret < 0) + goto put_autosuspend; + + /* integration time + 10 % to ensure completion */ + fsleep((it_sec * MICRO) + it_usec + (it_usec / 10)); + + if (!iio_device_claim_direct(iio)) { + ret =3D -EBUSY; + goto put_autosuspend; + } + + ret =3D regmap_bulk_read(data->regmap, addr, ®, sizeof(reg)); + iio_device_release_direct(iio); + if (ret < 0) + goto put_autosuspend; + + *val =3D le16_to_cpu(reg); + ret =3D IIO_VAL_INT; + +put_autosuspend: + pm_runtime_put_autosuspend(data->dev); + return ret; +} + +static int veml6031x00_read_raw(struct iio_dev *iio, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + return veml6031x00_single_read(iio, chan->type, val); + case IIO_CHAN_INFO_INT_TIME: + *val =3D 0; + return veml6031x00_get_it(data, val, val2); + case IIO_CHAN_INFO_SCALE: + return veml6031x00_get_scale(data, val, val2); + default: + return -EINVAL; + } +} + +static int veml6031x00_read_avail(struct iio_dev *iio, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + return iio_gts_avail_times(&data->gts, vals, type, length); + case IIO_CHAN_INFO_SCALE: + return iio_gts_all_avail_scales(&data->gts, vals, type, length); + } + + return -EINVAL; +} + +static int veml6031x00_write_raw(struct iio_dev *iio, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_INT_TIME: + return veml6031x00_set_it(iio, val, val2); + case IIO_CHAN_INFO_SCALE: + return veml6031x00_set_scale(iio, val, val2); + default: + return -EINVAL; + } +} + +static int veml6031x00_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_INT_TIME: + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int veml6031x00_set_interrupt(struct veml6031x00_data *data, bool s= tate) +{ + int ret; + + if (state) { + if (atomic_inc_return(&data->int_users) > 1) + return 0; + } else { + if (atomic_dec_return(&data->int_users) > 0) + return 0; + } + + ret =3D regmap_field_write(data->rf.int_en, state); + if (ret) { + if (state) + atomic_dec(&data->int_users); + else + atomic_inc(&data->int_users); + } + + return ret; +} + +static int veml6031x00_read_event_val(struct iio_dev *iio, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) +{ + switch (type) { + case IIO_EV_TYPE_THRESH: + if (dir =3D=3D IIO_EV_DIR_EITHER && info =3D=3D IIO_EV_INFO_PERIOD) + return veml6031x00_read_period(iio, val); + else + return veml6031x00_read_th(iio, val, val2, dir); + default: + return -EINVAL; + } +} + +static int veml6031x00_write_event_val(struct iio_dev *iio, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int val, int val2) +{ + switch (info) { + case IIO_EV_INFO_VALUE: + return veml6031x00_write_th(iio, val, val2, dir); + case IIO_EV_INFO_PERIOD: + return veml6031x00_write_period(iio, val); + default: + return -EINVAL; + } +} + +static int veml6031x00_read_event_config(struct iio_dev *iio, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + + guard(mutex)(&data->lock); + + return data->ev_en; +} + +static int veml6031x00_write_event_config(struct iio_dev *iio, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + bool state) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + int ret; + + scoped_guard(mutex, &data->lock) { + /* avoid multiple increments/decrements from one source */ + if (state =3D=3D data->ev_en) + return 0; + + ret =3D veml6031x00_set_interrupt(data, state); + if (ret) + return ret; + + data->ev_en =3D state; + } + + if (state) + return pm_runtime_resume_and_get(data->dev); + + pm_runtime_put_autosuspend(data->dev); + + return 0; +} + +static const struct iio_info veml6031x00_info =3D { + .read_raw =3D veml6031x00_read_raw, + .read_avail =3D veml6031x00_read_avail, + .write_raw =3D veml6031x00_write_raw, + .write_raw_get_fmt =3D veml6031x00_write_raw_get_fmt, + .read_event_value =3D veml6031x00_read_event_val, + .write_event_value =3D veml6031x00_write_event_val, + .read_event_config =3D veml6031x00_read_event_config, + .write_event_config =3D veml6031x00_write_event_config, + .event_attrs =3D &veml6031x00_event_attr_group, +}; + +static const struct iio_info veml6031x00_info_no_irq =3D { + .read_raw =3D veml6031x00_read_raw, + .read_avail =3D veml6031x00_read_avail, + .write_raw =3D veml6031x00_write_raw, + .write_raw_get_fmt =3D veml6031x00_write_raw_get_fmt, +}; + +/* AF_TRIG is reset by hardware, but the rest of the fields are persistent= */ +static int veml6031x00_set_af_trig(struct veml6031x00_data *data, bool sta= te) +{ + regcache_drop_region(data->regmap, VEML6031X00_REG_CONF0, + VEML6031X00_REG_CONF0); + + return regmap_update_bits(data->regmap, VEML6031X00_REG_CONF0, + VEML6031X00_CONF0_AF_TRIG, + FIELD_PREP(VEML6031X00_CONF0_AF_TRIG, state)); +} + +static irqreturn_t veml6031x00_interrupt(int irq, void *private) +{ + struct iio_dev *iio =3D private; + struct veml6031x00_data *data =3D iio_priv(iio); + s64 timestamp; + int ret, reg; + + ret =3D regmap_read(data->regmap, VEML6031X00_REG_INT, ®); + if (ret) { + dev_err(data->dev, + "Failed to read interrupt register %d\n", ret); + return IRQ_NONE; + } + + if (!(reg & VEML6031X00_INT_MASK)) + return IRQ_NONE; + + guard(mutex)(&data->lock); + + if ((reg & (VEML6031X00_INT_TH_H | VEML6031X00_INT_TH_L)) && data->ev_en)= { + timestamp =3D iio_get_time_ns(iio); + + if (reg & VEML6031X00_INT_TH_H) + iio_push_event(iio, IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + timestamp); + if (reg & VEML6031X00_INT_TH_L) + iio_push_event(iio, IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + timestamp); + } + + if ((reg & VEML6031X00_INT_DRDY) && data->trig_en) { + iio_trigger_poll_nested(data->trig); + ret =3D veml6031x00_set_af_trig(data, true); + if (ret) + dev_err(data->dev, "Failed to set trigger %d\n", ret); + } + + return IRQ_HANDLED; +} + +static int veml6031x00_buffer_preenable(struct iio_dev *iio) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + int ret, it_sec, it_usec; + + ret =3D pm_runtime_resume_and_get(data->dev); + if (ret) + return ret; + + ret =3D veml6031x00_get_it(data, &it_sec, &it_usec); + if (ret < 0) { + pm_runtime_put_autosuspend(data->dev); + return ret; + } + + /* + * Wait one integration period + 10% margin so the first triggered + * read does not race with the sensor completing its first conversion + * after power-on. + */ + fsleep((it_sec * MICRO) + it_usec + (it_usec / 10)); + + return 0; +} + +static int veml6031x00_buffer_postdisable(struct iio_dev *iio) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + struct device *dev =3D data->dev; + + pm_runtime_put_autosuspend(dev); + + return 0; +} + +static int veml6031x00_set_trigger_state(struct iio_trigger *trig, bool st= ate) +{ + struct iio_dev *iio =3D iio_trigger_get_drvdata(trig); + struct veml6031x00_data *data =3D iio_priv(iio); + int ret; + + scoped_guard(mutex, &data->lock) { + if (state =3D=3D data->trig_en) + return 0; + + ret =3D veml6031x00_set_interrupt(data, state); + if (ret) + return ret; + } + + /* The AF bit must be set before setting AF_TRIG */ + ret =3D regmap_update_bits(data->regmap, VEML6031X00_REG_CONF0, + VEML6031X00_CONF0_AF, + FIELD_PREP(VEML6031X00_CONF0_AF, state)); + if (ret) + goto err_disable_interrupt; + + ret =3D veml6031x00_set_af_trig(data, state); + if (ret) + goto err_clear_af; + + scoped_guard(mutex, &data->lock) + data->trig_en =3D state; + + return 0; + +err_clear_af: + regmap_update_bits(data->regmap, VEML6031X00_REG_CONF0, + VEML6031X00_CONF0_AF, + FIELD_PREP(VEML6031X00_CONF0_AF, !state)); +err_disable_interrupt: + veml6031x00_set_interrupt(data, !state); + return ret; +} + +static const struct iio_buffer_setup_ops veml6031x00_buffer_setup_ops =3D { + .preenable =3D veml6031x00_buffer_preenable, + .postdisable =3D veml6031x00_buffer_postdisable, +}; + +static const struct iio_trigger_ops veml6031x00_trigger_ops =3D { + .set_trigger_state =3D veml6031x00_set_trigger_state, +}; + +static irqreturn_t veml6031x00_trig_handler(int irq, void *p) +{ + struct iio_poll_func *pf =3D p; + struct iio_dev *iio =3D pf->indio_dev; + struct veml6031x00_data *data =3D iio_priv(iio); + int ch, ret, i =3D 0; + struct { + __le16 chans[2]; + aligned_s64 timestamp; + } scan; + + memset(&scan, 0, sizeof(scan)); + + if (*iio->active_scan_mask =3D=3D VEML6031X00_ALL_CH_MASK) { + ret =3D regmap_bulk_read(data->regmap, + VEML6031X00_REG_ALS_L, + &scan.chans, sizeof(scan.chans)); + if (ret) + goto done; + } else { + iio_for_each_active_channel(iio, ch) { + ret =3D regmap_bulk_read(data->regmap, + iio->channels[ch].address, + &scan.chans[i++], 2); + if (ret) + goto done; + } + } + + iio_push_to_buffers_with_timestamp(iio, &scan, pf->timestamp); + +done: + iio_trigger_notify_done(iio->trig); + + return IRQ_HANDLED; +} + +static int veml6031x00_validate_part_id(struct veml6031x00_data *data) +{ + int part_id, ret; + __le16 reg; + + ret =3D regmap_bulk_read(data->regmap, VEML6031X00_REG_ID_L, ®, + sizeof(reg)); + if (ret) + return dev_err_probe(data->dev, ret, "Failed to read ID\n"); + + part_id =3D le16_to_cpu(reg); + if (part_id !=3D data->chip->part_id) + dev_warn(data->dev, "Unknown ID %04x\n", part_id); + + return 0; +} + +static int veml6031x00_hw_init(struct iio_dev *iio) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + struct device *dev =3D data->dev; + int ret, val; + __le16 reg; + + /* Max resolution =3D 6.9632 lx/cnt for gain =3D 0.125 and IT =3D 3.125ms= */ + ret =3D devm_iio_init_iio_gts(data->dev, 6, 963200000, + veml6031x00_gain_sel, + ARRAY_SIZE(veml6031x00_gain_sel), + veml6031x00_it_sel, + ARRAY_SIZE(veml6031x00_it_sel), + &data->gts); + if (ret) + return dev_err_probe(data->dev, ret, "failed to init iio gts\n"); + + reg =3D 0; + ret =3D regmap_bulk_write(data->regmap, VEML6031X00_REG_WL_L, ®, + sizeof(reg)); + if (ret) + return dev_err_probe(dev, ret, "Failed to set low threshold\n"); + + reg =3D cpu_to_le16(U16_MAX); + ret =3D regmap_bulk_write(data->regmap, VEML6031X00_REG_WH_L, ®, + sizeof(reg)); + if (ret) + return dev_err_probe(dev, ret, "Failed to set high threshold\n"); + + ret =3D regmap_field_write(data->rf.int_en, 0); + if (ret < 0) + return ret; + + ret =3D regmap_read(data->regmap, VEML6031X00_REG_INT, &val); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to clear interrupts\n"); + + return 0; +} + +static int veml6031x00_setup_irq(struct i2c_client *i2c, struct iio_dev *i= io) +{ + struct veml6031x00_data *data =3D iio_priv(iio); + struct device *dev =3D data->dev; + int ret; + + data->trig =3D devm_iio_trigger_alloc(dev, "%s-drdy%d", iio->name, + iio_device_id(iio)); + if (!data->trig) + return -ENOMEM; + + data->trig->ops =3D &veml6031x00_trigger_ops; + iio_trigger_set_drvdata(data->trig, iio); + + ret =3D devm_iio_trigger_register(dev, data->trig); + if (ret) + return ret; + + iio->trig =3D iio_trigger_get(data->trig); + ret =3D devm_request_threaded_irq(dev, i2c->irq, NULL, + veml6031x00_interrupt, + IRQF_ONESHOT, + iio->name, iio); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to request irq %d\n", + i2c->irq); + + iio->info =3D &veml6031x00_info; + + return 0; +} + +static int veml6031x00_probe(struct i2c_client *i2c) +{ + struct device *dev =3D &i2c->dev; + struct veml6031x00_data *data; + struct iio_dev *iio; + struct regmap *regmap; + int ret; + + regmap =3D devm_regmap_init_i2c(i2c, &veml6031x00_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to set regmap\n"); + + iio =3D devm_iio_device_alloc(dev, sizeof(*data)); + if (!iio) + return -ENOMEM; + + data =3D iio_priv(iio); + i2c_set_clientdata(i2c, iio); + data->dev =3D dev; + data->regmap =3D regmap; + + ret =3D devm_mutex_init(dev, &data->lock); + if (ret) + return ret; + + ret =3D veml6031x00_regfield_init(data); + if (ret) + return dev_err_probe(dev, ret, "Failed to init regfield\n"); + + ret =3D devm_regulator_get_enable(dev, "vdd"); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable regulator\n"); + + data->chip =3D i2c_get_match_data(i2c); + if (!data->chip) + return dev_err_probe(dev, -EINVAL, "Failed to get chip data\n"); + + ret =3D devm_add_action_or_reset(dev, veml6031x00_als_shutdown_action, da= ta); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to add shutdown action\n"); + + ret =3D pm_runtime_set_active(dev); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to activate PM runtime\n"); + + ret =3D devm_pm_runtime_enable(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable PM runtime\n"); + + pm_runtime_get_noresume(dev); + pm_runtime_set_autosuspend_delay(dev, VEML6031X00_AUTOSUSPEND_MS); + pm_runtime_use_autosuspend(dev); + + ret =3D veml6031x00_validate_part_id(data); + if (ret) + return ret; + + iio->name =3D data->chip->name; + iio->channels =3D veml6031x00_channels; + iio->num_channels =3D ARRAY_SIZE(veml6031x00_channels); + iio->modes =3D INDIO_DIRECT_MODE; + + if (i2c->irq) { + ret =3D veml6031x00_setup_irq(i2c, iio); + if (ret < 0) + return ret; + } else { + iio->info =3D &veml6031x00_info_no_irq; + } + + ret =3D veml6031x00_hw_init(iio); + if (ret < 0) + return ret; + + ret =3D devm_iio_triggered_buffer_setup(dev, iio, NULL, + veml6031x00_trig_handler, + &veml6031x00_buffer_setup_ops); + if (ret) + return dev_err_probe(dev, ret, + "Failed to register triggered buffer\n"); + + pm_runtime_put_autosuspend(dev); + + ret =3D devm_iio_device_register(dev, iio); + if (ret) + return dev_err_probe(dev, ret, "Failed to register iio device\n"); + + return 0; +} + +static int veml6031x00_runtime_suspend(struct device *dev) +{ + struct veml6031x00_data *data =3D iio_priv(dev_get_drvdata(dev)); + + return veml6031x00_als_shutdown(data); +} + +static int veml6031x00_runtime_resume(struct device *dev) +{ + struct veml6031x00_data *data =3D iio_priv(dev_get_drvdata(dev)); + + return veml6031x00_als_power_on(data); +} + +static DEFINE_RUNTIME_DEV_PM_OPS(veml6031x00_pm_ops, veml6031x00_runtime_s= uspend, + veml6031x00_runtime_resume, NULL); + +static const struct veml6031x00_chip veml6031x00_chip =3D { + .name =3D "veml6031x00", + .part_id =3D 0x0001, +}; + +static const struct veml6031x00_chip veml6031x01_chip =3D { + .name =3D "veml6031x01", + .part_id =3D 0x0001, +}; + +static const struct veml6031x00_chip veml60311x00_chip =3D { + .name =3D "veml60311x00", + .part_id =3D 0x1001, +}; + +static const struct veml6031x00_chip veml60311x01_chip =3D { + .name =3D "veml60311x01", + .part_id =3D 0x1001, +}; + +static const struct of_device_id veml6031x00_of_match[] =3D { + { + .compatible =3D "vishay,veml6031x00", + .data =3D &veml6031x00_chip, + }, + { + .compatible =3D "vishay,veml6031x01", + .data =3D &veml6031x01_chip, + }, + { + .compatible =3D "vishay,veml60311x00", + .data =3D &veml60311x00_chip, + }, + { + .compatible =3D "vishay,veml60311x01", + .data =3D &veml60311x01_chip, + }, + { } +}; +MODULE_DEVICE_TABLE(of, veml6031x00_of_match); + +static const struct i2c_device_id veml6031x00_id[] =3D { + { "veml6031x00", (kernel_ulong_t)&veml6031x00_chip }, + { "veml6031x01", (kernel_ulong_t)&veml6031x01_chip }, + { "veml60311x00", (kernel_ulong_t)&veml60311x00_chip }, + { "veml60311x01", (kernel_ulong_t)&veml60311x01_chip }, + { } +}; +MODULE_DEVICE_TABLE(i2c, veml6031x00_id); + +static struct i2c_driver veml6031x00_driver =3D { + .driver =3D { + .name =3D "veml6031x00", + .of_match_table =3D veml6031x00_of_match, + .pm =3D pm_ptr(&veml6031x00_pm_ops), + }, + .probe =3D veml6031x00_probe, + .id_table =3D veml6031x00_id, +}; +module_i2c_driver(veml6031x00_driver); + +MODULE_AUTHOR("Javier Carrasco "); +MODULE_DESCRIPTION("VEML6031X00 Ambient Light Sensor"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_GTS_HELPER"); --=20 2.43.0