From nobody Sat Jun 13 17:03:46 2026 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (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 8AFAB15CD7E for ; Wed, 6 May 2026 06:49:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050149; cv=none; b=neTqLa91oBcaG9XhNnzj55l4Hsx32Qs/qM+FlAD3vQZHrMYDCgLXIFH/WhgZVgx9UKxxCR9GpW3HUq/DLb12IIMew+WvsMv3+eHb0RK1S5NPmfJqAivEs81Z/Oza9e4wqBKUtxxGK6mrtrzjgXxLlY7xUiPlEUJxAU3sQkO9KcI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050149; c=relaxed/simple; bh=pHp6Q7knii2n+EhMdTYm6APHUxAVGaG6SjWBOs/Ltog=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k8+3oq6hl4O1+AWtbpAmrrqCCsxTvwv2yKsNlnFNDxoIXnQSuYTHJdG6qQHZJcp4gDHzPfVH/kiDEad2hZYYFd99hkTCVZ6MAYKFSccmU4sxFwVwbgaY1PHn0zgcEsflOjSv8UEwpNWCc3tN4vINSGQlpPhJIItZ2EwXudWe3Fc= 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=X/n5+3He; arc=none smtp.client-ip=209.85.128.43 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="X/n5+3He" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-48334ee0aeaso42926435e9.1 for ; Tue, 05 May 2026 23:49:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778050146; x=1778654946; 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=RtWz4md+KpJ0I5o5giTzQAfd544HTKz5u0iahZieaR0=; b=X/n5+3HesL4FqjlKALUCRo5oHbnH9MRiVj/Pmv26H3kPXroqCKXuojOg+KsKTaq0YH D1HRDvzaAssIQE8pBuOYLHTSdHGYeyQSZoN6uxzNlbNuoqI9217TuyFu3E5ExYMtvDIJ JcT3SBDqbmnMt3CgCsmXsqA3UegUpb6Ef2ULCf/r4u+PCWJG9LL3iM63SXlrMSoGLYBV xqJEH4xszgHQxig/vpJBuSdex2/0HcwbSJHoriRTD5IHE6LgxsGNc9Y63lGrcECDDV4f w3l9ELdSVyc1NBWWMnjW8fki9hSqa80EY1PSMKOl3x6wR2TVANB7uhd4j8trxJEpTSXl KghQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778050146; x=1778654946; 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=RtWz4md+KpJ0I5o5giTzQAfd544HTKz5u0iahZieaR0=; b=LVrRPdYl7h/uGYJgf//Pm7BjMh9/mJSG0YSKwXwtfktRliXlqfaUh/67baNLmkdOML p8tpjGcp3M+y0wU+vnUUkZx9zFvdt6STLgrmdFXM5ezBFYsOjbHpup76qgq599/IbDEv QKbgdoSgBs1jQO3qsArWHVA1pj1HtDaP9FkgKeyRJaORnhQBdWU7Vqq4vZ/PZPXp/SQH kJjbjtem2ztGHOIVMER9Ejdv5Bs2Ylwc9zEJAcGhBEGNqO55bOJA8BVeOff+lWWiIHzV EkeV4Zhn2tT+5YOcaiyqzV3jac6wbVj6+TKEdCHugfRhpRne/6wRjkFFdxHmBkJOoxoz 1Qsw== X-Forwarded-Encrypted: i=1; AFNElJ+Yl9upQGNlen3XZcvwXbNQKOTlQaXynxmNJbG0msvU5Ty1aeVZzdp7m9niaWoAM565jOF3ol8R14l8+Gc=@vger.kernel.org X-Gm-Message-State: AOJu0YxgVrVmXTainC7swbPTp2yza0vm3TNWlxMkjmfj0mb+S36dhDro 2VgOdYvAsm4u32q4QVTXXPro7JUFwcHYNtChhCxlu9g0absv97BQVdDc X-Gm-Gg: AeBDiesy00DLABzAI/yfiXClGZMqxrS0WHCZHqXlWNImVofPub98pvWR0S8Mb9LPgDH OAhDdeFwJCFYgifXhE9bGLZn8Gq7GcMrqvAv34j/X3spUeKuTthNjbJ3V9X6NQ+TFaCypkwA+E9 qjbfi4iMUUYc//RhNmgzcFNDvK7BugK0V0ZLL/C9+HAQCumDyk/IvihCJPRhApT4vx46xPrjHQL tCGSLeflmutv5te6tIqttd+73fAF0ZJLsCKBsAfhDYPwIM/3JiL4NsbQLLnlPDGbWX/41TufAJB S31QCNoYRogGrkaIyU33PUgYG8K/Xp11R91M0uksCm94dKcFzJm9AA6fmRLMZivaZRoklcgBTr6 bR7jRAyb4/DanrYry+fTuanhPZetoB112fMnSUW7h6Ai94x3VS3kfd5jph0XfsfUZPXZTVIWJod tdrJ3J0gJJarOU3gOYakL3RzQ= X-Received: by 2002:a05:600c:41cc:b0:489:1c1f:35e6 with SMTP id 5b1f17b1804b1-48e51e0bc24mr17870485e9.6.1778050145887; Tue, 05 May 2026 23:49:05 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48e53891d62sm38398835e9.1.2026.05.05.23.49.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 May 2026 23:49:05 -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 v6 1/6] dt-bindings: leds: Document TI LM3560 Synchronous Boost Flash Driver Date: Wed, 6 May 2026 09:48:42 +0300 Message-ID: <20260506064847.37795-2-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260506064847.37795-1-clamor95@gmail.com> References: <20260506064847.37795-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 Reviewed-by: Conor Dooley --- .../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..6cf8cf91ab2e --- /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: 56250 + maximum: 900000 + led-max-microamp: + minimum: 28125 + maximum: 225000 + + - 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: 62500 + maximum: 1000000 + led-max-microamp: + minimum: 31250 + maximum: 250000 + +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 Sat Jun 13 17:03:46 2026 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (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 C9044369217 for ; Wed, 6 May 2026 06:49:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050150; cv=none; b=WP4XUlJuOftLil7DVhcQpp4gQW3p0AWZycNEj6cxfNOW2Oh/YbUZMIeALx9H5aPCIj+eVDvdw4u0lUFK+TLKGx+vhnkw/0ZnOChtvZvfOT+Tfj0BS9byH2Oguc2M1NEOBEwS7jdRlI2lkLdj2AQO3wQfWeCyd0AIbuCA+OjXQsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050150; c=relaxed/simple; bh=/aTZ7FfNJUxGAerV0GyNvRYzlJf90me3mmU4zDgewOs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qMqobYASXI9dO8VMuDIRUCtn01UlxqFfFGSepNqdquU4nGJImT5Ct+PzoVARzexBLFyfsck9oq/zjuR+p2VHhmqsehbHqeyO01ieGfZfOcgU18zXXTAjHteQn9FKNn/tblSpzvfpZ6z299AzuWMHOsEjF9Yc7CQVy3PA5WqK4k4= 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=ioIPtAWd; arc=none smtp.client-ip=209.85.128.48 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="ioIPtAWd" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-48896199cbaso52755465e9.1 for ; Tue, 05 May 2026 23:49:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778050147; x=1778654947; 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=ioIPtAWdgpZO/HahDRHEtmCPXbnoFdJHICYIPBbqRhmIe2dtghDjWcdCcQY95MJ7bd g6MMnSHIx1n7/PZ18GV1YUY6HvyiNrAz63CKKSlxyBFOspkLcJuk4Rloee5eyC1vuZlk TRElA42ngbe+yp8QMptnbUzKqxVFsjIWtKtCHibbolAP90DEDFfj8fHv8QBt72z/RnQp H1t7VcTtTOVxr/hRTVY3wM0E+XGKbvPEnadNHUnjZ00RBw0msSFJ3Mu1nnBh8W6FoT3c KwcbFbUqXRfMkbqEsMzCfNlcSP2XVNMq7BRx+d3eRydGb++jWlJLBP/A2VMuPyeJHjBe 5XjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778050147; x=1778654947; 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=kc9vMZFDUZQfbAhZ7ecwfL8QKSOjVff55lKVwzpdoK1BrXSLQZKFBJTGgAY72CQv7l G+9VhKGogu+dml0QX1CkQ6HQWdo6eGkDFu+rzd6plmUOYQysjmt9ykEknTkpbO8bGHj9 RVX4mrPvtP0+Kwu/6QCkn+avYv+YgEBTnjNt08D4ZHm3jkaCiIcYWu8PLOGu5rvb9+NP 53xyLeeZZ1HSyn2h3EQBEtgFKP5qe2uZ7IYVfVyA6o2f6zAKUgFNilBAYLorbdf/hBgF uKZienjwZfBU5hQQAsShrUhJ0LMaLB11aNdWGcIhpp+Vdw/UxZmxHF/ibmIUbgRYxqow fLKg== X-Forwarded-Encrypted: i=1; AFNElJ/5yalCBVExRkggiB5EqFNlvJ0VhE7f93cw+oRe00JFkSgl9dGINm5rKGEenuVmXfxvZFBCsiJ4CfDpPeY=@vger.kernel.org X-Gm-Message-State: AOJu0Yz2kVSuuBtVA93ez0G1lEbpYiU7jnVbw0o7t10wHDXQ0qzIwTJ6 AkGPczCmHEncGST7O0HJ9qCKRpBXc1ecVbxTi8PCj0d4NKpJN1lUNoZs X-Gm-Gg: AeBDievnzEZ/P7wErteVJpwcvUoLxdQvRIclifl44uUzWiUoN7y3WD/X1/PLYQmm1YN CA7/8k4k3yrJjSXnnG5qVkTEfB1owpUxvGnyHfEL53zWiHDZVtn9wonOubIKFIIVuq4eXWXAQtr C6byxk3nzgqwVKsktQMEYqy7nc0Q8D9bIqRrjfOcSTjdckEJrlIA+SKp7qxPfKRapZso6kLW5hy hru8cPICSIcNf5ztJ+04uC+mG3B9pl/eysi3iSvOdCwhgTLuYIO0o2yK419Kifzb3nplSKybLjo wnnYv8LQUEUripoE0f7ecPiN63fT6lWaY/R/JGvcwiid7eF4J5tYNPry2Kvozjn7B40hbXTX+mO LwV4R2slhCvjYrmpVvEmZN+hLZJJTh5fhBGuHYfgzQc6d/EDVGKoyeSQshQ5Bwz780YoQwDgZut unHWpCOrH048nsDr6Zfxs2E4o= X-Received: by 2002:a05:600c:3e05:b0:488:9ed3:1492 with SMTP id 5b1f17b1804b1-48e51f2a997mr38200825e9.10.1778050147183; Tue, 05 May 2026 23:49:07 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48e53891d62sm38398835e9.1.2026.05.05.23.49.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 May 2026 23:49:06 -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 v6 2/6] media: i2c: lm3560: Fix v4l2 subdev registration Date: Wed, 6 May 2026 09:48:43 +0300 Message-ID: <20260506064847.37795-3-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260506064847.37795-1-clamor95@gmail.com> References: <20260506064847.37795-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 Sat Jun 13 17:03:46 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.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 49B7136C592 for ; Wed, 6 May 2026 06:49:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050152; cv=none; b=GKTKNM+Wa2UaCqBWY6YyjPfmkrxVwkW3pBN1mGGLpWnnZ+cXJwUGCDN8zWxaRxcXaGSyeUItiqK/sBZjQOMOjES2+xQdvcUB5NU1Zjriw88qAgHZ1kjHwBfJHYmJ4ee6wB8Nq0kGkBNXbMued6wF6Be7KU6qVDkp/ju2guAo2cY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050152; c=relaxed/simple; bh=LRXlNS9x02z8g+CGxmATU/6gvHvDK0YuBVqtECCU2ME=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Oj79d4g73BsBp1so07X54rI+ey2IOdCUA30teTYA26tDmJ2lyFAFHvdbbfDM2gAm8cvSUzyv4GX6kYWdA3BkJ0zwijLIkuMzmppR5K6otw59rHR0LfsGrZHgqnEWpf2jMjYAC8Gtm/FlP8GxTuaDXbze7Fj9c0CFGCFesEKlqaU= 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=YwEXz4Pz; arc=none smtp.client-ip=209.85.128.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="YwEXz4Pz" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-4838c15e3cbso48502465e9.3 for ; Tue, 05 May 2026 23:49:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778050149; x=1778654949; 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=YwEXz4Pzty/l82umOVfQLn1ytJucYokbpH7jLwYuugLDPyvHkirQUCYwncQZpvqWQQ jCbAv27Mv6yFUm90kCMHtAxRM80+coU5/ZSPClG3zP/aCcW+O1m50DSxxaMPPVAaojjT sraGyH4Qu7XOvxb7WO1st01yK7bgAjjT23GfhWivW8Mjx/TMX8O9ipFlVL6rnm8YsAiA utJYo2PTfj5K0Te4sfmqUe3YFiQ/5pP3uxt4iAYiuqwYASrlYs+shLvTm6rzvSNHFtVy r5Xx1nkpLrdpvpziZr/09uB9rBdiDysPlVZIXp13lyAToN1oapuBQc7yKHQ1M1UAARkn SNtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778050149; x=1778654949; 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=GW0eS288YcD3FInYhjBFzpa52QN8DkfaoT/iG2cCFTfOXaCB6j9bhz0rbaSYVz5kIV +03S9ScxtQDG3VrFcLOc5HgjnooNGVJwL3V4mFV7OSyd2a+F3ajScYNuOtoKIuTg36TT 4xAvC3m013WHTtY5J0pGSYgIqfZflGMQnU8mrnxQ4SlLpO3siioyVP0BSCgqBWq3MZtz 7Ns5FofDf/2Ii8kTfUGzRKSvGInWmElNpBG0Ry1n3WvXHsbKTLa5mUHdarDQZa5OzRXp 9JVjIx1WlTU3AamGd08TXZxLLIo+11aJHvAZLjQ+n5FChRA0pXLLntvs2HqLV8GwHscs 7RqQ== X-Forwarded-Encrypted: i=1; AFNElJ9L8ac7bBsefREPWqdhmudCI5/Vak+oKke+eCEPD8ggbfVwYbl11X0eSnwlLTVULjaZF2BVGoTplTUHd7Q=@vger.kernel.org X-Gm-Message-State: AOJu0Yywpa3Il2OExGc2KkqtKZknXYQgS8L2AaCBpUC7mamh45edknmJ W7hOrxe36ef/4P9WoawlAOiKdu+a1oAiDq/aFiRVk+da6Qfwnq8Nlffz X-Gm-Gg: AeBDievOAevcH92genbpQDCQPdorijgWT5cTzBA0InLwA91D7g67ylDe3kruVgFec/a tWaJCJ1mVVmkK9NIE6dyNb1lkLSs23PIY313Vf/aHtcqe2EZWR8jBIGTj2vscpb27HZ43KESJ/4 gsWvAKrtry7oiMjPui+kZvTxUPKu/laEGQu35QUISYgc57tQ++x5/VWFTOJmg9/RWuxLdrWLK22 h1wtGnIurMuElf64N+C1qwrCTziCcJn9XqBh2cbSC80EAEQgvpVoIS81JwBrSBgn/rdmBlqaoZT vgcfcHGWTHjDgpY3i3f5DlqdCE1pENvWMOYHy6h6GgoPdYg6IIw+mWUirVUvBXcHBeReHxW2pjr SPuGE2nO4wr7Mn943YAa0IAcC62buwlxof3IaaMcaHANHR2kMTuAtqpjcsjrESa/MuC1bLZJbYh gUVjejOYMR4EtvS1FQ3Jzfs/8= X-Received: by 2002:a05:600c:608f:b0:489:1ba8:5be9 with SMTP id 5b1f17b1804b1-48e51f4b0e1mr36256855e9.29.1778050148544; Tue, 05 May 2026 23:49:08 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48e53891d62sm38398835e9.1.2026.05.05.23.49.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 May 2026 23:49:08 -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 v6 3/6] media: i2c: lm3560: Optimize mutex lock usage Date: Wed, 6 May 2026 09:48:44 +0300 Message-ID: <20260506064847.37795-4-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260506064847.37795-1-clamor95@gmail.com> References: <20260506064847.37795-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 Sat Jun 13 17:03:46 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (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 BCADF36D4F3 for ; Wed, 6 May 2026 06:49:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050153; cv=none; b=gLSF+dr6i+KE2qLySenCbqSnbNRpH/ZI9asNfqMSzfPK15Y8Ysw56qDE5rD/PwVQ4spxH61e/7u+H83g9vc8srZ0E8uHO1siiR5uhvsLOQuQIfhazCp1WQtHm5XiBp4K+w0aw4/iN04MqGpQWQkOLQ35JaifJUa5gF4QhxgSlho= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050153; c=relaxed/simple; bh=qRKhPdDsO/maMbVLPB7p07zW7WQkSqXfLzrV1M6rki4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d55Lc4QqolRn5Nq8yT31s/HsZu7oSci6iw6axEfE2SdTa82llxDswnY+b8HQebc7B4gYwkbyRLhhvQ2MXRBnGanZo7cEH99vpKz7D0T9I9S4VSP1OUyQfl+SBW14Gb0xxcp9JOuZ1VP0Ygu1aFBETrmjluoPnxJi6q7LKnIF4i4= 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=ljLT9wRY; arc=none smtp.client-ip=209.85.128.42 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="ljLT9wRY" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4891d7164ddso32643925e9.3 for ; Tue, 05 May 2026 23:49:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778050150; x=1778654950; 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=kS3QB3e6Q4E9+488tCJcJ7+sIbzQ0uDSTnIe3Kaky6s=; b=ljLT9wRYOlrTpodGm9dWyt5FHnKZEwdbyGWo1C505XS9MwqUoPdoa2zriOZTFDL0kn P2Tr9FBh5UtTtet6uaJ0ERGAP2jpPV6XswgNSUTl9Ce1YK7HD2Kyr/zBNPtMN0N4INHK AHQAjAqbEoWEiDl5XPZr3WW5qgNJJOsIb+LMZ4L1g3HLrI4nfCr8aU1Uw0Tka0YKXMuk oDtqo30bthNiQSZGo0V96MX2s6j7GlyV92kEyH9wGAN/i1rOB/qzlarE6a2oJKC0pASd vo83EMdMdZeGIUSAwH8t+u33oIWddKScngV90hOVFEAihTiy22bntUoVGWGnhZHEB888 FNHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778050150; x=1778654950; 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=kS3QB3e6Q4E9+488tCJcJ7+sIbzQ0uDSTnIe3Kaky6s=; b=gBdHRV4b6xDkm+A8QzRFOujLSrv2lKiJBPWuDLDVCweqAv6rBaV1nLPaRMGXmHrwoJ h5DFLMrGtQ/hl1ASIc7FCFeoHkdr7q63X62NwTd86m3yrynibIneh8gJmslzXhVF8V2K Ogz+sp6zaZYYzGU2ro4Dv+5Gixy2Dj9yBSbKUd66KVRn969VPgtqDiJ0YX3bz3lP+xLg nZVesdDAPYf+mLJhjmScIFYi/v4miFh7V1thgiVvcRjugtvxfHcYJlloJbJE8HdSHIrW U1Ri8McetTgHfbKv8m/5NfKeoUkUFqxad4lDCmum3PPe9ZErZdCX4x/jGfbWY6QgrLCY Sw1A== X-Forwarded-Encrypted: i=1; AFNElJ99cGlwqouA+m0CY5DSBRR64peQkcTx1f7iE0zvfh0LO9c0aCD4FJMxrKMKTA1PtgquOYy8lbL1Ru5MGb0=@vger.kernel.org X-Gm-Message-State: AOJu0Yx6bctrmZrVHrJjdYSqKtm3h+8fj6tRwDNqTGlhfvWwBJSpEl+w IwTXAwtIYc/v+y2P3ixqngg2DyIcp6aLWrjoAnG5Wx6OGWIgKtS6XjLp X-Gm-Gg: AeBDievvIX+hGxwo/k3QFHuE6jhPvDnUCZneRiPyUMForKDhAae/YyNR0MrBW7x2e2q 1Xo9KtcE866ASmDboY0S3pbi7VHRTbYfHS1P0OXpbtec1/Xt+Q3sNPBExntbwc67Lg09/7+m+N8 DPZUiciA3uIIZM8oPtHRX63OIOi6CAI0AI1Gf42m/WfC5iTkw4BsrG5vPPdNx9E9K26KeUWz0Fv AwmgsY2XI2C+dUC8nOsAgk1cJ1ryj9/9HI5wnG2RnSf+2kCedFEYQMLpozKXLWiB6+4MZMMNuEi RDvea69S2p50l/0TY3vrrotEYoABY9Mx6PXj8NYcZU3BkJEMEOOAE/SW8N4pDK3Yl8PpFYKZOhM UtKAlEjdRJu3LnAKg3OVtHIoZ+0KHnjr6/l2npyt/75BtS1aJD+wOQNVa6j5dfMKeOkSXd4CBwg nCH0MGTD27249JvctIPFGsEcY= X-Received: by 2002:a05:600c:1e8a:b0:488:fd7e:1063 with SMTP id 5b1f17b1804b1-48e51f4cdcdmr34799555e9.29.1778050149971; Tue, 05 May 2026 23:49:09 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48e53891d62sm38398835e9.1.2026.05.05.23.49.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 May 2026 23:49:09 -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 v6 4/6] media: i2c: lm3560: Convert to use OF bindings Date: Wed, 6 May 2026 09:48:45 +0300 Message-ID: <20260506064847.37795-5-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260506064847.37795-1-clamor95@gmail.com> References: <20260506064847.37795-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 | 141 ++++++++++++++++++++++++++----------- include/media/i2c/lm3560.h | 15 ---- 2 files changed, 100 insertions(+), 56 deletions(-) diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c index 5b568ed9536b..609fd0339345 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -9,11 +9,14 @@ * Ldd-Mlp */ =20 +#include #include #include #include #include +#include #include +#include #include #include #include @@ -43,22 +46,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 +283,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 +309,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 +353,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 fwnode_handle *fwnode) { 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 fwnode_handle_get(fwnode); rval =3D lm3560_init_controls(flash, led_no); if (rval) goto err_out; @@ -378,7 +395,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 +408,21 @@ 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); + u32 peak_ua; int rval; =20 flash =3D devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL); @@ -415,36 +435,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; + device_for_each_child_node_scoped(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 fwnode_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; + fwnode_property_read_u32(node, "flash-max-microamp", + &flash->max_flash_brt[reg]); + + flash->max_torch_brt[reg] =3D LM3560_TORCH_BRT_MIN; + fwnode_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 +508,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 +531,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 Sat Jun 13 17:03:46 2026 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F398D36896F for ; Wed, 6 May 2026 06:49:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050155; cv=none; b=Z2I+W7LkfYne+wRlVoAWGTVT3CpGFQ7K9L7HBII8zCVxvQl5kPgdPtQmxrxcXDB50k5mNUidqQS7pGzfJrwa4ncZOynWGPCCMfXJKTcGlEQzC5Piwnu59RuYTUUiUp30fYLvDDNDu8C/6qtbrHWWdZWs1J9QEOCt0VDHXRSCDHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050155; c=relaxed/simple; bh=89540iaVZSqku3rNQPcP/FeBt8NoJGP35+1Y9aLPSUU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MAdWYOR2MKGAVqqVhGfL9Zur/+MBOYGPs+SxRbtc1SGXDSXaoYZkJ5u+cKg/aU5yP0T3sDJk/rYlzUdhDV1bRShqFwP7rr6BSQbQKKZ6aUhKNc3RB5FFFKxC8SY5jAIkuEs9dwQdhxUBSmiwjJipkqxyM1IW5NvkeQ/MLiaC5m8= 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=T1yyYBiz; arc=none smtp.client-ip=209.85.128.44 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="T1yyYBiz" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-4891e5b9c1fso57791355e9.2 for ; Tue, 05 May 2026 23:49:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778050151; x=1778654951; 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=+1A33MEOc97LDWAJfo5ET+7oDF3PRcg1aKX3rJdiUA4=; b=T1yyYBizbjFa1qUhxJgT3uxyhg91vV5PaRcwt3JpYRu5PyjJ9QNiTf0sFI+3+LCETF SN7/czf04i/G6IZ+XFKuUaMLw6ASlZi4og4XRb/SnubourxkaKD2BjLf8AiFszFyWQvV iLheH+itIf32DjrSxFVsF/PmItGLk+5zMEhrm3fArCbUi4hDQarDuop4s2yUpiQ/Klt+ zjpAwMoZr1i0DtZ40XTVmyw4uqau2RXO3MCJraNFlVdPWTT/HUr229xxLeXSRdUfSBBJ X+Et1272S5qkzaJ+Lyqg3eu9nnZCdsVExuSeZoNlHc+vEUX55FPDCFRQ95sFs3wUxNmZ 7YDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778050151; x=1778654951; 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=+1A33MEOc97LDWAJfo5ET+7oDF3PRcg1aKX3rJdiUA4=; b=NW+sU7poDF82nTyVclNEjipumPq9W7Vvm9srBWBvn52F/oIxSgq3HN/MubEGWgoihh TVfv1JlZJHRBcNlR0Kfg7fpUt7G9wVYCtiBj6zXtDZHTDqD1w7uKFC9wU+0ZWbxHTZXz 2xYJ8eHd5C+NJ2jEM3L2lkwo/AlIhDTiMOdFaoO73J8Ub9nO1CMGRAcXI5MXV++//28e V55Ju7TRZAnoTcbUmcRfKVXB1q2NdNcE2y7WMKP2Z8INV3aZOkf6i4X5R12YByWFPM5+ VtfzReXbb+LoOiscG2uNKfBCR0y4jgx9u/m+ahRdCDFXVbEG3i3+kwKCCUFndFrqoS4/ 1wJw== X-Forwarded-Encrypted: i=1; AFNElJ/PRX1S70Ni20utccfqfSLbO8b49uGB7pWjQoGIFEmEghSGdw+AX+o5d20lYch3RCNk7aRxDO7S00cUgVE=@vger.kernel.org X-Gm-Message-State: AOJu0Yzug8wcdnvLKsdi2Wyq17IXc1RAf6jO4vq50w5WtA2g235vC1Wf m2YYnEEYDzBn4RjTwlYztx2BYnFGBZ3X44scO7brKcnypD+u9vMNdCuASrSFFQ== X-Gm-Gg: AeBDietcmLqX9fblyckgwnPwh20+0mtKPPXXmzJxhTVACtqwW1NLgPzX1+YPdM7kbS5 CcGROOTB1HJ5jzkXIgqRTKbDAV5K5EbkQr4WOwuGkhiGN7KCJ+OPAf4C03YNZBU+zQMddzg4/Lk ikoqeQHOxsbMlU9dwn59spkxz0wXO3O3LO3TvbzC4YNiL7P4shbFLUpp+jKEeqUx4C7udcTy2zC /Ih6VMV1Vqv7GRJx6XTfZMmTLqy10CnuQ5G1PBhnen2Qo9lq90kTxbge8rxM8ZLBYtwUNoYhkBp mST5tVqRDzlL0j0B04DagdAgArX47qx7aHyvlKSzuoCZBpNSPRUY0fknzOgcBH736ptwZK69Ha+ BK9m+fUd06z9R5d+mPFUS3LMUUjPQz3qf51TxooruGf2RZNcG2DlpIyHFwAB+DP1RXmy5uL15tP xt0XdMSrb3BrHGwFPrAuWUGXI= X-Received: by 2002:a05:600c:3208:b0:48a:75b9:b0bc with SMTP id 5b1f17b1804b1-48e51f46c07mr20345135e9.29.1778050151249; Tue, 05 May 2026 23:49:11 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48e53891d62sm38398835e9.1.2026.05.05.23.49.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 May 2026 23:49:10 -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 v6 5/6] media: i2c: lm3560: Add support for PM features Date: Wed, 6 May 2026 09:48:46 +0300 Message-ID: <20260506064847.37795-6-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260506064847.37795-1-clamor95@gmail.com> References: <20260506064847.37795-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 609fd0339345..49030bc0f441 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -12,12 +12,15 @@ #include #include #include +#include #include #include #include #include +#include #include #include +#include #include #include #include @@ -48,6 +51,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 @@ -62,6 +67,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]; @@ -176,12 +184,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_active(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) @@ -191,6 +204,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 @@ -200,6 +215,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_active(flash->dev)) + return 0; + switch (ctrl->id) { case V4L2_CID_FLASH_LED_MODE: flash->led_mode =3D ctrl->val; @@ -245,6 +263,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 @@ -408,6 +428,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; @@ -440,6 +492,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); @@ -467,9 +530,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 device_for_each_child_node_scoped(flash->dev, node) { u32 reg; @@ -490,10 +563,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); @@ -502,7 +575,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) @@ -510,8 +599,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" }, @@ -530,7 +633,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 Sat Jun 13 17:03:46 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.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 4CFE736E486 for ; Wed, 6 May 2026 06:49:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050156; cv=none; b=mcETCkknRwlqpCw0IZv3uz6alsTzXMWxiU/WMpHkl23NVzlUNC7NvdDu7Zal7dpindNHAGPftLULW/gQg4E62UwbgntwvejytCW+sETL3oanI0LKlnRhv8zZrVws2O2NELdE7fF7ENZHv/WhFaHyxHCf68wJXET2EQRvuQ9/aTY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778050156; c=relaxed/simple; bh=TMThTQo3yIw9ubNee6V0unpg1zKvURsJh6wm0IbVOkQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fk7i4fhurkudT4SKOdzlw0auo0yCe4I5aqC6oKOBUdqqfEfvXXDwI10E1cU5SSqDTJCTHfkb5VUsEWchZVXnMTAMEnCg8YauNhJz2rCKPrb0q84YCDs8IIQpK4Lw0vt8WI4x9n5jy31rloyFgCIRKp3a6V5VqlDizArSJMIZN3k= 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=gsA95KII; arc=none smtp.client-ip=209.85.128.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="gsA95KII" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-4891f625344so5689705e9.0 for ; Tue, 05 May 2026 23:49:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778050153; x=1778654953; 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=CTtL2NS35lfymU/+dj8+RyAAWq/AZ/bJ0227rifTUmU=; b=gsA95KIIHSc8m2uGbDyY14AXERZApu0JPQ3DWTYFJyvi6k6Bs3X8RmmHu94D+afHzG mJ/GL4gMxQr6xCtvyhc8wopJ65y46AcsVnrvTHsCCdQ7pB+JwLvMBVP+p+zcosSZE4Y2 LdDI8/oU3wrM3nUPpVALjxww54Sct3pqb/AfgtGqvX2Vdt01Ixcy1yA8cxJB7pl3pFKf tqhd66H9Xwxp/CORiqXfjZFZD1JjmbtMzjeiC1qvZxw3WXx8/+vpugn2eDL5ylrSPD1S AlaIOo+8Y6RKouOxkfrDwC+CC6SuHZ6cZbnILSz0MoGTVq6lkYONfI/FrLIu45X7K6wf 7Lzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778050153; x=1778654953; 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=CTtL2NS35lfymU/+dj8+RyAAWq/AZ/bJ0227rifTUmU=; b=YzmrN6yKLkPIof6Rtx/iMAfS8dMs9nM+Js2/9Hq2RsMmJ/s0sDnZaI/xsFLAwjerFT SsBCmc4i9ehmKuB92V/TbiXWDZhxU4CnnAAjArpH3n4L6ot19zerVIQxkOGlYQuO5VXU xLlxOybJF4CqRbbgXJbnV1Q3P+jAVsxudwmQf+PS0HEla92gNNbak97h6ZHW+4eU6H2S NFfV/bIDYb9vF/kbr7NEVVkPPBLtRVCgfazc9wcrnxZX+9dvsJuFh0ib1u0rRtUwUSXt EAFGvrVxXakzUYL3xLtElstywNx2T9EV5SeKvgqEZSRS1qpcgt9u9NkSkq5ifiva0BSa buQw== X-Forwarded-Encrypted: i=1; AFNElJ8lU92EQjJvE8uulZwmxFF/PoNbghM+0a297vB50p3RqeDQTb9mm+FmzDdrEO7fXKPS2emm9/ymBw5/o5w=@vger.kernel.org X-Gm-Message-State: AOJu0YxFdWTDdGqFRCo5HP68krjmhrla2J5GySJo/W+kLHuGPC6nXT1e QX07hfIs9AXhICzJo9q4xTmdxBz44YctrEJmMkG8cuAQ+lyL3RCZr9tR X-Gm-Gg: AeBDieve/49aLTjP0+gDKo9xf/mZYglDosFKqppTPI8bbiCWvT7SCPrb2E+YGt0ygND zB6wvJo2D/31LVF59yHdURgpV7kSEjFfcuYIUzXQdDWG8BeqkJ8KeXGI2NIvyKGyBiOk1aNfXMO O3K50i7c9z0Vcb8Zf2V+/CROMTAngt07iqL8a1VWtOCbR7MDFDMo6jyzhNL/zRpBI1YueDcEUcV yCFkyTWLKCNTn11JkxzOLuCcwKPdwquADyFRISeJcuIL98ZdzVYvp1IDB3XZwUNOa9OVzZCnikD F0sPaMlQ7fk97TvhFcY0E8CGJE+oOnpHZFtxuabhsDYBFEKLxWo7QSBK6nKAcBXsodsh4mO3gCx 3GCpSNeWEMiup2xvUd7N2nDsq+YeI03ky8vLaP5Ukwy63jIC6AGUTZjGEQ8ng/cuL4H3LvoQ97O dsxu2HoODqWUiCdnbfHsK7keQ= X-Received: by 2002:a05:600c:c11c:b0:485:3c2e:60d5 with SMTP id 5b1f17b1804b1-48e5226c4f0mr20936315e9.2.1778050152566; Tue, 05 May 2026 23:49:12 -0700 (PDT) Received: from xeon ([188.163.112.56]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48e53891d62sm38398835e9.1.2026.05.05.23.49.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 May 2026 23:49:12 -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 v6 6/6] media: i2c: lm3560: Add proper support for LM3559 Date: Wed, 6 May 2026 09:48:47 +0300 Message-ID: <20260506064847.37795-7-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260506064847.37795-1-clamor95@gmail.com> References: <20260506064847.37795-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 49030bc0f441..46d316a26e50 100644 --- a/drivers/media/i2c/lm3560.c +++ b/drivers/media/i2c/lm3560.c @@ -22,9 +22,9 @@ #include #include #include -#include #include #include +#include =20 /* registers definitions */ #define REG_ENABLE 0x10 @@ -39,12 +39,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 * @@ -61,6 +93,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; @@ -81,6 +114,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) \ @@ -136,15 +171,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); @@ -159,15 +199,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); @@ -307,6 +352,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 @@ -335,13 +381,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, @@ -481,6 +527,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); @@ -507,16 +557,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; @@ -545,6 +605,7 @@ static int lm3560_probe(struct i2c_client *client) pm_runtime_enable(flash->dev); =20 device_for_each_child_node_scoped(flash->dev, node) { + const struct lm3560_flash_config *config =3D flash->config; u32 reg; =20 rval =3D fwnode_property_read_u32(node, "reg", ®); @@ -553,11 +614,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; fwnode_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; fwnode_property_read_u32(node, "led-max-microamp", &flash->max_torch_brt[reg]); =20 @@ -615,24 +676,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