From nobody Sun Jun 14 04:09:15 2026 Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) (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 8C81D366553 for ; Sun, 3 May 2026 16:44:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826701; cv=none; b=r9z0uihAo4Wm4iS0J8P573LfmGAoKlv1yIZA3w8ONwR8Tu5c+O4yVuyjETAZl7HEHpnvVq9ADzFnoMU3vpXAgj+CFCgwTxtcE7kl9QMDBC8nYxIVxZa6dnTUE/uqOF4ALq8SWSTpyF/4ZLryQATukVP/Kq9awqhwvB64sec4+rw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826701; c=relaxed/simple; bh=We6F5WQggj2X+707QRLSrq42JZKnZW3sTqiE8bDQHj0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=upkYUU1VoxV+MRKDdHl6k+UoPzsrZ4ElhFgfhvtjSIE4sYXEMVXrPdypphWxmB/jpef66rQJHJ38abp78mSSDb3VHQyQsQQCA9uIOxJiQ+bC2B5WoRp0uAca38UY3rSzBYXLXONJqhWTJXEMixWGHkYHznKkNbbb7hGw5sPfw2A= 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=d+fMtf8x; arc=none smtp.client-ip=209.85.218.50 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="d+fMtf8x" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-bc1f0f48351so46714166b.1 for ; Sun, 03 May 2026 09:44:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777826698; x=1778431498; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=WQAiHiX6KTDh/ntQ/qXMLOirhMuLN1OliVdEMKPofM0=; b=d+fMtf8xuuxOUb7Gfe7t5cDzXcA2E5Ylrv1XdwzVV6vQSK668JapZED7gLWCoLKdNf 6pqXy2lh+FlyQEWrv5yUlUyQC+n/n/Qoxss0aA7W/pNBGG4pEBTCEKXXTmdhd3j6lVAp DfFgDX4+MMq9OOOEsStUFB4Cfx7eWzYJ/vZfn0WrDWOWEiKbpaVV3OPeWaJVbOWnqom9 5YFRMiUAWYPNdtjSTpR8n6X2xFEJGvzhGIhCvMdP4Q8w9GN7sV/s8bjHV8vzj4sYpD+P RluhHLjWdF1NS5YFJUx7abedWPQxqnhAY3VaCEAXWkuF69a19bACZcGJDoFSjWYpt28v Y/NA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777826698; x=1778431498; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=WQAiHiX6KTDh/ntQ/qXMLOirhMuLN1OliVdEMKPofM0=; b=lpe2TvCvStj1TXOIESOMlYFDF0AdsA8zZzCKIgvlAVE5/e6iX+spVNIUnjUVxN1S+W Ny6fYq12H4JiZJB+gmVrey8pDB7NuCHxTt2FrMGZeVRu61TDmnn5HSGHaZncI9FAiEyA 28flJyeMa/HLAI6BViXayWYotTh4ykmZXkU6bc7XW7HTu0a2h9r/MbxyUi5IGsKYa/uL JcN2pdPccOgEdmXYUg3Xwavd0fjV32wWgN9J2R0dEZa9opdcMkqKMyuaJDZez9JAMn/u wgSnM6tiiGUgkUZxYeWyWbU3oA9B/KWC1zFOgis8KkepZtiolqiiN9H05yKLWN3aLAq6 aZkQ== X-Forwarded-Encrypted: i=1; AFNElJ+QH0GaWfnfBU/YZZ2yERw+sz+d58fItv0SyYbfmwcOTxTxwOvTSydzejfyZbSDCL6LvRSXhPzPwCfNi4c=@vger.kernel.org X-Gm-Message-State: AOJu0YwvfFlATJJfNiCen9tiYnbutlcDoDyzoTHrOGuYmQsAANNVgxzu ej+s8RmbguWQ0oC2WCX33da/VTpmluX7PSzHLWtQ1tXa4pCNUqXOFZm/ X-Gm-Gg: AeBDievlQsV4wlcYKEhgx1plTb+lnwZqDasXbGKfXAhpbJ0Z5xnm+zwCAARLbQ8nlTU VUTJL0cKlJgnUOjn0+vFH6EV4BB6LOdUEUSPmGiMyCjDOMHjoxSbWcs0f55u8ln6MXeP4zGWT+K gOe+aLqynQt0m3tnyVtEpAqeDhCYYdMmf2XBNtdb/LJAxmjSfSjDyDDNq80uWmmZSfYFk5A5Rhl p4SG0g56DHiY46TJp7T9hXgjWO77bFvjnhWt4+bcFRqgsBpiV7+3scCLiQwSKc8LKILbqclpZWD nVfDo7sXRDmGtcvODfnDDRXNo1vLNJoGQGfshCWfER3eR9INeZwOcKMcIU+M9viBeykospasBr7 7o8ngeRp3EzO/VAoAP/ZvtUJ3rFyQclnNDUKhU4xIRHv7RDrBMUVWlXNC7agUBZ5F5W8Zbe2his 8GO1cQivy8bcSFJS1uVRscojM= X-Received: by 2002:a17:907:2dab:b0:bc2:1f0e:3fab with SMTP id a640c23a62f3a-bc21f0e404bmr57267266b.24.1777826697714; Sun, 03 May 2026 09:44:57 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bc237ef8297sm27430566b.57.2026.05.03.09.44.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 09:44:57 -0700 (PDT) From: Svyatoslav Ryhel To: Lee Jones , Pavel Machek , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Sakari Ailus , Mauro Carvalho Chehab , Svyatoslav Ryhel Cc: linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH v5 1/6] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver Date: Sun, 3 May 2026 19:44:40 +0300 Message-ID: <20260503164445.215540-2-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260503164445.215540-1-clamor95@gmail.com> References: <20260503164445.215540-1-clamor95@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Document TI LM3559 and LM3560 Synchronous Boost Flash Driver used for camera flash LEDs. Signed-off-by: Svyatoslav Ryhel --- .../devicetree/bindings/leds/ti,lm3560.yaml | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/ti,lm3560.yaml diff --git a/Documentation/devicetree/bindings/leds/ti,lm3560.yaml b/Docume= ntation/devicetree/bindings/leds/ti,lm3560.yaml new file mode 100644 index 000000000000..e79de4a57f83 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/ti,lm3560.yaml @@ -0,0 +1,163 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/ti,lm3560.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI LM3560 Synchronous Boost Flash Driver + +maintainers: + - Svyatoslav Ryhel + +description: + The LM3560 is a 2-MHz fixed frequency synchronous boost converter with t= wo + 1000-mA constant current drivers for high-current white LEDs. The dual h= igh- + side current sources allow for grounded cathode LED operation and can be + tied together for providing flash currents at up to 2 A through a single= LED. + An adaptive regulation method ensures the current for each LED remains in + regulation and maximizes efficiency. + +properties: + compatible: + enum: + - ti,lm3559 + - ti,lm3560 + + reg: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + enable-gpios: + description: GPIO connected to the HWEN pin. + maxItems: 1 + + vin-supply: + description: Supply connected to the IN line. + + flash-max-timeout-us: + minimum: 32000 + maximum: 1024000 + default: 32000 + + ti,peak-current-microamp: + description: + The LM3560 features 4 selectable current limits 1.6A, 2.3A, 3A, and = 3.6A + (in case of LM3559 - 1.4A, 2.1A, 2.7A, and 3.2A). When the current l= imit + is reached, the LM3559/LM3560 stops switching for the remainder of t= he + switching cycle. + +patternProperties: + '^led@[01]$': + type: object + $ref: /schemas/leds/common.yaml# + description: LED control bank nodes. + unevaluatedProperties: false + + properties: + reg: + description: Control bank selection (0 =3D bank A, 1 =3D bank B). + maximum: 1 + + required: + - reg + - flash-max-microamp + - led-max-microamp + +allOf: + - $ref: /schemas/leds/common.yaml# + - if: + properties: + compatible: + contains: + const: ti,lm3559 + then: + properties: + ti,peak-current-microamp: + enum: [1400000, 2100000, 2700000, 3200000] + default: 1400000 + patternProperties: + '^led@[01]$': + properties: + flash-max-microamp: + minimum: 62500 + maximum: 1000000 + led-max-microamp: + minimum: 31250 + maximum: 250000 + + - if: + properties: + compatible: + contains: + const: ti,lm3560 + then: + properties: + ti,peak-current-microamp: + enum: [1600000, 2300000, 3000000, 3600000] + default: 1600000 + patternProperties: + '^led@[01]$': + properties: + flash-max-microamp: + minimum: 56250 + maximum: 900000 + led-max-microamp: + minimum: 28125 + maximum: 225000 + +required: + - compatible + - reg + - '#address-cells' + - '#size-cells' + +additionalProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + led-controller@53 { + compatible =3D "ti,lm3560"; + reg =3D <0x53>; + + enable-gpios =3D <&gpio 28 GPIO_ACTIVE_HIGH>; + vin-supply =3D <&vdd_3v3_sys>; + + flash-max-timeout-us =3D <1024000>; + ti,peak-current-microamp =3D <1600000>; + + #address-cells =3D <1>; + #size-cells =3D <0>; + + led@0 { + reg =3D <0>; + + function =3D LED_FUNCTION_FLASH; + color =3D ; + + flash-max-microamp =3D <562500>; + led-max-microamp =3D <156250>; + }; + + led@1 { + reg =3D <1>; + + function =3D LED_FUNCTION_FLASH; + color =3D ; + + flash-max-microamp =3D <562500>; + led-max-microamp =3D <156250>; + }; + }; + }; --=20 2.51.0 From nobody Sun Jun 14 04:09:15 2026 Received: from mail-ed1-f53.google.com (mail-ed1-f53.google.com [209.85.208.53]) (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 7A2E4378D64 for ; Sun, 3 May 2026 16:45:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826702; cv=none; b=fEGcN6acgiKakK0bvIHqovYxv44TgcBiQOS9F+AjK5rcnv9ognwYznEF305fILKtx4VQwpcaFeisu8hFJ80GFyZg31skKbSyhO1gtHFCTfS03a42KCk3dcgcW6hrCX5P6BbclwIEtDH9HqeJ4CUst4uJ8rrhw9uyc7wTLfe/Cj8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826702; c=relaxed/simple; bh=/aTZ7FfNJUxGAerV0GyNvRYzlJf90me3mmU4zDgewOs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Sv/7glcEcj+xRPnuaMvxM1p1M80o0VeuanD+vr9wUO36sVRWK3BSSf8adFKc6T4w30HP6ZvcpUTZSmSGiRF4VNMr+UnbPdl1oE8zUKU8YDUva/NVWZpAIUEZ0Um5NcG7iWPU2rcsaL8pHdSTtvEPawXGECoPyuDHa/KyALODASg= 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=HPHX4tN6; arc=none smtp.client-ip=209.85.208.53 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="HPHX4tN6" Received: by mail-ed1-f53.google.com with SMTP id 4fb4d7f45d1cf-67c1e0229acso1562900a12.1 for ; Sun, 03 May 2026 09:45:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777826699; x=1778431499; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qqEpiDmgYxnJFJBZV5oyq8iX4ijdqmclDgeEbjUzvZU=; b=HPHX4tN6pvOtLFDE8vxYilTNjL4kyEPNuJ5YNSx0FG8Y9ArrtjSsmw1ntDJFrMtRkq juMCYBXOA/Zos9GUcZac0QC4hfOThUnqc0KHaRuIQnL1Gd5rwxsEQO23RD+SaymF/OSf 2tqXZhwNrpZvHHCrjCd+MzQ1wlAUkWAsWqTuRFw+/GtTQ8AhbXbyEw45RHh+HPsVyVYv 3s1Tziin/HKa726vlzP9+ljJofrAVWZOZinB18nYqr6Udr8usFXxdh7fQ5RLq97U2uOF lorIO4dIqf2BJ6RhCaT5swb2eOSyIBYPbe6B8tTzrbi1uvK+1cvzX69Vej6WXjP1DSnd FbOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777826699; x=1778431499; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=qqEpiDmgYxnJFJBZV5oyq8iX4ijdqmclDgeEbjUzvZU=; b=e0S9Xw5QSPSwth0Omgy8MGcaGuADT50a8Att5CHyDaag1H7ReriOJV/trxOUSx2J0D x8IzNLbkjn6ki4BQ3Se146UnVj36+1VIBYT214PTDY/OPUZ20fR3Tt9mF/Myx/r8XMIe W777JyNJhdMqiLNFQogpIHhj/3IN1vEloGqK1v9x9zq9I3XMAfOG+1KWe+8MfmDBsYfO +s9og7VN8L0IA56bakBcVQkBwUYWOO59ha3v+nZdsMjddezxwGtXWZWuNYk+aYJPBLyn YCT2TMOaK55ybZMYt2PVuBwSFJEpoqySwMxCLTFVDwAGdwRl/yi+Nr0gILsPL25Lxnsv dgyQ== X-Forwarded-Encrypted: i=1; AFNElJ/3Sum9z7VPcMOEwupMRMsDrWnhb6GpjR729QCfYdO6E9J0sL9SgACk7TpF+wq8dM5lvCKJ8SdUmA7ooD8=@vger.kernel.org X-Gm-Message-State: AOJu0Yx84W2ioxQjZSD9QD3Bwl5asxxWl/KwheCmRCdhoCCz7gB28p+L xSCKQgW9b0+uQaFdPll3Vso5QwQS9TWg9EQOihI1gPUeIT/FwQpiYqbO X-Gm-Gg: AeBDiev1cs37HyjfUpxyOMt1P4m3rEafUx2da3vuH2uSYk1ZF/Okt5f3+vKVRWxVA34 pohzjkI5Ra5zhGZga5LcBB7Pu3wVNqyS11sJ5Wnb4BOv3QAjsH7l+JBI9+ZyeCP5EgyLbHDeom0 zTfqEVf/OESXVhk7Lbq95Yd/qn+au9t7595padblHuW7Co/MW5Qq4GDiASkoHH+Rp5cPekKaNSA 66t1v0Oi+B62CMZJEXR9fsAcvgbOrLnN8e1fbgCul3RjIBGVgBR71A2rYfERkZAOXKc7FfVlOsJ gu47LFFuG/d5EvIdAHgs8oAhBYcTEQQOPd1ZelBbQbgcFCl0JLOSfSFB9/ZA2aLBkSX3jCDRxxQ 60JSjcpYOVSnGqgmkDHVzRk3GTgznWuyE9Kk/SmdfgkbJpAEqShArAVPqgyCeSTrHfhPkBM2pRv VQ3EG9bOKNOq/YjEhhSqH8CHU= X-Received: by 2002:a17:907:9455:b0:b9c:9594:e00 with SMTP id a640c23a62f3a-bbff9e28c78mr324860966b.1.1777826698801; Sun, 03 May 2026 09:44:58 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bc237ef8297sm27430566b.57.2026.05.03.09.44.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 09:44:58 -0700 (PDT) From: Svyatoslav Ryhel To: Lee Jones , Pavel Machek , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Sakari Ailus , Mauro Carvalho Chehab , Svyatoslav Ryhel Cc: linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH v5 2/6] media: i2c: lm3560: Fix v4l2 subdev registration Date: Sun, 3 May 2026 19:44:41 +0300 Message-ID: <20260503164445.215540-3-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260503164445.215540-1-clamor95@gmail.com> References: <20260503164445.215540-1-clamor95@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The existing driver does not call media subdev registration, making it invisible to the media framework. Since the LM3560 supports two independent LEDs, register each LED as a separate media entity. Because registering LEDs before device initialization may cause access attempts before the hardware is ready, lm3560_init_device has been moved before the subdevice initializations. An additional helper, lm3560_subdev_cleanup, was added to release LED0 if the initialization of LED1 fails, and to deregister both LEDs in the remove function. Signed-off-by: Svyatoslav Ryhel --- drivers/media/i2c/lm3560.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index f4cc844f4e3c..edfb07587cab 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -364,8 +364,15 @@ static int lm3560_subdev_init(struct lm3560_flash *fla= sh, goto err_out; flash->subdev_led[led_no].entity.function =3D MEDIA_ENT_F_FLASH; =20 - return rval; + rval =3D v4l2_async_register_subdev(&flash->subdev_led[led_no]); + if (rval < 0) { + dev_err(flash->dev, "failed to register V4L2 subdev"); + goto error_out_media; + } =20 + return rval; +error_out_media: + media_entity_cleanup(&flash->subdev_led[led_no].entity); err_out: v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]); return rval; @@ -391,6 +398,14 @@ static int lm3560_init_device(struct lm3560_flash *fla= sh) return rval; } =20 +static void lm3560_subdev_cleanup(struct lm3560_flash *flash, + enum lm3560_led_id led_no) +{ + v4l2_async_unregister_subdev(&flash->subdev_led[led_no]); + v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]); + media_entity_cleanup(&flash->subdev_led[led_no].entity); +} + static int lm3560_probe(struct i2c_client *client) { struct lm3560_flash *flash; @@ -425,17 +440,19 @@ static int lm3560_probe(struct i2c_client *client) flash->dev =3D &client->dev; mutex_init(&flash->lock); =20 - rval =3D lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0"); + rval =3D lm3560_init_device(flash); if (rval < 0) return rval; =20 - rval =3D lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1"); + rval =3D lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0"); if (rval < 0) return rval; =20 - rval =3D lm3560_init_device(flash); - if (rval < 0) + rval =3D lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1"); + if (rval < 0) { + lm3560_subdev_cleanup(flash, LM3560_LED0); return rval; + } =20 i2c_set_clientdata(client, flash); =20 @@ -447,11 +464,8 @@ static void lm3560_remove(struct i2c_client *client) struct lm3560_flash *flash =3D i2c_get_clientdata(client); unsigned int i; =20 - for (i =3D LM3560_LED0; i < LM3560_LED_MAX; i++) { - v4l2_device_unregister_subdev(&flash->subdev_led[i]); - v4l2_ctrl_handler_free(&flash->ctrls_led[i]); - media_entity_cleanup(&flash->subdev_led[i].entity); - } + for (i =3D LM3560_LED0; i < LM3560_LED_MAX; i++) + lm3560_subdev_cleanup(flash, i); } =20 static const struct i2c_device_id lm3560_id_table[] =3D { --=20 2.51.0 From nobody Sun Jun 14 04:09:15 2026 Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.51]) (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 85455377017 for ; Sun, 3 May 2026 16:45:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826705; cv=none; b=OtVr4k05/p8F2OK3DiXVhLv5kllE9JGlDwIKMp9TW5VJ2oB+RIOMa320zLmGr9AQTAUXfYGkVzIeFacP5l9L7ZaAuFD+JdUc342U41YjVsqXIR3HK3hHeTk0Le6Y7gYZIclcjn5lvwHccMqfR9c+/SByjS0yDb0EqIC4J47Pxwo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826705; c=relaxed/simple; bh=LRXlNS9x02z8g+CGxmATU/6gvHvDK0YuBVqtECCU2ME=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i7LLWLCrcNWt0Gmo5aY/LCnTmABx6ZlJfDPgNvnSCvI8EIYL21jZqxbiGJ8h4/8JS1UekMkyeJ66Ni8xS/DVOIgK9Cm+OhemmO318W2lBfCqg+4746hPDXQL7luqzuhJ2z3Epzlx+b067kMZXd5sQAMZB/sIu5//e+/LXAm9bQg= 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=OOQJq025; arc=none smtp.client-ip=209.85.218.51 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="OOQJq025" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-bbe539fc355so273355966b.2 for ; Sun, 03 May 2026 09:45:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777826701; x=1778431501; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2KGU01Qq2W7EXZE5uDuHFOzhjoXBSa5CoF8m94VBiMo=; b=OOQJq025zP22Fc7s20qoPylJWHgRBwlbxBySVpn+FzjwdqMH9bk+vq83xwjYbvImtj mNmil/SjoqdgCv97K7ZMWVAXQ9fPYeaDB3BlnfGyQ5DD7ZIqdGnSAdIKaIfp3azyUj7u MnVMArB9a6mDhiCeI/R+oGjfROe6bFO85HQNtyHxhn6bTXId+DAFqGY605ql63tJko0L tRKeECTiPBFEOZPtfg1Gz4Sw6SxN+f3P9eRu/2rbT/Mq8J1uoTbPiOOEjNyzfRw+km+s J7PS518sm+INx4jcAfPAB5mwVjaiO3Pl+IKT8jDwcAuDWvfTa/GS22b1Sg2l9CGBzFst BINg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777826701; x=1778431501; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=2KGU01Qq2W7EXZE5uDuHFOzhjoXBSa5CoF8m94VBiMo=; b=iZEBX1ifejOB9wIOxsxi3WRXSFJ8les8kfcaOXWG8k6UDl/XauEIgAeuz5mxh86CQC /F2t51+VjwskSHeW7RCJVyVrOOjUUViTEr74Zj1oe0UvEWzaQzJrdk22YsVNk6eq/vJK lnUZCWlgEkHGoOoAeNok6D+m0aQ01plvGUxCDxAjDJCkAYScdmHP9gSkr/OGhNocICXT vdBzsxKnXLRQXTGM5n5meFAlj65oM0yfM9cZwGOaKRuK1vxytEZZUf/c8yuZ4U7cYCTt r0NuFJc91ghNhQ/02X9FK4KJgKyMvylqEcneds6amdwXpxJePEA6kiAc4B2g2gE0xS5V 8jYg== X-Forwarded-Encrypted: i=1; AFNElJ9jInKgsE53Xp0QhdCRW1mGMLm12sk1DnglmhVvYYhna+41J+ctvCks4+gPCH+EeJndH+AP19P0mQAt+Wk=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4+0ujmGWbcpKEm0PxG+20EUo/TdS4x0r+QkrT+vQP3t9K19op GlUp6dlrlAh4sGAcBAFqWqMKf08Szs/Fmg5EocRRnv5P3gz9tGYXvbK3 X-Gm-Gg: AeBDievcWxnwggWnqINEAkCCil6zUmmMZ4FK68bSDYNXNGTcPCEV/0IUJ99XWTsqJgQ YZUc/g94sP98Ngu3b8nabGzdRFuARFpEiFEYirovnECE0mcXDRQsUzZQrGfFj62/klOM4fHyy3s 4TY6vlu07umYigsofUlrk9LIaX4+iirF4g9w0NHL55WvKUnHk5H2b3C6oG1sQNC+66c0ktvz+7y R93gb4L4RzJeSmLCiqWapNLKQrFsMojvX30PY/w3kwb2lLXSe+pEWaiMzxrULfJGXp7Vy4wgoYV LpwKpk9aayNGjX7t2+gHA/Vclc0uoQ/D8QfN7a9BBRR7D82qEEj1dweCcunGY6OsXjs1OVHKUUg nZo3q4VKFsHpxRcxVo7zYXr1HEJ1IWQMN66IHZtIveZjMvxR5hgzpoqSdas/eNt5QiJx/g46hxJ qfahCWpGqmTox/a8vIpW7kDMA= X-Received: by 2002:a17:906:2083:b0:ba9:559:10c8 with SMTP id a640c23a62f3a-bbffbf85acdmr212670666b.41.1777826700933; Sun, 03 May 2026 09:45:00 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bc237ef8297sm27430566b.57.2026.05.03.09.44.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 09:45:00 -0700 (PDT) From: Svyatoslav Ryhel To: Lee Jones , Pavel Machek , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Sakari Ailus , Mauro Carvalho Chehab , Svyatoslav Ryhel Cc: linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH v5 3/6] media: i2c: lm3560: Optimize mutex lock usage Date: Sun, 3 May 2026 19:44:42 +0300 Message-ID: <20260503164445.215540-4-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260503164445.215540-1-clamor95@gmail.com> References: <20260503164445.215540-1-clamor95@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Pass the device's own mutex lock to the control handler so that the media framework can handle control access instead of managing it manually. The lock must be common to both sub-devices since they share same hardware, so the individual sub-device locks will not work here. Signed-off-by: Svyatoslav Ryhel --- drivers/media/i2c/lm3560.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index edfb07587cab..5b568ed9536b 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -162,14 +162,12 @@ static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, en= um lm3560_led_id led_no) struct lm3560_flash *flash =3D to_lm3560_flash(ctrl, led_no); int rval =3D -EINVAL; =20 - mutex_lock(&flash->lock); - if (ctrl->id =3D=3D V4L2_CID_FLASH_FAULT) { s32 fault =3D 0; unsigned int reg_val; rval =3D regmap_read(flash->regmap, REG_FLAG, ®_val); if (rval < 0) - goto out; + return rval; if (reg_val & FAULT_SHORT_CIRCUIT) fault |=3D V4L2_FLASH_FAULT_SHORT_CIRCUIT; if (reg_val & FAULT_OVERTEMP) @@ -179,8 +177,6 @@ static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum= lm3560_led_id led_no) ctrl->cur.val =3D fault; } =20 -out: - mutex_unlock(&flash->lock); return rval; } =20 @@ -190,8 +186,6 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum= lm3560_led_id led_no) u8 tout_bits; int rval =3D -EINVAL; =20 - mutex_lock(&flash->lock); - switch (ctrl->id) { case V4L2_CID_FLASH_LED_MODE: flash->led_mode =3D ctrl->val; @@ -202,14 +196,12 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, en= um lm3560_led_id led_no) case V4L2_CID_FLASH_STROBE_SOURCE: rval =3D regmap_update_bits(flash->regmap, REG_CONFIG1, 0x04, (ctrl->val) << 2); - if (rval < 0) - goto err_out; break; =20 case V4L2_CID_FLASH_STROBE: if (flash->led_mode !=3D V4L2_FLASH_LED_MODE_FLASH) { rval =3D -EBUSY; - goto err_out; + break; } flash->led_mode =3D V4L2_FLASH_LED_MODE_FLASH; rval =3D lm3560_mode_ctrl(flash); @@ -218,7 +210,7 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum= lm3560_led_id led_no) case V4L2_CID_FLASH_STROBE_STOP: if (flash->led_mode !=3D V4L2_FLASH_LED_MODE_FLASH) { rval =3D -EBUSY; - goto err_out; + break; } flash->led_mode =3D V4L2_FLASH_LED_MODE_NONE; rval =3D lm3560_mode_ctrl(flash); @@ -239,8 +231,6 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum= lm3560_led_id led_no) break; } =20 -err_out: - mutex_unlock(&flash->lock); return rval; } =20 @@ -328,6 +318,8 @@ static int lm3560_init_controls(struct lm3560_flash *fl= ash, if (fault !=3D NULL) fault->flags |=3D V4L2_CTRL_FLAG_VOLATILE; =20 + hdl->lock =3D &flash->lock; + if (hdl->error) return hdl->error; =20 @@ -363,6 +355,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flas= h, if (rval < 0) goto err_out; flash->subdev_led[led_no].entity.function =3D MEDIA_ENT_F_FLASH; + flash->subdev_led[led_no].state_lock =3D &flash->lock; =20 rval =3D v4l2_async_register_subdev(&flash->subdev_led[led_no]); if (rval < 0) { --=20 2.51.0 From nobody Sun Jun 14 04:09:15 2026 Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) (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 1102437F73E for ; Sun, 3 May 2026 16:45:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826717; cv=none; b=gmw8ce7a6T+suWUzEfKAlEMzpI3P78XyWmo2xaeZ68O5T0QbFveO/TtVyhYOjdMsjyb3R0tJWaokRj3FEMDxMvneaSGN20oSN4KAVhrXHl+TPKUE9Mohp4fXDVmS6b/h0DFYo+pO2wM+kz1TfpJN6zS3Xmg8OUCstXo9UJSE7Mg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826717; c=relaxed/simple; bh=i6Hj7U3fS4BqtoSibzAuYpq/vb5ugPkQKLtH35zOVx4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YQJEDrCCzBihyRGopEA7eBCQc4WdJopaE9oBh3N6DrOc849jt1fT/Jv/ezOYGvEDN50SjN9I77T7nUbVGVEu6X+ChJrF3WFSjk2CmkaIPHbxOa9Lgi/sHPD6ynl89UP55KN34VfUI0K64O1TJEXXDGvaDhyti3YIR9zpm7qgSN4= 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=EyR0hsTk; arc=none smtp.client-ip=209.85.218.47 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="EyR0hsTk" Received: by mail-ej1-f47.google.com with SMTP id a640c23a62f3a-bc264a50e7fso15914066b.0 for ; Sun, 03 May 2026 09:45:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777826703; x=1778431503; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=EtUh5EYJwmKXAER6m4XzUWsXnZUgq5RskppIOaQaosQ=; b=EyR0hsTkLyWd7nU7PyjOg6itw5Ms/Z/FdATDPgt8K9JeMkN68sfxeYOqYr0BxSoxpm 5CcOetlS7NL+y8PT6Bs3+557dGORNNNv24duxoI73u/3oA5TkWRZ1Ejp08loI2Hri1KO D+YpROV/A9S9F8Jge8VOwk+s5RgGWU8VT1K65x05bpoz+VV7o7Pk1xKrRo6QPjWPn2Jc 1ss2PsSXC+A0uR3CKT2tyioe2n1UXfqdCWPAXNyySy+OyMGLN6IX1oBFJ3vi2/eZh4Oc 8LI2Gyo8uMdXrzUrHmYsALznWiliSJETMgcczHxHZPamm+8t52vxFLTVaLMX1n+DtTiW qxqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777826703; x=1778431503; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=EtUh5EYJwmKXAER6m4XzUWsXnZUgq5RskppIOaQaosQ=; b=fvvabC9We23Pax8cGpK6KVSvssgTwihltoMFKL37Y5DwuikOuQIuVI00gcgNz/wHUP cO98C9GjeC01SvcTFCLnnJ1D6ApFnc8t99i5z3TjwpcC78B4cRTo9tv/lDABkCoPwgbN VwZRSF2wJSvp1DcrEjNPr8/sGLdYPIchjoAiock7JfDOrsCY0dAJ0A1moZVWScYMi90+ 2D1W/M7NgaUGT5oDXxGRu4ne104r5nRWROyoLfr086FzQp1OmqP8eyznN3Fim/Zju30q 8ZP75PE0HObmbGDv2Jbxfe9QWdxbh7YV5aHIui9/esSWMs7LnAqTBNf7q1JOpOzXZu9D c2tw== X-Forwarded-Encrypted: i=1; AFNElJ/1EJ4yPmtqsd7N0RS68kToTJv889XdAaoktEwWMWvo7RmJYKYS6QKaCEbGZiWWKrko22xfBjtZUJtXXvU=@vger.kernel.org X-Gm-Message-State: AOJu0YyVNZuLLL1EO9OvHCf/ZUyS7mKvNjGY/C5gMfYa4mSmMIb2WP2O uxv8nv5QLA5VMCef9b3LzIcKso78hhI2gQX8T97gIdK3JcN+4euEqGUq X-Gm-Gg: AeBDietiWGYSS5q012sUFdX7BRiQ8oo+32OtPUzTdecWXEirt9CzfzFJiI8HvZ1wh6F ihSAy656EkjZ41BIxoem+0h6qhnL36UIUChXAFwce35DRsPuyeL/07Y5iPHNHDiNSkMgpGnOqt7 lqMk6CH6nRkrHlkCU4UNxfqapzBq2QDUaF9SntmND3simmlGzAcueRUjO18uyzpj3bPnaHtlfOJ bXBT6Mgou8ddTi/33nTA6LnqG1BaqvirPQO4FWDg0O6nrL/SksocUBOot8S1i6nIRsoiv4m7sC2 FW7jNr89QcI7xvtItdEW4C1dMXM/pz2ONlyhIancWpMSR0rGBausbX3sOSAVC5o/n6DDMnuV9SD RVFMNtWkl0dSLFQKshXnFLKreffemucHQKM+hQrCb0DO6KoiYGIMt7l5agajUG/mTQj2y9Z43PN i5cWTkTRwfzSfSchR4WDaMF8o= X-Received: by 2002:a17:907:6d13:b0:bad:a28:e09 with SMTP id a640c23a62f3a-bbffe3c7554mr287296966b.41.1777826703105; Sun, 03 May 2026 09:45:03 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bc237ef8297sm27430566b.57.2026.05.03.09.45.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 09:45:01 -0700 (PDT) From: Svyatoslav Ryhel To: Lee Jones , Pavel Machek , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Sakari Ailus , Mauro Carvalho Chehab , Svyatoslav Ryhel Cc: linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH v5 4/6] media: i2c: lm3560: Convert to use OF bindings Date: Sun, 3 May 2026 19:44:43 +0300 Message-ID: <20260503164445.215540-5-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260503164445.215540-1-clamor95@gmail.com> References: <20260503164445.215540-1-clamor95@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Since there are no users of this driver via platform data, remove the platform data support and switch to using Device Tree bindings. Converting to Device Tree assumes dynamic and independent registration of LEDs. To monitor the configured LEDs, a bitmap has been added. This makes LED cleanup more robust and less context dependent. Signed-off-by: Svyatoslav Ryhel --- drivers/media/i2c/lm3560.c | 143 ++++++++++++++++++++++++++----------- include/media/i2c/lm3560.h | 15 ---- 2 files changed, 102 insertions(+), 56 deletions(-) diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 5b568ed9536b..ce4b09d1f208 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -9,11 +9,15 @@ * Ldd-Mlp */ =20 +#include #include #include #include #include +#include #include +#include +#include #include #include #include @@ -43,22 +47,33 @@ enum led_enable { * struct lm3560_flash * * @dev: pointer to &struct device - * @pdata: platform data * @regmap: reg. map for i2c * @lock: muxtex for serial access. * @led_mode: V4L2 LED mode * @ctrls_led: V4L2 controls * @subdev_led: V4L2 subdev + * @led_id: LED status holder + * @peak: peak current + * @max_flash_timeout: flash timeout + * @max_flash_brt: flash mode led brightness + * @max_torch_brt: torch mode led brightness */ struct lm3560_flash { struct device *dev; - struct lm3560_platform_data *pdata; struct regmap *regmap; struct mutex lock; =20 enum v4l2_flash_led_mode led_mode; struct v4l2_ctrl_handler ctrls_led[LM3560_LED_MAX]; struct v4l2_subdev subdev_led[LM3560_LED_MAX]; + + DECLARE_BITMAP(led_id, LM3560_LED_MAX); + + enum lm3560_peak_current peak; + u32 max_flash_timeout; + + u32 max_flash_brt[LM3560_LED_MAX]; + u32 max_torch_brt[LM3560_LED_MAX]; }; =20 #define to_lm3560_flash(_ctrl, _no) \ @@ -269,8 +284,8 @@ static int lm3560_init_controls(struct lm3560_flash *fl= ash, enum lm3560_led_id led_no) { struct v4l2_ctrl *fault; - u32 max_flash_brt =3D flash->pdata->max_flash_brt[led_no]; - u32 max_torch_brt =3D flash->pdata->max_torch_brt[led_no]; + u32 max_flash_brt =3D flash->max_flash_brt[led_no]; + u32 max_torch_brt =3D flash->max_torch_brt[led_no]; struct v4l2_ctrl_handler *hdl =3D &flash->ctrls_led[led_no]; const struct v4l2_ctrl_ops *ops =3D &lm3560_led_ctrl_ops[led_no]; =20 @@ -295,9 +310,9 @@ static int lm3560_init_controls(struct lm3560_flash *fl= ash, /* flash strobe timeout */ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TIMEOUT, LM3560_FLASH_TOUT_MIN, - flash->pdata->max_flash_timeout, + flash->max_flash_timeout, LM3560_FLASH_TOUT_STEP, - flash->pdata->max_flash_timeout); + flash->max_flash_timeout); =20 /* flash brt */ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY, @@ -339,15 +354,18 @@ static const struct regmap_config lm3560_regmap =3D { }; =20 static int lm3560_subdev_init(struct lm3560_flash *flash, - enum lm3560_led_id led_no, char *led_name) + enum lm3560_led_id led_no, + struct device_node *np) { struct i2c_client *client =3D to_i2c_client(flash->dev); int rval; =20 v4l2_i2c_subdev_init(&flash->subdev_led[led_no], client, &lm3560_ops); flash->subdev_led[led_no].flags |=3D V4L2_SUBDEV_FL_HAS_DEVNODE; - strscpy(flash->subdev_led[led_no].name, led_name, - sizeof(flash->subdev_led[led_no].name)); + snprintf(flash->subdev_led[led_no].name, + sizeof(flash->subdev_led[led_no].name), + "lm3560-led%d", led_no); + flash->subdev_led[led_no].fwnode =3D of_fwnode_handle(np); rval =3D lm3560_init_controls(flash, led_no); if (rval) goto err_out; @@ -378,7 +396,7 @@ static int lm3560_init_device(struct lm3560_flash *flas= h) =20 /* set peak current */ rval =3D regmap_update_bits(flash->regmap, - REG_FLASH_TOUT, 0x60, flash->pdata->peak); + REG_FLASH_TOUT, 0x60, flash->peak); if (rval < 0) return rval; /* output disable */ @@ -391,18 +409,22 @@ static int lm3560_init_device(struct lm3560_flash *fl= ash) return rval; } =20 -static void lm3560_subdev_cleanup(struct lm3560_flash *flash, - enum lm3560_led_id led_no) +static void lm3560_subdev_cleanup(struct lm3560_flash *flash) { - v4l2_async_unregister_subdev(&flash->subdev_led[led_no]); - v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]); - media_entity_cleanup(&flash->subdev_led[led_no].entity); + int led_no; + + for_each_set_bit(led_no, flash->led_id, LM3560_LED_MAX) { + v4l2_async_unregister_subdev(&flash->subdev_led[led_no]); + v4l2_ctrl_handler_free(&flash->ctrls_led[led_no]); + media_entity_cleanup(&flash->subdev_led[led_no].entity); + } } =20 static int lm3560_probe(struct i2c_client *client) { struct lm3560_flash *flash; - struct lm3560_platform_data *pdata =3D dev_get_platdata(&client->dev); + struct device_node *node; + u32 peak_ua; int rval; =20 flash =3D devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); @@ -415,36 +437,69 @@ static int lm3560_probe(struct i2c_client *client) return rval; } =20 - /* if there is no platform data, use chip default value */ - if (pdata =3D=3D NULL) { - pdata =3D devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); - if (pdata =3D=3D NULL) - return -ENODEV; - pdata->peak =3D LM3560_PEAK_3600mA; - pdata->max_flash_timeout =3D LM3560_FLASH_TOUT_MAX; - /* led 1 */ - pdata->max_flash_brt[LM3560_LED0] =3D LM3560_FLASH_BRT_MAX; - pdata->max_torch_brt[LM3560_LED0] =3D LM3560_TORCH_BRT_MAX; - /* led 2 */ - pdata->max_flash_brt[LM3560_LED1] =3D LM3560_FLASH_BRT_MAX; - pdata->max_torch_brt[LM3560_LED1] =3D LM3560_TORCH_BRT_MAX; - } - flash->pdata =3D pdata; flash->dev =3D &client->dev; mutex_init(&flash->lock); =20 + bitmap_zero(flash->led_id, LM3560_LED_MAX); + + flash->peak =3D LM3560_PEAK_1600mA; + rval =3D device_property_read_u32(flash->dev, + "ti,peak-current-microamp", &peak_ua); + if (!rval) { + switch (peak_ua) { + case 1600000: + flash->peak =3D LM3560_PEAK_1600mA; + break; + case 2300000: + flash->peak =3D LM3560_PEAK_2300mA; + break; + case 3000000: + flash->peak =3D LM3560_PEAK_3000mA; + break; + case 3600000: + flash->peak =3D LM3560_PEAK_3600mA; + break; + default: + return -EINVAL; + } + } + + flash->max_flash_timeout =3D LM3560_FLASH_TOUT_MIN * 1000; + device_property_read_u32(flash->dev, "flash-max-timeout-us", + &flash->max_flash_timeout); + flash->max_flash_timeout /=3D 1000; + rval =3D lm3560_init_device(flash); if (rval < 0) return rval; =20 - rval =3D lm3560_subdev_init(flash, LM3560_LED0, "lm3560-led0"); - if (rval < 0) - return rval; + for_each_available_child_of_node(dev_of_node(flash->dev), node) { + u32 reg; =20 - rval =3D lm3560_subdev_init(flash, LM3560_LED1, "lm3560-led1"); - if (rval < 0) { - lm3560_subdev_cleanup(flash, LM3560_LED0); - return rval; + rval =3D of_property_read_u32(node, "reg", ®); + if (rval < 0) + /* We care only about nodes with reg property */ + continue; + + if (reg =3D=3D LM3560_LED0 || reg =3D=3D LM3560_LED1) { + flash->max_flash_brt[reg] =3D LM3560_FLASH_BRT_MIN; + of_property_read_u32(node, "flash-max-microamp", + &flash->max_flash_brt[reg]); + + flash->max_torch_brt[reg] =3D LM3560_TORCH_BRT_MIN; + of_property_read_u32(node, "led-max-microamp", + &flash->max_torch_brt[reg]); + + rval =3D lm3560_subdev_init(flash, reg, node); + if (rval < 0) { + lm3560_subdev_cleanup(flash); + return dev_err_probe(flash->dev, rval, + "failed to register led%d\n", + reg); + } + + set_bit(reg, flash->led_id); + } } =20 i2c_set_clientdata(client, flash); @@ -455,12 +510,17 @@ static int lm3560_probe(struct i2c_client *client) static void lm3560_remove(struct i2c_client *client) { struct lm3560_flash *flash =3D i2c_get_clientdata(client); - unsigned int i; =20 - for (i =3D LM3560_LED0; i < LM3560_LED_MAX; i++) - lm3560_subdev_cleanup(flash, i); + lm3560_subdev_cleanup(flash); } =20 +static const struct of_device_id lm3560_of_match[] =3D { + { .compatible =3D "ti,lm3559" }, + { .compatible =3D "ti,lm3560" }, + { } +}; +MODULE_DEVICE_TABLE(of, lm3560_of_match); + static const struct i2c_device_id lm3560_id_table[] =3D { { LM3559_NAME }, { LM3560_NAME }, @@ -473,6 +533,7 @@ static struct i2c_driver lm3560_i2c_driver =3D { .driver =3D { .name =3D LM3560_NAME, .pm =3D NULL, + .of_match_table =3D lm3560_of_match, }, .probe =3D lm3560_probe, .remove =3D lm3560_remove, diff --git a/include/media/i2c/lm3560.h b/include/media/i2c/lm3560.h index 770d8c72c94a..b56c1ff8fd49 100644 --- a/include/media/i2c/lm3560.h +++ b/include/media/i2c/lm3560.h @@ -66,19 +66,4 @@ enum lm3560_peak_current { LM3560_PEAK_3600mA =3D 0x60 }; =20 -/* struct lm3560_platform_data - * - * @peak : peak current - * @max_flash_timeout: flash timeout - * @max_flash_brt: flash mode led brightness - * @max_torch_brt: torch mode led brightness - */ -struct lm3560_platform_data { - enum lm3560_peak_current peak; - - u32 max_flash_timeout; - u32 max_flash_brt[LM3560_LED_MAX]; - u32 max_torch_brt[LM3560_LED_MAX]; -}; - #endif /* __LM3560_H__ */ --=20 2.51.0 From nobody Sun Jun 14 04:09:15 2026 Received: from mail-ed1-f53.google.com (mail-ed1-f53.google.com [209.85.208.53]) (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 12ABB37CD20 for ; Sun, 3 May 2026 16:45:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826714; cv=none; b=qoaZRTv4m+kpCa+816GhUO4MeZ7QAZnPFRCe/Z/zpVKrHrQUZ1vQ/VIvViBzd08/qkUKxQxJG1qUgwlEU0mZEhCCL2GJPUE0HR/f1ks35utlx1luSEGG1ai9f2LsTWuAa1mKpX+AUBHtclYVEpjpPPvmbFivE0/f3DeyQwynays= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826714; c=relaxed/simple; bh=PXMbL35meuA3K4hWiUmh26Ifh+2vO6KRGqztajociNo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JGcgpI8H2qY23MTVfSCHC+KfspezSUSsXcOt6BH3k6fQZhPhcdauTCMdYPr4gKIidyhpIZL6vBch8/rROj+faSZNtg21h0/WRBmixhkL7AloKSoWTI9IPUrm8f7WfsOzSNcdrG02TnvtHghbUt7l4Ru3GAqfQ24vuGlgo3yypWg= 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=ElGr9luZ; arc=none smtp.client-ip=209.85.208.53 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="ElGr9luZ" Received: by mail-ed1-f53.google.com with SMTP id 4fb4d7f45d1cf-65c4152313fso4673575a12.1 for ; Sun, 03 May 2026 09:45:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777826704; x=1778431504; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sRXkstlVfDTEdoKTn7b1ddY7nla/Jav5UO7h+m11Go8=; b=ElGr9luZA0OJ5FVLJTAGW7vaysrroq6JUTWHJLSizlBnhGbc+KWWvi1LFYVgv1AbxC GC5ML+UZupBN8CSarMuTOKFW9XdjvMlMPq8AtURO7u4Luom1dfkHPTv9b8JKyAnIkSR6 3Yp5N3D90g885uJONZgupf4ShUTvdM53Nn1tGyw+Hpxhs4816bjfxinnDT8yLE+Z6cz3 GWtBpYaRuXtrjzYB9jankuJm8MEeoEWeWpyLWx3sy/3bxXiRtL2cIpQNvvL2MCqS+78a 37M8tELMGYjqdbWIp7KpB8/KAGe3Ll+RcB0U5rOzIls2SCgN7ub27OKvMZYEGgzkzNvb nHFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777826704; x=1778431504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=sRXkstlVfDTEdoKTn7b1ddY7nla/Jav5UO7h+m11Go8=; b=ChqsvkmswdeQrrwnGzIcdx1Vr3JApcfJVuALeYajsOkb7mY6n6AJvgxlqcCQk1pWHw Ui2VnY2QXh/s1U0yGgWuVsyIrzmg5NRv0qN5xP9/4pZN5jpRJS6LmeRN5IGBBCq/CyKq WC0d81CRe7Yh7cMMpIpWROy2NlVjQtVEsoONO0UJLPG6ql9p06qX8claBnwaoFm4p0xG MQnSUtPUQUg3awP/+KIpZOlP7Ftr9U08RfnRun2kaXbwwUvO6wXemMwGi7JZxqr8MWt7 /iiEs0EAZMMmqBS3m5grhcAByFtDxu7urfa08oVmGidQXDGSzEiPF0fUd5sXhXzAqtHJ m2sw== X-Forwarded-Encrypted: i=1; AFNElJ+njhiRaQVFJTi0gnVtTYp5TqzWKraSA0YufehOYE8HQvfZv9Z3Aly/AYpvI95hX8u3gipxAHYrr7q9wGs=@vger.kernel.org X-Gm-Message-State: AOJu0Yxq2EY9ST5BJP+sOe5c+vatPZeivudxpsIz4E4WkpwyKwU3u5Rx 7k7FBx3BnouW+S+SoY92ghnhiAjoWUBfs0wuusxWLBze2LYrB4eDk0c/ X-Gm-Gg: AeBDievM4WBkA1LDQa8m5JFIcqQybZ47c8o5EEg9RWiLeYA75+dbIQqxqCE4ll/qJAB oqaiE5O5QiaMPg0G37OMwonIZwULPpM/zpFAlw3mU971tXsL3CiW73bS1yGGLc3PepPpAmx0H8M 5a2tWlO0pRU6Fx8OPG0MN/xnP/czjlejawMoCzZfLhP++DYyBkFU/2639IN2rB41C08+0blLkBf e5booV7katutxqely12fx2vjIyh2mC6qvgxqcr8/j5UQkyzKLI45Elh46IpeTJx1OzRPkDSpYnE u62fwG9Z/sJxIhwIMj/t73ipYGrHGnZ/IXIxEt7wO2aKP4Nq34i0bTHOg9j/McY6OADCba6jv9J 5JVBhz/JXQYQxPk0/CtZ1B7RPwGI2wUA60G+spS4RAqJKhVMlQdtfH6kUzwu/HGLQ0rLNnhUPtn sQmoVb+RzQ09jO6XorMdJ0lGQ= X-Received: by 2002:a17:907:930d:b0:bad:52bd:8764 with SMTP id a640c23a62f3a-bbffcf919b4mr313501666b.24.1777826704242; Sun, 03 May 2026 09:45:04 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bc237ef8297sm27430566b.57.2026.05.03.09.45.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 09:45:03 -0700 (PDT) From: Svyatoslav Ryhel To: Lee Jones , Pavel Machek , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Sakari Ailus , Mauro Carvalho Chehab , Svyatoslav Ryhel Cc: linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH v5 5/6] media: i2c: lm3560: Add support for PM features Date: Sun, 3 May 2026 19:44:44 +0300 Message-ID: <20260503164445.215540-6-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260503164445.215540-1-clamor95@gmail.com> References: <20260503164445.215540-1-clamor95@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for power management features to better control the LM3560 within the media framework. To achieve the desired PM support, the HWEN GPIO and VIN power supply were added and configured into power on/off sequences. Added PM operations along with the PM configuration setup. Signed-off-by: Svyatoslav Ryhel --- drivers/media/i2c/lm3560.c | 117 ++++++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index ce4b09d1f208..15741ea5684f 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -12,13 +12,16 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -49,6 +52,8 @@ enum led_enable { * @dev: pointer to &struct device * @regmap: reg. map for i2c * @lock: muxtex for serial access. + * @hwen_gpio: line connected to HWEN pin + * @vin_supply: line connected to IN supply (2.5V - 5.5V) * @led_mode: V4L2 LED mode * @ctrls_led: V4L2 controls * @subdev_led: V4L2 subdev @@ -63,6 +68,9 @@ struct lm3560_flash { struct regmap *regmap; struct mutex lock; =20 + struct gpio_desc *hwen_gpio; + struct regulator *vin_supply; + enum v4l2_flash_led_mode led_mode; struct v4l2_ctrl_handler ctrls_led[LM3560_LED_MAX]; struct v4l2_subdev subdev_led[LM3560_LED_MAX]; @@ -177,12 +185,17 @@ static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, en= um lm3560_led_id led_no) struct lm3560_flash *flash =3D to_lm3560_flash(ctrl, led_no); int rval =3D -EINVAL; =20 + if (!pm_runtime_get_if_in_use(flash->dev)) + return 0; + if (ctrl->id =3D=3D V4L2_CID_FLASH_FAULT) { s32 fault =3D 0; unsigned int reg_val; rval =3D regmap_read(flash->regmap, REG_FLAG, ®_val); - if (rval < 0) + if (rval < 0) { + pm_runtime_put(flash->dev); return rval; + } if (reg_val & FAULT_SHORT_CIRCUIT) fault |=3D V4L2_FLASH_FAULT_SHORT_CIRCUIT; if (reg_val & FAULT_OVERTEMP) @@ -192,6 +205,8 @@ static int lm3560_get_ctrl(struct v4l2_ctrl *ctrl, enum= lm3560_led_id led_no) ctrl->cur.val =3D fault; } =20 + pm_runtime_put(flash->dev); + return rval; } =20 @@ -201,6 +216,9 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum= lm3560_led_id led_no) u8 tout_bits; int rval =3D -EINVAL; =20 + if (!pm_runtime_get_if_in_use(flash->dev)) + return 0; + switch (ctrl->id) { case V4L2_CID_FLASH_LED_MODE: flash->led_mode =3D ctrl->val; @@ -246,6 +264,8 @@ static int lm3560_set_ctrl(struct v4l2_ctrl *ctrl, enum= lm3560_led_id led_no) break; } =20 + pm_runtime_put(flash->dev); + return rval; } =20 @@ -409,6 +429,38 @@ static int lm3560_init_device(struct lm3560_flash *fla= sh) return rval; } =20 +static int __maybe_unused lm3560_power_off(struct device *dev) +{ + struct lm3560_flash *flash =3D dev_get_drvdata(dev); + + gpiod_set_value_cansleep(flash->hwen_gpio, 0); + regulator_disable(flash->vin_supply); + + return 0; +} + +static int __maybe_unused lm3560_power_on(struct device *dev) +{ + struct lm3560_flash *flash =3D dev_get_drvdata(dev); + int rval; + + rval =3D regulator_enable(flash->vin_supply); + if (rval < 0) { + dev_err(flash->dev, "failed to enable vin power supply\n"); + return rval; + } + + gpiod_set_value_cansleep(flash->hwen_gpio, 1); + + rval =3D lm3560_init_device(flash); + if (rval < 0) { + lm3560_power_off(dev); + return rval; + } + + return 0; +} + static void lm3560_subdev_cleanup(struct lm3560_flash *flash) { int led_no; @@ -442,6 +494,17 @@ static int lm3560_probe(struct i2c_client *client) =20 bitmap_zero(flash->led_id, LM3560_LED_MAX); =20 + flash->hwen_gpio =3D devm_gpiod_get_optional(flash->dev, "enable", + GPIOD_OUT_LOW); + if (IS_ERR(flash->hwen_gpio)) + return dev_err_probe(flash->dev, PTR_ERR(flash->hwen_gpio), + "failed to get hwen gpio\n"); + + flash->vin_supply =3D devm_regulator_get(flash->dev, "vin"); + if (IS_ERR(flash->vin_supply)) + return dev_err_probe(flash->dev, PTR_ERR(flash->vin_supply), + "failed to get vin-supply\n"); + flash->peak =3D LM3560_PEAK_1600mA; rval =3D device_property_read_u32(flash->dev, "ti,peak-current-microamp", &peak_ua); @@ -469,9 +532,19 @@ static int lm3560_probe(struct i2c_client *client) &flash->max_flash_timeout); flash->max_flash_timeout /=3D 1000; =20 + rval =3D regulator_enable(flash->vin_supply); + if (rval < 0) + return dev_err_probe(flash->dev, rval, + "failed to enable vin power supply\n"); + + gpiod_set_value_cansleep(flash->hwen_gpio, 1); + rval =3D lm3560_init_device(flash); if (rval < 0) - return rval; + goto error_disable; + + pm_runtime_set_active(flash->dev); + pm_runtime_enable(flash->dev); =20 for_each_available_child_of_node(dev_of_node(flash->dev), node) { u32 reg; @@ -492,10 +565,10 @@ static int lm3560_probe(struct i2c_client *client) =20 rval =3D lm3560_subdev_init(flash, reg, node); if (rval < 0) { - lm3560_subdev_cleanup(flash); - return dev_err_probe(flash->dev, rval, - "failed to register led%d\n", - reg); + dev_err(flash->dev, + "failed to register led%d: %d\n", + reg, rval); + goto error_clean; } =20 set_bit(reg, flash->led_id); @@ -504,7 +577,23 @@ static int lm3560_probe(struct i2c_client *client) =20 i2c_set_clientdata(client, flash); =20 + pm_runtime_set_autosuspend_delay(flash->dev, 1000); + pm_runtime_use_autosuspend(flash->dev); + pm_runtime_idle(flash->dev); + return 0; + +error_clean: + pm_runtime_disable(flash->dev); + pm_runtime_set_suspended(flash->dev); + + lm3560_subdev_cleanup(flash); + +error_disable: + gpiod_set_value_cansleep(flash->hwen_gpio, 0); + regulator_disable(flash->vin_supply); + + return rval; } =20 static void lm3560_remove(struct i2c_client *client) @@ -512,8 +601,22 @@ static void lm3560_remove(struct i2c_client *client) struct lm3560_flash *flash =3D i2c_get_clientdata(client); =20 lm3560_subdev_cleanup(flash); + + /* + * Disable runtime PM. In case runtime PM is disabled in the kernel, + * make sure to turn power off manually. + */ + pm_runtime_disable(&client->dev); + if (!pm_runtime_status_suspended(&client->dev)) { + lm3560_power_off(&client->dev); + pm_runtime_set_suspended(&client->dev); + } } =20 +static const struct dev_pm_ops lm3560_pm_ops =3D { + SET_RUNTIME_PM_OPS(lm3560_power_off, lm3560_power_on, NULL) +}; + static const struct of_device_id lm3560_of_match[] =3D { { .compatible =3D "ti,lm3559" }, { .compatible =3D "ti,lm3560" }, @@ -532,7 +635,7 @@ MODULE_DEVICE_TABLE(i2c, lm3560_id_table); static struct i2c_driver lm3560_i2c_driver =3D { .driver =3D { .name =3D LM3560_NAME, - .pm =3D NULL, + .pm =3D pm_ptr(&lm3560_pm_ops), .of_match_table =3D lm3560_of_match, }, .probe =3D lm3560_probe, --=20 2.51.0 From nobody Sun Jun 14 04:09:15 2026 Received: from mail-ej1-f45.google.com (mail-ej1-f45.google.com [209.85.218.45]) (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 2A15727F4F5 for ; Sun, 3 May 2026 16:45:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826712; cv=none; b=gbs5cT2WGCb46L0L94Du0oMr/BpCmZz5HXYtUpklJaxPuOmqZRH1M8Jin2dCUtLRCS8zdXM/GuMCe3sqgDSYKZTOnEC7iRAxbajvpyFK/0Ury84iyyhqioNG2cgOxBeXC5v0QTaVJfuelT7UrI6vdcDDHw7I6oFf0KbbrsBlQhM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777826712; c=relaxed/simple; bh=7Op9ubqBC6Ql1b7wKXH5NzggGBRcOSoMZ1O9wP90KmY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GUsIIqPgEgsIQVIlOWm+wT+QGn3z1jZ81UNIcY/rZ/qqo/DCQOHcttVF0K4rzCVVWAunl5iEeQx4+TC4Sb6/9RdH85IHwVEcc3xyqpYr3DNq9Cczlj0LP6+six/V14Bn3/aKFu5VARyy1Pmk6GkfhB+gecppjeXJaPJ8kNIZbA4= 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=o+R3qjJG; arc=none smtp.client-ip=209.85.218.45 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="o+R3qjJG" Received: by mail-ej1-f45.google.com with SMTP id a640c23a62f3a-ba545100a13so612599266b.2 for ; Sun, 03 May 2026 09:45:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777826705; x=1778431505; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gOh4PG7yMJifApqzJycmTrJ4xR4vGrLLw/m7gNops7A=; b=o+R3qjJGuoQWAtn6yS3YP66NuwSZrk8yIFbEPaAr6WmEbDyU3KK4I9LRtQOE5vwOgg vMBzVu1G4eE5dWS3J1wh4IzK7bsX4XY456BfuX+IA/lU+w8fvEALMTDHJmdZO0/vunc/ 6VQ5ZWg2WXVwJi1vwn50iB48HNZyGCB4Jm+yXzM0EelkrXudgMK9vFQBR3UKFgxanM2n fryE8yA05i3CnNBDoXWMaO92KNQfbjiWeOulXE6ZDR+nXmiYFwy0jtzNkFArvtjgvKi+ 3vWU09WcAy5bgbZmO4LUDDKmV95nPdY5nmQaw/Nu9eO66htro4cCGY9CH1pTOtsaUYEa 0Lpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777826705; x=1778431505; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=gOh4PG7yMJifApqzJycmTrJ4xR4vGrLLw/m7gNops7A=; b=q5VLgswk7n6sS0mu2H/DAfFuxDd46dqV1P1euW2wbmKb5NGqHfR5WK48wp9dd++O9m KTrRtcJgw0Rn9zUWpECSnBMzIP6U1RMUC3MYhYbhq/QNY+p/vdlzFVq1oDi6iLtbxZ98 mR+SWOqrzSt2+EDT5LQbXqfaB9JThFb5r3wg5vZYE98YjwSA9GY5AxbmlN/+ryGzpJzD WgY5yUv+FJLlM3VqcxExyppgJbG7iORGKu0SykSJo7Nf7NsQbn2BxtFndIMw/s1br9zi iJn1+JSbOJEtCNyaX+10s+9p+zexk1AGEUBgzZuO8cBbMg6Sb2dAt+UJcxYpllwH2tmo s1YQ== X-Forwarded-Encrypted: i=1; AFNElJ8vf4ab1gPqqjiSCiE76wqqAUmGWeUDURBbfIvEmP4Aut7GUEaJsieGb7JFzge/6v1/6rXsG8e1Vd1p/1g=@vger.kernel.org X-Gm-Message-State: AOJu0Yxx26byKK4yGGIYEEhnFeJ52TSF+HgaWW9VBCfQxiMbIIi8WNAM gxN8d8+EUbAMhe8cdEd5dgT4LYyWe2fUr8mpnVr5eRZ8yaF5FABnR1BF X-Gm-Gg: AeBDiet+Muo3pJHQeguTP7fwKnbMynQtNLPcLXVR28xdkbB4ZgkcUXAPIHkOcORQ0Cr Ets+ry8X+nLL9BfY9TxmEykHOzT7XUtfqPI3l9Q12whwnQwB357dyXAwaSyoHSD3AYRnqL+nu7C mJ5lKRLLIxujHkyVg8MIyDAQZmg4HEy8RrDcqCzwSdv/bT5u33LMb6jGN/xX4AcI2K7LeMERNQO b6KCAnqxK6Tlh6mTfGqyyz+NYoWAF8K+bkQqw+VzBybAuvHwZzQm2Y37XDVHRKl0GfU55TztcbT 2TXHe8DM3Aa/3VYn1VyEbLBMPS4tVsKmiP+F/7lvj0BMkVPs01VzcDjOy/RBHijg5NO0Q0z3K9c Tr537tliTn1TUGF+JgrVb/9c1PZIv06qj1xv38m4Qf+S+T52ILllpybYQi7TDAmitNefSTmR9XI QOcL2QsnYkZd3YM7CeIdpbNGqxUM14OPrNsg== X-Received: by 2002:a17:907:805:b0:bc1:6ec9:453b with SMTP id a640c23a62f3a-bc16ec95285mr139456566b.42.1777826705359; Sun, 03 May 2026 09:45:05 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bc237ef8297sm27430566b.57.2026.05.03.09.45.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 09:45:04 -0700 (PDT) From: Svyatoslav Ryhel To: Lee Jones , Pavel Machek , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Sakari Ailus , Mauro Carvalho Chehab , Svyatoslav Ryhel Cc: linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Subject: [PATCH v5 6/6] media: i2c: lm3560: Add proper support for LM3559 Date: Sun, 3 May 2026 19:44:45 +0300 Message-ID: <20260503164445.215540-7-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260503164445.215540-1-clamor95@gmail.com> References: <20260503164445.215540-1-clamor95@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The LM3559 is very similar to the LM3560, but it operates at much lower currents. This may result in incorrect current selection if LM3560 ranges are applied to the LM3559. Implement driver data matching to use device-specific current configurations. Since the driver no longer supports platform data and device configuration is performed more granularly, move the remaining enums from the header into the driver file and remove the header. Signed-off-by: Svyatoslav Ryhel --- drivers/media/i2c/lm3560.c | 120 ++++++++++++++++++++++++++++++------- include/media/i2c/lm3560.h | 69 --------------------- 2 files changed, 100 insertions(+), 89 deletions(-) delete mode 100644 include/media/i2c/lm3560.h diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 15741ea5684f..da12fbd7dc59 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -23,9 +23,9 @@ #include #include #include -#include #include #include +#include =20 /* registers definitions */ #define REG_ENABLE 0x10 @@ -40,12 +40,44 @@ #define FAULT_OVERTEMP (1<<1) #define FAULT_SHORT_CIRCUIT (1<<2) =20 +#define LM3560_FLASH_TOUT_MIN 32 +#define LM3560_FLASH_TOUT_STEP 32 +#define LM3560_FLASH_TOUT_MAX 1024 +#define LM3560_FLASH_TOUT_ms_TO_REG(a) \ + ((a) < LM3560_FLASH_TOUT_MIN ? 0 : \ + (((a) - LM3560_FLASH_TOUT_MIN) / LM3560_FLASH_TOUT_STEP)) +#define LM3560_FLASH_TOUT_REG_TO_ms(a) \ + ((a) * LM3560_FLASH_TOUT_STEP + LM3560_FLASH_TOUT_MIN) + +enum lm3560_led_id { + LM3560_LED0 =3D 0, + LM3560_LED1, + LM3560_LED_MAX +}; + +enum lm3560_peak_current { + LM3560_PEAK_1600mA =3D 0x00, + LM3560_PEAK_2300mA =3D 0x20, + LM3560_PEAK_3000mA =3D 0x40, + LM3560_PEAK_3600mA =3D 0x60 +}; + enum led_enable { MODE_SHDN =3D 0x0, MODE_TORCH =3D 0x2, MODE_FLASH =3D 0x3, }; =20 +struct lm3560_flash_config { + u32 flash_brt_min_ua; + u32 flash_brt_max_ua; + u32 flash_brt_step_ua; + + u32 torch_brt_min_ua; + u32 torch_brt_max_ua; + u32 torch_brt_step_ua; +}; + /** * struct lm3560_flash * @@ -62,6 +94,7 @@ enum led_enable { * @max_flash_timeout: flash timeout * @max_flash_brt: flash mode led brightness * @max_torch_brt: torch mode led brightness + * @config: device specific current configuration */ struct lm3560_flash { struct device *dev; @@ -82,6 +115,8 @@ struct lm3560_flash { =20 u32 max_flash_brt[LM3560_LED_MAX]; u32 max_torch_brt[LM3560_LED_MAX]; + + const struct lm3560_flash_config *config; }; =20 #define to_lm3560_flash(_ctrl, _no) \ @@ -137,15 +172,20 @@ static int lm3560_enable_ctrl(struct lm3560_flash *fl= ash, static int lm3560_torch_brt_ctrl(struct lm3560_flash *flash, enum lm3560_led_id led_no, unsigned int brt) { + const struct lm3560_flash_config *config =3D flash->config; int rval; - u8 br_bits; + u32 br_bits; =20 - if (brt < LM3560_TORCH_BRT_MIN) + if (brt < config->torch_brt_min_ua) return lm3560_enable_ctrl(flash, led_no, false); else rval =3D lm3560_enable_ctrl(flash, led_no, true); =20 - br_bits =3D LM3560_TORCH_BRT_uA_TO_REG(brt); + br_bits =3D clamp(brt, config->torch_brt_min_ua, + config->torch_brt_max_ua); + br_bits =3D (br_bits - config->torch_brt_min_ua) / + config->torch_brt_step_ua; + if (led_no =3D=3D LM3560_LED0) rval =3D regmap_update_bits(flash->regmap, REG_TORCH_BR, 0x07, br_bits); @@ -160,15 +200,20 @@ static int lm3560_torch_brt_ctrl(struct lm3560_flash = *flash, static int lm3560_flash_brt_ctrl(struct lm3560_flash *flash, enum lm3560_led_id led_no, unsigned int brt) { + const struct lm3560_flash_config *config =3D flash->config; int rval; - u8 br_bits; + u32 br_bits; =20 - if (brt < LM3560_FLASH_BRT_MIN) + if (brt < config->flash_brt_min_ua) return lm3560_enable_ctrl(flash, led_no, false); else rval =3D lm3560_enable_ctrl(flash, led_no, true); =20 - br_bits =3D LM3560_FLASH_BRT_uA_TO_REG(brt); + br_bits =3D clamp(brt, config->flash_brt_min_ua, + config->flash_brt_max_ua); + br_bits =3D (br_bits - config->flash_brt_min_ua) / + config->flash_brt_step_ua; + if (led_no =3D=3D LM3560_LED0) rval =3D regmap_update_bits(flash->regmap, REG_FLASH_BR, 0x0f, br_bits); @@ -308,6 +353,7 @@ static int lm3560_init_controls(struct lm3560_flash *fl= ash, u32 max_torch_brt =3D flash->max_torch_brt[led_no]; struct v4l2_ctrl_handler *hdl =3D &flash->ctrls_led[led_no]; const struct v4l2_ctrl_ops *ops =3D &lm3560_led_ctrl_ops[led_no]; + const struct lm3560_flash_config *config =3D flash->config; =20 v4l2_ctrl_handler_init(hdl, 8); =20 @@ -336,13 +382,13 @@ static int lm3560_init_controls(struct lm3560_flash *= flash, =20 /* flash brt */ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_INTENSITY, - LM3560_FLASH_BRT_MIN, max_flash_brt, - LM3560_FLASH_BRT_STEP, max_flash_brt); + config->flash_brt_min_ua, max_flash_brt, + config->flash_brt_step_ua, max_flash_brt); =20 /* torch brt */ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_TORCH_INTENSITY, - LM3560_TORCH_BRT_MIN, max_torch_brt, - LM3560_TORCH_BRT_STEP, max_torch_brt); + config->torch_brt_min_ua, max_torch_brt, + config->torch_brt_step_ua, max_torch_brt); =20 /* fault */ fault =3D v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FLASH_FAULT, 0, @@ -483,6 +529,10 @@ static int lm3560_probe(struct i2c_client *client) if (flash =3D=3D NULL) return -ENOMEM; =20 + flash->config =3D device_get_match_data(&client->dev); + if (!flash->config) + return -ENODEV; + flash->regmap =3D devm_regmap_init_i2c(client, &lm3560_regmap); if (IS_ERR(flash->regmap)) { rval =3D PTR_ERR(flash->regmap); @@ -509,16 +559,26 @@ static int lm3560_probe(struct i2c_client *client) rval =3D device_property_read_u32(flash->dev, "ti,peak-current-microamp", &peak_ua); if (!rval) { + /* + * LM3559 has lower peak current limit, but + * bit configuration matches LM3560. + * Correct current restrictions are enforced + * by the LM3560 schema. + */ switch (peak_ua) { + case 1400000: case 1600000: flash->peak =3D LM3560_PEAK_1600mA; break; + case 2100000: case 2300000: flash->peak =3D LM3560_PEAK_2300mA; break; + case 2700000: case 3000000: flash->peak =3D LM3560_PEAK_3000mA; break; + case 3200000: case 3600000: flash->peak =3D LM3560_PEAK_3600mA; break; @@ -547,6 +607,7 @@ static int lm3560_probe(struct i2c_client *client) pm_runtime_enable(flash->dev); =20 for_each_available_child_of_node(dev_of_node(flash->dev), node) { + const struct lm3560_flash_config *config =3D flash->config; u32 reg; =20 rval =3D of_property_read_u32(node, "reg", ®); @@ -555,11 +616,11 @@ static int lm3560_probe(struct i2c_client *client) continue; =20 if (reg =3D=3D LM3560_LED0 || reg =3D=3D LM3560_LED1) { - flash->max_flash_brt[reg] =3D LM3560_FLASH_BRT_MIN; + flash->max_flash_brt[reg] =3D config->flash_brt_min_ua; of_property_read_u32(node, "flash-max-microamp", &flash->max_flash_brt[reg]); =20 - flash->max_torch_brt[reg] =3D LM3560_TORCH_BRT_MIN; + flash->max_torch_brt[reg] =3D config->torch_brt_min_ua; of_property_read_u32(node, "led-max-microamp", &flash->max_torch_brt[reg]); =20 @@ -617,24 +678,43 @@ static const struct dev_pm_ops lm3560_pm_ops =3D { SET_RUNTIME_PM_OPS(lm3560_power_off, lm3560_power_on, NULL) }; =20 +static const struct lm3560_flash_config lm3559_config =3D { + .flash_brt_min_ua =3D 56250, + .flash_brt_max_ua =3D 900000, + .flash_brt_step_ua =3D 56250, + + .torch_brt_min_ua =3D 28125, + .torch_brt_max_ua =3D 225000, + .torch_brt_step_ua =3D 28125, +}; + +static const struct lm3560_flash_config lm3560_config =3D { + .flash_brt_min_ua =3D 62500, + .flash_brt_max_ua =3D 1000000, + .flash_brt_step_ua =3D 62500, + + .torch_brt_min_ua =3D 31250, + .torch_brt_max_ua =3D 250000, + .torch_brt_step_ua =3D 31250, +}; + static const struct of_device_id lm3560_of_match[] =3D { - { .compatible =3D "ti,lm3559" }, - { .compatible =3D "ti,lm3560" }, + { .compatible =3D "ti,lm3559", .data =3D &lm3559_config }, + { .compatible =3D "ti,lm3560", .data =3D &lm3560_config }, { } }; MODULE_DEVICE_TABLE(of, lm3560_of_match); =20 static const struct i2c_device_id lm3560_id_table[] =3D { - { LM3559_NAME }, - { LM3560_NAME }, - {} + { "lm3559", (kernel_ulong_t)&lm3559_config }, + { "lm3560", (kernel_ulong_t)&lm3560_config }, + { } }; - MODULE_DEVICE_TABLE(i2c, lm3560_id_table); =20 static struct i2c_driver lm3560_i2c_driver =3D { .driver =3D { - .name =3D LM3560_NAME, + .name =3D "lm3560", .pm =3D pm_ptr(&lm3560_pm_ops), .of_match_table =3D lm3560_of_match, }, diff --git a/include/media/i2c/lm3560.h b/include/media/i2c/lm3560.h deleted file mode 100644 index b56c1ff8fd49..000000000000 --- a/include/media/i2c/lm3560.h +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * include/media/i2c/lm3560.h - * - * Copyright (C) 2013 Texas Instruments - * - * Contact: Daniel Jeong - * Ldd-Mlp - */ - -#ifndef __LM3560_H__ -#define __LM3560_H__ - -#include - -#define LM3559_NAME "lm3559" -#define LM3560_NAME "lm3560" -#define LM3560_I2C_ADDR (0x53) - -/* FLASH Brightness - * min 62500uA, step 62500uA, max 1000000uA - */ -#define LM3560_FLASH_BRT_MIN 62500 -#define LM3560_FLASH_BRT_STEP 62500 -#define LM3560_FLASH_BRT_MAX 1000000 -#define LM3560_FLASH_BRT_uA_TO_REG(a) \ - ((a) < LM3560_FLASH_BRT_MIN ? 0 : \ - (((a) - LM3560_FLASH_BRT_MIN) / LM3560_FLASH_BRT_STEP)) -#define LM3560_FLASH_BRT_REG_TO_uA(a) \ - ((a) * LM3560_FLASH_BRT_STEP + LM3560_FLASH_BRT_MIN) - -/* FLASH TIMEOUT DURATION - * min 32ms, step 32ms, max 1024ms - */ -#define LM3560_FLASH_TOUT_MIN 32 -#define LM3560_FLASH_TOUT_STEP 32 -#define LM3560_FLASH_TOUT_MAX 1024 -#define LM3560_FLASH_TOUT_ms_TO_REG(a) \ - ((a) < LM3560_FLASH_TOUT_MIN ? 0 : \ - (((a) - LM3560_FLASH_TOUT_MIN) / LM3560_FLASH_TOUT_STEP)) -#define LM3560_FLASH_TOUT_REG_TO_ms(a) \ - ((a) * LM3560_FLASH_TOUT_STEP + LM3560_FLASH_TOUT_MIN) - -/* TORCH BRT - * min 31250uA, step 31250uA, max 250000uA - */ -#define LM3560_TORCH_BRT_MIN 31250 -#define LM3560_TORCH_BRT_STEP 31250 -#define LM3560_TORCH_BRT_MAX 250000 -#define LM3560_TORCH_BRT_uA_TO_REG(a) \ - ((a) < LM3560_TORCH_BRT_MIN ? 0 : \ - (((a) - LM3560_TORCH_BRT_MIN) / LM3560_TORCH_BRT_STEP)) -#define LM3560_TORCH_BRT_REG_TO_uA(a) \ - ((a) * LM3560_TORCH_BRT_STEP + LM3560_TORCH_BRT_MIN) - -enum lm3560_led_id { - LM3560_LED0 =3D 0, - LM3560_LED1, - LM3560_LED_MAX -}; - -enum lm3560_peak_current { - LM3560_PEAK_1600mA =3D 0x00, - LM3560_PEAK_2300mA =3D 0x20, - LM3560_PEAK_3000mA =3D 0x40, - LM3560_PEAK_3600mA =3D 0x60 -}; - -#endif /* __LM3560_H__ */ --=20 2.51.0