From patchwork Wed Jan 8 14:13:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dzmitry Sankouski X-Patchwork-Id: 855854 Received: from mail-ed1-f44.google.com (mail-ed1-f44.google.com [209.85.208.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 D9DA21FCFE5; Wed, 8 Jan 2025 14:14:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736345655; cv=none; b=r87/ME+hmd5gpUkTDyDKvmI70AVBWRubFkuY4SgCPHVDJY+uCOo2f64hzeQLy3pT6DEjuQP73qadsXj0sIbDaB3cii87Tcy7h0kYs29ae9HURQk18iSZHROpUiSNr5elBFVJt2/+fUqf17zNwg7ZSZkgYPvBFzM3UGNqbpK4z7Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736345655; c=relaxed/simple; bh=rXMMoUEBWsz761qBBGBqdbWKIdj1EFYCUeoxnRId9F4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BNEjnmG9yhxgFk8hCaXKJcIRKid5NXCwVXrolw70L6KFdhSChxg0e3A7m12Jbqsqv2w2lbGhLdQscBDwduYiOs8uYWvIDa1wJ77vAj+6oir6OIHVllaxRiTt4fK26v0PbH62KoMCfWY3ES6ei/JjPolv6YraqWj7Yst6Y5SYJt0= 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=PxQFBD72; arc=none smtp.client-ip=209.85.208.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="PxQFBD72" Received: by mail-ed1-f44.google.com with SMTP id 4fb4d7f45d1cf-5d122cf8e52so29173127a12.1; Wed, 08 Jan 2025 06:14:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1736345645; x=1736950445; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=EemsH4Zp9goG/DvipUIIJ+D3oeBJrKh5E5A6/JLDo5M=; b=PxQFBD72e8NItd+MGfy3dSFK+Ex6z7DFe/A1RRTlvVOe3VaHOd+x2grJQIo0nIGTGQ FL7woUePR8T8pPkpL6u7mf1PlFRdFA+xEaXZGznr3urFkF+cyMeu2uRI40t71TnP+047 Yd3LUSVKaJGhazh+KTQZvm35z8aiuKE6MYSzyBk4jqKDcExg3YnFF8azyPIlP5ip4r2z 5y+f8zBMqS8+VE0rhs65/aPFR3w9tcDqj16GNAj+dZYXcUDZHPFsGf2IRoo9gE9Dc14o u8I7ZmlbSBHSLn9uMmXugRuP+XNBnpc8rIFbSr4lPUaYJZqPAReqJvwayN7kj/FANDFl 4aag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736345645; x=1736950445; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EemsH4Zp9goG/DvipUIIJ+D3oeBJrKh5E5A6/JLDo5M=; b=r9L72RiJ35q5f0m7QJnsGXCTeZHNcL3qcfKab1hqIYRpisuF+NZzgefWUsI7xJ47Es /zca/GKlxkuHDvoqaPfpqMt4Vvra5rHke3gp9MVX7yMIl9ZdM7qWt8FyxLczDWK/l2ae Tug98hCjVc3w2xmtApxSR3d3ww3gcUbuS0GS16ie7bfs07SW0OPBL/Fbb+35+bRLNLPM 1BXrxlD8HqApk+rU7HtKtSMRe9X4TfsbbxJfc0IqgMrNlP3XE+wbjjYgwmi/6zN1DDul tsLzGTQwVZMOKAnMp68t5ZeGevrefMkPkGmf/UUzjEZwYSK5B9b+ipUiopRpb1HkLyTy 18rA== X-Forwarded-Encrypted: i=1; AJvYcCVqUfSDOheXHp/SMSB0y6s+bBOtrhDt7Pn4GrpLwDO0g6izacotPffb/CjPZluBIe44aBkOQR4BD8E5zA==@vger.kernel.org, AJvYcCWQv3kBBKcOmZqmbZyIilBWEH8aI0QaalLMjG6GQKIh7Owm6jn0zK4V/jpQV/pvIdourWsgrFCLrX38ZP0=@vger.kernel.org, AJvYcCWgsFSQEZiu23vfQ6Z/93jlU9Q80A4ClcivPWu5Qw/4mE/ZLF+ja+9ZjJXuxgLvbn4ZxzDx8Jlu5Gmfh7T9@vger.kernel.org, AJvYcCXxdz9J48VHm5rtlAbgedpIikdrDmap6j1DDSeOD+1MeCmMe/T5WzSk6PROjlRhEqsssx3p5Lm4li9x@vger.kernel.org X-Gm-Message-State: AOJu0YxHCvknQR6abRArdtqAyer3aw4RHoiAp+0dRIeihSIGwEr3uUNn gx+CqPNwa9iQDnvlgj0Z0toy/d48+Z61XGGzbiMLGetpsvghtzdv X-Gm-Gg: ASbGncvd8GiXXg0RcZg0zHvj6ZhTtYvVqlvJUQAO680Duc6oDBxaeEcwfGKAHuvjQua dlc2W0aQnCDaVQ514VZLllRFl7176k1/pLrWftBZxPfLFmCdZFoCZOQX0nXil3bh9qSlNAT4hwd EzaMXJlpJEle7DvtDwTrwEPXih6N2QhZ6Avs82GPZqat5hmBb4e05AWXLvCNVVjwYfatYotJbJb 6HHDFz4VECE+94wcE8GrjVIH+HqWQtNah8OZweohZZwgKS7hZ+bqBocQfNcT+SslOMkkPQmE8a5 0H1TIA/KENpbHs9Thvr/4aAnKA== X-Google-Smtp-Source: AGHT+IHNZ3x4Qg1guN0mFGBLUwQ0UfGE4wfr8PtLRJoeoCMH8PVgsbHcC3T2WJvOzUPGUn5sR26MAg== X-Received: by 2002:a05:6402:400e:b0:5d2:729f:995b with SMTP id 4fb4d7f45d1cf-5d972e479cdmr2637523a12.24.1736345644702; Wed, 08 Jan 2025 06:14:04 -0800 (PST) Received: from [127.0.1.1] (nat6-minsk-pool-46-53-210-232.telecom.by. [46.53.210.232]) by smtp.googlemail.com with ESMTPSA id a640c23a62f3a-aac0efe4941sm2500562666b.95.2025.01.08.06.14.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jan 2025 06:14:04 -0800 (PST) From: Dzmitry Sankouski Date: Wed, 08 Jan 2025 17:13:45 +0300 Subject: [PATCH v14 01/10] power: supply: add undervoltage health status property Precedence: bulk X-Mailing-List: linux-leds@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250108-starqltechn_integration_upstream-v14-1-f6e84ec20d96@gmail.com> References: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> In-Reply-To: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> To: Sebastian Reichel , Chanwoo Choi , Krzysztof Kozlowski , Lee Jones , Rob Herring , Conor Dooley , Dmitry Torokhov , Pavel Machek , Hans de Goede , Marek Szyprowski , Sebastian Krzyszkowiak , Purism Kernel Team , Krzysztof Kozlowski Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org, Dzmitry Sankouski X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1736345640; l=2343; i=dsankouski@gmail.com; s=20240619; h=from:subject:message-id; bh=rXMMoUEBWsz761qBBGBqdbWKIdj1EFYCUeoxnRId9F4=; b=u0iBcG7nsI6h8j9uqJCQ8PuqHdAoS53jQuDQrv45uvjmKffYLhZl6hC6GXVKkI6iBVY9i7DwU wLlW3PgxpP8DNXQtXQW2FXNq4BiIPOONby7a65fkNGW8knf80779HCV X-Developer-Key: i=dsankouski@gmail.com; a=ed25519; pk=YJcXFcN1EWrzBYuiE2yi5Mn6WLn6L1H71J+f7X8fMag= Add POWER_SUPPLY_HEALTH_UNDERVOLTAGE status for power supply to report under voltage lockout failures. Signed-off-by: Dzmitry Sankouski --- Changes for v5: - update Documentation/ABI/testing/sysfs-class-power and drivers/power/supply/power_supply_sysfs.c --- Documentation/ABI/testing/sysfs-class-power | 2 +- drivers/power/supply/power_supply_sysfs.c | 1 + include/linux/power_supply.h | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-class-power b/Documentation/ABI/testing/sysfs-class-power index cb53dde20a80..2a5c1a09a28f 100644 --- a/Documentation/ABI/testing/sysfs-class-power +++ b/Documentation/ABI/testing/sysfs-class-power @@ -453,7 +453,7 @@ Description: Valid values: "Unknown", "Good", "Overheat", "Dead", - "Over voltage", "Unspecified failure", "Cold", + "Over voltage", "Under voltage", "Unspecified failure", "Cold", "Watchdog timer expire", "Safety timer expire", "Over current", "Calibration required", "Warm", "Cool", "Hot", "No battery" diff --git a/drivers/power/supply/power_supply_sysfs.c b/drivers/power/supply/power_supply_sysfs.c index 9ce5eda24093..edb058c19c9c 100644 --- a/drivers/power/supply/power_supply_sysfs.c +++ b/drivers/power/supply/power_supply_sysfs.c @@ -99,6 +99,7 @@ static const char * const POWER_SUPPLY_HEALTH_TEXT[] = { [POWER_SUPPLY_HEALTH_OVERHEAT] = "Overheat", [POWER_SUPPLY_HEALTH_DEAD] = "Dead", [POWER_SUPPLY_HEALTH_OVERVOLTAGE] = "Over voltage", + [POWER_SUPPLY_HEALTH_UNDERVOLTAGE] = "Under voltage", [POWER_SUPPLY_HEALTH_UNSPEC_FAILURE] = "Unspecified failure", [POWER_SUPPLY_HEALTH_COLD] = "Cold", [POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE] = "Watchdog timer expire", diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index c3ce9f2b17d4..6ed53b292162 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -60,6 +60,7 @@ enum { POWER_SUPPLY_HEALTH_OVERHEAT, POWER_SUPPLY_HEALTH_DEAD, POWER_SUPPLY_HEALTH_OVERVOLTAGE, + POWER_SUPPLY_HEALTH_UNDERVOLTAGE, POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, POWER_SUPPLY_HEALTH_COLD, POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE, From patchwork Wed Jan 8 14:13:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dzmitry Sankouski X-Patchwork-Id: 855855 Received: from mail-ed1-f50.google.com (mail-ed1-f50.google.com [209.85.208.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 4284A1FCFF5; Wed, 8 Jan 2025 14:14:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736345655; cv=none; b=nyoalskF/+9+PhGQv8DphnKtUPRtu1u6t2/ixj+GMmXLXqoDjb3ESciUkgOcmQiUeVL8obrT88uUvi1qBjjmE4HPposNZ6t0Xl7re4LOTFuCopF53CM1RgidukWDNFbE786Jg+bW9Lhrgkur7sTcJb/c5+Y2prSZXG0KJiVomwI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736345655; c=relaxed/simple; bh=LRRZ1LF62sUfrrQaRQZQnd6FxEzB6hrrJNyuB8N+gNI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TkGSD0upc7MpAaz7K2lGWxubbeKmSwefEArblnF6fh8XWjMB9fzQm0PyyphV1h5Vr8bgIOFR4MVkK26/TIDCjbZcK0ZdheJLildoHaOHE7bvRKtL3+nmHhWOSjncyWjRpHK6aJBEeiXp/nx5yDdHvqESozv+xwcVLVr+9mVSZ8k= 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=ZviKUWDl; arc=none smtp.client-ip=209.85.208.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="ZviKUWDl" Received: by mail-ed1-f50.google.com with SMTP id 4fb4d7f45d1cf-5d3f28881d6so24986170a12.1; Wed, 08 Jan 2025 06:14:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1736345646; x=1736950446; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=yyujKwEsNfDHScoNav6ae3GjHsN1+8L3jPXCGfk2bqY=; b=ZviKUWDlvHWzJC59FxpYs9kn0BGIPn+4v9AoasN2jzoTEo5v0BPC7gEFsr0Llb5Zf3 2PzT9XHS+nxFC8if6N74+XLnPMeiTOtEa4WSrly8Ab7fm2HNWSLv5sEHf5azDCcowPrT 4ykuov4VV6uupRKpQSYYqFByh/B5fQ+PtwO/1zFFMug5DUu5Uc9tug0ldEI/emDwj3Q+ dK47z20R9ZA0eXb8wINbJKUxTEkJt9OntwZX0W5y2/Hc8TANsuimFmfekFvKZEkq0t/Z qhKhSIdQK/NkOkgfBFnfFdQ/p6yftb5rbo0CnEh9SHqgfP+cZyiPZCcGTPQDVahIwG0E 8KUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736345646; x=1736950446; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yyujKwEsNfDHScoNav6ae3GjHsN1+8L3jPXCGfk2bqY=; b=qQAzIQNIMly/4Vft/BR6tRmFTypsnglhfRbl7Sdi7oV034tnCD98x20guNYM5yHhCT Roks0+vB9d5BX8rpEGkVK7xWy3xnp2hml+ZbEEeS0oYL/tU230hSzypANo7pBsNWXFi2 4drFH/3AMLGufd3dh4Ldd8yVr2uoqf7Nkaq0aw9lSNuE2pPE+Q/BjWBxhpj7b86OehMR e4Ud6k+AptylIe3B9a7mjTsUgXdiXAzC/vOS57UAim6JDkorfYk+29wXeHkldhdzJD3V CjpEAfO+8AY1wkdofc4no84+Z91g7ms0DIVSHMTcifVFMXBnBMpo22/6sN7Xei5tfYBS CYfg== X-Forwarded-Encrypted: i=1; AJvYcCW9el4xVyT0XWE/0Ss3ytBDWwXfj87LNOaG+dbkbSYu1kKTIqmdNkKLjS8+YTDKOUgAUl5V1PkObmr02A==@vger.kernel.org, AJvYcCWRoV+t+zqfPF+bnySQPisdcW3CLMKnPuJ2v2jUAxA5ZrBfJ4f7uGleHjxo7eD3Kq06ObuX94fmDt7e5GU=@vger.kernel.org, AJvYcCXg7NHCnBWi+p1JlpLcDJ4cf9L8iVeAQyt/k3OYlJXaBjTbMigzi7yIwcDoefRGhNfHgZc234uOyHIZ@vger.kernel.org, AJvYcCXlpXYgTQc4f81WAWaEMqLfgvhxMJWUOg04BaF9Jrt7oasVh3NmsH4y5BM4X1Uiveo62j0+5Cdq9+TYAg/c@vger.kernel.org X-Gm-Message-State: AOJu0YwEL5Dd/7VJzvZYJ8rKOounYX0+pY+B8l89Lr+0u807MRjOdgqU R69DKqMWRVUL5G20Rd/NVIA8FCZ4dHESU6wM25C/MrgXH1JkvRM+ X-Gm-Gg: ASbGncuCAFHqT3EAZyPWrJd8tLi+TB9GkPLqIjq0A9rHjVyyDmhtgxGTOYO2gM5R5D0 zXZ4M9lIGm1sQTIjbqiubed0sFtW8JQysFpJ1hrG0/CfdatUrD7Th3diz1Yxofma1EZd3IOPUgL zRB8OP0kF1qCMg92SsaqjNHtZTExQDhLZRTyegZOlm8PyafDa4Up7AEd4MLjSx7UuYTj5y0yUU+ cPoRa3iJpXd/G5LOpfvu+5gvjwBH0VFsNfYn+vJqsH0fV7IBCc5JjQJfXx3WaN2cLR7AzjAYtYg 9lpbiukCVJamqcqE5+9c8DH8sg== X-Google-Smtp-Source: AGHT+IGVM5pD1YcoKYnzP654hghnKgGHGlW/glRlDkDsJcU4SselCB7M3z74Cs4SO4Tf4FrZNUuH5g== X-Received: by 2002:a05:6402:35ca:b0:5d0:d818:559d with SMTP id 4fb4d7f45d1cf-5d972e0b954mr6919492a12.11.1736345645944; Wed, 08 Jan 2025 06:14:05 -0800 (PST) Received: from [127.0.1.1] (nat6-minsk-pool-46-53-210-232.telecom.by. [46.53.210.232]) by smtp.googlemail.com with ESMTPSA id a640c23a62f3a-aac0efe4941sm2500562666b.95.2025.01.08.06.14.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jan 2025 06:14:05 -0800 (PST) From: Dzmitry Sankouski Date: Wed, 08 Jan 2025 17:13:46 +0300 Subject: [PATCH v14 02/10] dt-bindings: power: supply: max17042: add max77705 support Precedence: bulk X-Mailing-List: linux-leds@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250108-starqltechn_integration_upstream-v14-2-f6e84ec20d96@gmail.com> References: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> In-Reply-To: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> To: Sebastian Reichel , Chanwoo Choi , Krzysztof Kozlowski , Lee Jones , Rob Herring , Conor Dooley , Dmitry Torokhov , Pavel Machek , Hans de Goede , Marek Szyprowski , Sebastian Krzyszkowiak , Purism Kernel Team , Krzysztof Kozlowski Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org, Dzmitry Sankouski , Krzysztof Kozlowski X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1736345640; l=906; i=dsankouski@gmail.com; s=20240619; h=from:subject:message-id; bh=LRRZ1LF62sUfrrQaRQZQnd6FxEzB6hrrJNyuB8N+gNI=; b=nlwz+W7BOSRQcqzk0vd9qZ7XPsoXHIGVqTz9Q48a7M/o8VyxKMa1YFk7CmcGpYA0OY0NO/Dfh PiWDngZDtUrDWJkqRMjJso2wSlVx2FfA/5GV/MBDqdlpMdOyZS2K9q9 X-Developer-Key: i=dsankouski@gmail.com; a=ed25519; pk=YJcXFcN1EWrzBYuiE2yi5Mn6WLn6L1H71J+f7X8fMag= Add max77705 fuel gauge support. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Dzmitry Sankouski --- Changes in v14: - add reviewed trailers Changes in v10: - keep alphabetical order --- Documentation/devicetree/bindings/power/supply/maxim,max17042.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max17042.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max17042.yaml index 085e2504d0dc..14242de7fc08 100644 --- a/Documentation/devicetree/bindings/power/supply/maxim,max17042.yaml +++ b/Documentation/devicetree/bindings/power/supply/maxim,max17042.yaml @@ -19,6 +19,7 @@ properties: - maxim,max17047 - maxim,max17050 - maxim,max17055 + - maxim,max77705-battery - maxim,max77849-battery reg: From patchwork Wed Jan 8 14:13:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dzmitry Sankouski X-Patchwork-Id: 855853 Received: from mail-ej1-f53.google.com (mail-ej1-f53.google.com [209.85.218.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 1B3C51FCFE4; Wed, 8 Jan 2025 14:14:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736345658; cv=none; b=J8SmJ7tefuCmSAzA2joXJVHU42Bqf8/QC46EiR4xEErzPB+y7hiaqoX/qvpw24b+tk9BJlBbNOG3zJlocwrTlgyCLseXtw72v3Kpw677DY78DqnVFLGMh0E7TPvublhMKU4ZlJZUCvE6/SIDr0xewsXwQtmh4k4l3vPzpVwnp2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736345658; c=relaxed/simple; bh=iiRnf4Wt6mhhESchgHXjPJDU1ILplxAAXBKmr7mHB+o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YxqQPBqO3HpWO4BtgNTgeBZrAeMYy4QEQuhX7h4z396lWl1EnuCq0NwGlyLuQHU596wuGWaEsk+M+j0vmYsCsP7nuIaBAyU+4pU91WPqi+3wneV4lVn08F4FiDO0A6wr2XndlJOHszjpUpSGtePJmJBIyR9etKzxlh5iVyGDH2M= 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=ZjqLBZpI; arc=none smtp.client-ip=209.85.218.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="ZjqLBZpI" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-aa6b4cc7270so2430176166b.0; Wed, 08 Jan 2025 06:14:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1736345651; x=1736950451; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=ny34XKwUX+MJKcT29KzUxMJWJuevNw9zT0IEL+SXaPw=; b=ZjqLBZpIzTOasYhyIQmAh1j1wagtq7WJzft6sJEu6e9X2EInf6m54G/G132/k2tRBf Pllnuy+EgHptzwLJySmh4szrPsZ6NF8opbBrZ5NyvZOCtpGoD/EgulOwCHjUzm3YZULz 6CTTjWxQVBYygA7K+0Zu75Q32cgrVG/D46S21vazJK3nMAUuVQhLn5wM3vS0armge3mw CfXd04h1OEES2YahluNtmlw8V0ZqqzcdRVHG3vjeW4VGPF/iWhbGYvQDu/iIUzhMy9iv RpV4g5Znx8/szghwawgV2LueF0by61f4gWGnkXrMPLk6EXKY4cyh5e1xBbnBVCDqB/0N D40g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736345651; x=1736950451; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ny34XKwUX+MJKcT29KzUxMJWJuevNw9zT0IEL+SXaPw=; b=XpjgDDryPjrWXCi/CeTKARHwcT+wGf/1gRBvfNBO8VzvyDv4soIBsaCHr411keFKsc HD0JezocDGvH//47K49jdku3aMrHR/AiHIpj/qauVcFBPlBjosiEmaZ3nHbnXSDQ52eV RQvCopKu7jT8G0y4btsmmL2HoUdRJH0k0Hg9TEWHkVYt4gE+ifPDFlms6v/Z7mYT5k+t VHqiBsFEiG1+ozQeFTt6IWb5AmSjMTQ5z1+J2sRPx2mVEDZ1nDykBFoWIBQHE2MwU86v GZi9mSyJ2+Eb3Ur+elcxOL8xGfUFVDZu6z4J0/WpQ95GdsOMSOheOXo8izKAZHLiQUtf wLJA== X-Forwarded-Encrypted: i=1; AJvYcCU27oGM9s+qoiDWMXFFKDSbrO4LhyTMpxCtl1R2g/CmMtkln909ciNnX326a4qO0uMjBSIGRZ3MT2CXEQkx@vger.kernel.org, AJvYcCUWWwimxxVgjUk5lAhdn/zwb3wy01Aj3QpJQRGhWEj2IjtXiSxv3OMf4eeeXRb1Mv6AWKShy8neFHt6eg==@vger.kernel.org, AJvYcCVTIINUIzkMgWyIMFdsW7nW9hv8oApwdXG2bvk2xmxgvnvy0iU8FCqmRzb15AYmpmT+42aWy44jTRnUPIo=@vger.kernel.org, AJvYcCXGrlomKoK6XgizNxuGMEv1Z2/woQWo5B17LohtyMEFmrjVX0JW8oXDqtTdlmHCXposr2hgMj2b5NFi@vger.kernel.org X-Gm-Message-State: AOJu0YzLNlGVTzwAJlCovs10gk0EtZGIj6UyEMpU7eOXAqdJflYQwUI6 bGJ78OWdoLk6tQvVU5Mtqa74K7VhBwyMIZat4aFgoxTPQ9BrZhla X-Gm-Gg: ASbGncu5LMo0mrjRWriPtn3lqpGF4E6ezvG9DOlaOvpzfc0vbQ3gPYXddmxAdpl1IqF X01MFIWerXT61n+Ny/WpV0G1JaWnmg1FEeytJhL4Rv33Tnir/mzTzBIFmCItXecYY/YqboSWS87 KnZx7D7JSnkPD+OJymNLlqWfOTS0TA/BrwyyW+5OGDOGgkFx7OLL6vzXF1u/glXo1DF3u3GJJfZ C3IyIclqcTyUYFRGlZWbKtCUkl7tCRPKupV/zC0bOE04bWEre4lr9DnZW3EJOmJVnIV1PaHBGlD osDBMOoGLhCidaxLhshkwupqHA== X-Google-Smtp-Source: AGHT+IHHnmhZ3qi0gyf3t368dwgvmTxBOD3hjh+LjlYRMGD9VRgDw+Egk9Cr6rifjtSwMfxE6RqAnQ== X-Received: by 2002:a05:6402:530f:b0:5d1:2377:5af3 with SMTP id 4fb4d7f45d1cf-5d972e00027mr5942480a12.5.1736345650625; Wed, 08 Jan 2025 06:14:10 -0800 (PST) Received: from [127.0.1.1] (nat6-minsk-pool-46-53-210-232.telecom.by. [46.53.210.232]) by smtp.googlemail.com with ESMTPSA id a640c23a62f3a-aac0efe4941sm2500562666b.95.2025.01.08.06.14.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jan 2025 06:14:10 -0800 (PST) From: Dzmitry Sankouski Date: Wed, 08 Jan 2025 17:13:49 +0300 Subject: [PATCH v14 05/10] power: supply: max17042: add max77705 fuel gauge support Precedence: bulk X-Mailing-List: linux-leds@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250108-starqltechn_integration_upstream-v14-5-f6e84ec20d96@gmail.com> References: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> In-Reply-To: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> To: Sebastian Reichel , Chanwoo Choi , Krzysztof Kozlowski , Lee Jones , Rob Herring , Conor Dooley , Dmitry Torokhov , Pavel Machek , Hans de Goede , Marek Szyprowski , Sebastian Krzyszkowiak , Purism Kernel Team , Krzysztof Kozlowski Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org, Dzmitry Sankouski X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1736345640; l=1366; i=dsankouski@gmail.com; s=20240619; h=from:subject:message-id; bh=iiRnf4Wt6mhhESchgHXjPJDU1ILplxAAXBKmr7mHB+o=; b=e3n/SJmIQ+m+1tqyYlTow66FpXac6IJetEnkckrhjejE7c3qZF7uIuJpA2bMBGh64zmAjiFPZ df67MVQELdoCTchlq/srtuCPIuK1Ly3UCRGCae4fQ/F1hXpoDkKEsbw X-Developer-Key: i=dsankouski@gmail.com; a=ed25519; pk=YJcXFcN1EWrzBYuiE2yi5Mn6WLn6L1H71J+f7X8fMag= Add max77705 fuel gauge support. Signed-off-by: Dzmitry Sankouski --- Changes in v12: - add only to platform version IDs Changes in v11: - add device type to compatible Changes in v10: - keep alphabetical order --- drivers/power/supply/max17042_battery.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c index 4037843e25bb..655b3f25dbd7 100644 --- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -1234,6 +1234,8 @@ static const struct of_device_id max17042_dt_match[] __used = { .data = (void *) MAXIM_DEVICE_TYPE_MAX17050 }, { .compatible = "maxim,max17055", .data = (void *) MAXIM_DEVICE_TYPE_MAX17055 }, + { .compatible = "maxim,max77705-battery", + .data = (void *) MAXIM_DEVICE_TYPE_MAX17047 }, { .compatible = "maxim,max77849-battery", .data = (void *) MAXIM_DEVICE_TYPE_MAX17047 }, { }, @@ -1256,6 +1258,7 @@ static const struct platform_device_id max17042_platform_id[] = { { "max17047", MAXIM_DEVICE_TYPE_MAX17047 }, { "max17050", MAXIM_DEVICE_TYPE_MAX17050 }, { "max17055", MAXIM_DEVICE_TYPE_MAX17055 }, + { "max77705-battery", MAXIM_DEVICE_TYPE_MAX17047 }, { "max77849-battery", MAXIM_DEVICE_TYPE_MAX17047 }, { } }; From patchwork Wed Jan 8 14:13:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dzmitry Sankouski X-Patchwork-Id: 855852 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (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 C5A8D1FDE07; Wed, 8 Jan 2025 14:14:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736345661; cv=none; b=BOyQ/GoHKiTlG9AyVZL9Oi27e29p/9MGv9meTW7+FZgUatH8UBuje4X3dIknpLQM4LjeoOYNwbBgohEvQgHm63fnQPBHfs1MYvgoQ7BjgUQkeg6J934qBTBmOksn72P6GEhDo4A+I6x4vFLOUD+nkZp8eSLXdHPN96ezngPjs7s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736345661; c=relaxed/simple; bh=CDRaw8FHbEGw/KbAZOWEuN4qBon9JzZ0D2kZ1D5rV2s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jbrz/wWvr5fCwDR+9yD37aMq4OpVzAO70RA0T801036ihu43K8PoHIkqhR/CQ1xxDldo1ywXFfjA0P7jKlTVKWB9ymUyxXkUeABzdC5q/+Ew7x3dqtd+SWKDr9cXUzM36CXir8h88d50cj4ix76tNHZtWJrvpMt22F4JtbYeKW8= 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=HQ1C4FN4; arc=none smtp.client-ip=209.85.218.49 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="HQ1C4FN4" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-ab2aea81cd8so131567466b.2; Wed, 08 Jan 2025 06:14:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1736345652; x=1736950452; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Fd0ibJeAMEqNXQZWLX/t2oT1/n+AscodZ4H+P8CNj4g=; b=HQ1C4FN4UH1AqqsG6EvPf8oZlCbEdqJereBaHHVkM/MikLJRX8rPkaUUVeHfdjR2m8 9x797tG9ckn4uWte//2WyGvAvNFFit/KY0viq6BiOJDJF1g7NQ6b0LLxRGM+r0Hs3dPp Dsi8wU+1y71ZEY8YrZ//cWq4fW7+00tUu/SZ7SQeaQDsltQSWKwuvZ/UnjjJCGiiR2yj LkrRUCy0304zLib7F2SXv1pAm3P2/rveFZ/vExgzU4i+dtHooxFhW/uamZU40kVuK2wE e9AJbgpbJwSsgI50Xn6gOMMu22V8wyabTQJg8Cy9fmwP4hOeEYs8cgR9JWtCOj5sTcRb NRbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736345652; x=1736950452; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Fd0ibJeAMEqNXQZWLX/t2oT1/n+AscodZ4H+P8CNj4g=; b=ClGDcetAeVHQd7AhExY2NMmXjS0znznuddA2uPDMPt+4klzqaBT/Fo025Srd0VIclr e456PkqKBgHr24zdqx3LLPonka7f8gN8abhXTcy7nfY0pxJv1/KIUAksLPHnQNi/DTQO 6Yl+jZh4XXMAWEYznhSjk8ZamQiSIRpJe6PfkawFQXcqqz+ZT5PIX1n/BgN9OW3s9Mta wzmfIAODZc67EemZMr9Ny+agK8M0fe27xvtXI2DrU1tKKigB8WLnaJY9SGu+F0GdG14N Jc8DebFSrPlB+d2W7ZdSK988gzJNGqLnlPuGpcl7lTmE5C0j38M0jCB1VkYHr+wBQFhn couQ== X-Forwarded-Encrypted: i=1; AJvYcCU0378BRWe6F7gDWiW1UNZ2pxhxHFCNkZfJKv7XNv9mHkpbnB2rexuCO7bKXDicad+CLcD04xnCZhe/AQ==@vger.kernel.org, AJvYcCUxZLT5eZJ4ocpEVuMYY0aCF5BiFWhU0Rj/dne5v9hvP3KrAxKj18K4g+rdE3OJN2tuM/vQrDdyxzIvGp+u@vger.kernel.org, AJvYcCVAyhAm7rRFLixDwnVL0spNuulZqkx1g04Jq5oMFDN+oyoJ7K8xziEMbLbncxPg3DM4hqUQWAcJMmznFbU=@vger.kernel.org, AJvYcCVh5hHdY/PXSufzqmAygTLbYfuGI/nmXekG5xkoR0Io2WY8eMHRVglEZVl5yEGGUW3hfT6KIgddJH0D@vger.kernel.org X-Gm-Message-State: AOJu0YwVK72m/q1gwqam6BHt33mHws5rX1uTlSLZamQhfmXhxS/o0UVr 8L39KRds3vn/9v7ohuT8EwZbXaNiRkahqhjzzh1APtRsxZGX6tnD X-Gm-Gg: ASbGnctycQeo0gx4bqW1sSJPFe795iLrZC17KRFAdO3Qi+vE9n3kmttRLe/1NQAp4Sh F1wmwhRsJoSCja7Ck5UmBiCVYxtcZ4rdRRY31DkmOPLz9ohgg6wQu9qT16ZRV7uMJvdEpoyC/J5 G6xwbgBkNjX6TOFCsUMBOp47iWcubakvSdSdPISO59yf0MfQOr8j9mcfsjW97caXWiklraM+nr8 FJM6FwYVP9yipqznKm1UeasvBotk/Remfp5C1jgHuweIS7/x3r9HtwBm1MvRGXZkWtfUe0LtjaR in2dW3ssxzJ4J1OAQUtHoLAo0A== X-Google-Smtp-Source: AGHT+IGCKGOiTmPUZkWQ6cMc1WECcqhOJR7m+VYQy196eG35vrT04uUACrwR9vd1azV5aimu3LfhfA== X-Received: by 2002:a17:907:1c10:b0:aa6:96ad:f903 with SMTP id a640c23a62f3a-ab2ab6fcf90mr208263966b.31.1736345652063; Wed, 08 Jan 2025 06:14:12 -0800 (PST) Received: from [127.0.1.1] (nat6-minsk-pool-46-53-210-232.telecom.by. [46.53.210.232]) by smtp.googlemail.com with ESMTPSA id a640c23a62f3a-aac0efe4941sm2500562666b.95.2025.01.08.06.14.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jan 2025 06:14:11 -0800 (PST) From: Dzmitry Sankouski Date: Wed, 08 Jan 2025 17:13:50 +0300 Subject: [PATCH v14 06/10] power: supply: max77705: Add charger driver for Maxim 77705 Precedence: bulk X-Mailing-List: linux-leds@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250108-starqltechn_integration_upstream-v14-6-f6e84ec20d96@gmail.com> References: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> In-Reply-To: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> To: Sebastian Reichel , Chanwoo Choi , Krzysztof Kozlowski , Lee Jones , Rob Herring , Conor Dooley , Dmitry Torokhov , Pavel Machek , Hans de Goede , Marek Szyprowski , Sebastian Krzyszkowiak , Purism Kernel Team , Krzysztof Kozlowski Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org, Dzmitry Sankouski X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1736345640; l=27410; i=dsankouski@gmail.com; s=20240619; h=from:subject:message-id; bh=CDRaw8FHbEGw/KbAZOWEuN4qBon9JzZ0D2kZ1D5rV2s=; b=zWIywdMkmt1T380G2CZXuh8IKq2249tmLhLcFndkt/rEJpALcPmPz/Vjw/qYJXV2GskIGTO04 qSnEs+Ju19RB6db1le49G1CxndHxdavE206JC4GoC1Tkk61UbpZzwml X-Developer-Key: i=dsankouski@gmail.com; a=ed25519; pk=YJcXFcN1EWrzBYuiE2yi5Mn6WLn6L1H71J+f7X8fMag= Add driver for Maxim 77705 switch-mode charger. It providing power supply class information to userspace. The driver is configured through DTS (battery and system related settings). Signed-off-by: Dzmitry Sankouski --- Changes in v12: - add missing new line - reorder max77705_charger_enable and max77705_charger_disable action - convert driver from platform to i2c, adjust commit msg accordingly Changes in v11: - remove multiple blank lines - return dev_err_probe - fit on one line where possible; Changes in v10: - never blank line between call and its error check - replace remove function with devm_add_action_or_reset - remove unused inline functions from header - use dev_err_probe for error handling Changes in v9: - move power supply registration before interrupts to prevent NULL exceptions when handling interrupts Changes for v8: - join lines, where fits 100 chars - change comment style C++ -> C - remove author from 'based on' file header statement Changes for v6: - add i2c init in driver - replace remove_new back on remove - handle IS_ERR(i2c_chg) Changes for v5: - remove const modifier from max77705_charger_irq_chip because it's modified with irq_drv_data in probe function - fix license to GPL 2.0 only, where old vendor code used GPL 2.0 only - move power header to power include dir - use same hardware name in Kconfig and module descriptions Changes for v4: - start from scratch - change word delimiters in filenames to '_' - use GENMASK in header - remove debugfs code - migrate to regmap_add_irq_chip - fix property getters to follow the same style --- drivers/power/supply/Kconfig | 6 ++ drivers/power/supply/Makefile | 1 + drivers/power/supply/max77705_charger.c | 576 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/power/max77705_charger.h | 194 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 777 insertions(+) diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 7b18358f194a..c120d8ed870f 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -583,6 +583,12 @@ config CHARGER_MAX77693 help Say Y to enable support for the Maxim MAX77693 battery charger. +config CHARGER_MAX77705 + tristate "Maxim MAX77705 battery charger driver" + depends on MFD_MAX77705 + help + Say Y to enable support for the Maxim MAX77705 battery charger. + config CHARGER_MAX77976 tristate "Maxim MAX77976 battery charger driver" depends on I2C diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index b55cc48a4c86..a4669383d53e 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_CHARGER_MAX14577) += max14577_charger.o obj-$(CONFIG_CHARGER_DETECTOR_MAX14656) += max14656_charger_detector.o obj-$(CONFIG_CHARGER_MAX77650) += max77650-charger.o obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o +obj-$(CONFIG_CHARGER_MAX77705) += max77705_charger.o obj-$(CONFIG_CHARGER_MAX77976) += max77976_charger.o obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o diff --git a/drivers/power/supply/max77705_charger.c b/drivers/power/supply/max77705_charger.c new file mode 100644 index 000000000000..563b41420c7c --- /dev/null +++ b/drivers/power/supply/max77705_charger.c @@ -0,0 +1,576 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Based on max77650-charger.c + * + * Copyright (C) 2024 Dzmitry Sankouski + * + * Battery charger driver for MAXIM 77705 charger/power-supply. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *max77705_charger_model = "max77705"; +static const char *max77705_charger_manufacturer = "Maxim Integrated"; + +static const struct regmap_config max77705_chg_regmap_config = { + .reg_base = MAX77705_CHG_REG_BASE, + .reg_bits = 8, + .val_bits = 8, + .max_register = MAX77705_CHG_REG_SAFEOUT_CTRL, +}; + +static enum power_supply_property max77705_charger_props[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_CHARGE_TYPE, + POWER_SUPPLY_PROP_HEALTH, + POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, +}; + +static int max77705_chgin_irq(void *irq_drv_data) +{ + struct max77705_charger_data *charger = irq_drv_data; + + queue_work(charger->wqueue, &charger->chgin_work); + + return 0; +} + +static const struct regmap_irq max77705_charger_irqs[] = { + { .mask = MAX77705_BYP_IM, }, + { .mask = MAX77705_INP_LIMIT_IM, }, + { .mask = MAX77705_BATP_IM, }, + { .mask = MAX77705_BAT_IM, }, + { .mask = MAX77705_CHG_IM, }, + { .mask = MAX77705_WCIN_IM, }, + { .mask = MAX77705_CHGIN_IM, }, + { .mask = MAX77705_AICL_IM, }, +}; + +static struct regmap_irq_chip max77705_charger_irq_chip = { + .name = "max77705-charger", + .status_base = MAX77705_CHG_REG_INT, + .mask_base = MAX77705_CHG_REG_INT_MASK, + .handle_post_irq = max77705_chgin_irq, + .num_regs = 1, + .irqs = max77705_charger_irqs, + .num_irqs = ARRAY_SIZE(max77705_charger_irqs), +}; + +static int max77705_charger_enable(struct max77705_charger_data *chg) +{ + int rv; + + rv = regmap_update_bits(chg->regmap, MAX77705_CHG_REG_CNFG_09, + MAX77705_CHG_EN_MASK, MAX77705_CHG_EN_MASK); + if (rv) + dev_err(chg->dev, "unable to enable the charger: %d\n", rv); + + return rv; +} + +static void max77705_charger_disable(void *data) +{ + struct max77705_charger_data *chg = data; + int rv; + + rv = regmap_update_bits(chg->regmap, + MAX77705_CHG_REG_CNFG_09, + MAX77705_CHG_EN_MASK, + MAX77705_CHG_DISABLE); + if (rv) + dev_err(chg->dev, "unable to disable the charger: %d\n", rv); +} + +static int max77705_get_online(struct regmap *regmap, int *val) +{ + unsigned int data; + int ret; + + ret = regmap_read(regmap, MAX77705_CHG_REG_INT_OK, &data); + if (ret < 0) + return ret; + + *val = !!(data & MAX77705_CHGIN_OK); + + return 0; +} + +static int max77705_check_battery(struct max77705_charger_data *charger, int *val) +{ + unsigned int reg_data; + unsigned int reg_data2; + struct regmap *regmap = charger->regmap; + + regmap_read(regmap, MAX77705_CHG_REG_INT_OK, ®_data); + + dev_dbg(charger->dev, "CHG_INT_OK(0x%x)\n", reg_data); + + regmap_read(regmap, MAX77705_CHG_REG_DETAILS_00, ®_data2); + + dev_dbg(charger->dev, "CHG_DETAILS00(0x%x)\n", reg_data2); + + if ((reg_data & MAX77705_BATP_OK) || !(reg_data2 & MAX77705_BATP_DTLS)) + *val = true; + else + *val = false; + + return 0; +} + +static int max77705_get_charge_type(struct max77705_charger_data *charger, int *val) +{ + struct regmap *regmap = charger->regmap; + unsigned int reg_data; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_09, ®_data); + if (!MAX77705_CHARGER_CHG_CHARGING(reg_data)) { + *val = POWER_SUPPLY_CHARGE_TYPE_NONE; + return 0; + } + + regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, ®_data); + reg_data &= MAX77705_CHG_DTLS; + + switch (reg_data) { + case 0x0: + case MAX77705_CHARGER_CONSTANT_CURRENT: + case MAX77705_CHARGER_CONSTANT_VOLTAGE: + *val = POWER_SUPPLY_CHARGE_TYPE_FAST; + return 0; + default: + *val = POWER_SUPPLY_CHARGE_TYPE_NONE; + return 0; + } + + return 0; +} + +static int max77705_get_status(struct max77705_charger_data *charger, int *val) +{ + struct regmap *regmap = charger->regmap; + unsigned int reg_data; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_09, ®_data); + if (!MAX77705_CHARGER_CHG_CHARGING(reg_data)) { + *val = POWER_SUPPLY_CHARGE_TYPE_NONE; + return 0; + } + + regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, ®_data); + reg_data &= MAX77705_CHG_DTLS; + + switch (reg_data) { + case 0x0: + case MAX77705_CHARGER_CONSTANT_CURRENT: + case MAX77705_CHARGER_CONSTANT_VOLTAGE: + *val = POWER_SUPPLY_STATUS_CHARGING; + return 0; + case MAX77705_CHARGER_END_OF_CHARGE: + case MAX77705_CHARGER_DONE: + *val = POWER_SUPPLY_STATUS_FULL; + return 0; + /* those values hard coded as in vendor kernel, because of */ + /* failure to determine it's actual meaning. */ + case 0x05: + case 0x06: + case 0x07: + *val = POWER_SUPPLY_STATUS_NOT_CHARGING; + return 0; + case 0x08: + case 0xA: + case 0xB: + *val = POWER_SUPPLY_STATUS_DISCHARGING; + return 0; + default: + *val = POWER_SUPPLY_STATUS_UNKNOWN; + return 0; + } + + return 0; +} + +static int max77705_get_vbus_state(struct regmap *regmap, int *value) +{ + int ret; + unsigned int charge_dtls; + + ret = regmap_read(regmap, MAX77705_CHG_REG_DETAILS_00, &charge_dtls); + if (ret) + return ret; + + charge_dtls = ((charge_dtls & MAX77705_CHGIN_DTLS) >> + MAX77705_CHGIN_DTLS_SHIFT); + + switch (charge_dtls) { + case 0x00: + *value = POWER_SUPPLY_HEALTH_UNDERVOLTAGE; + break; + case 0x01: + *value = POWER_SUPPLY_HEALTH_UNDERVOLTAGE; + break; + case 0x02: + *value = POWER_SUPPLY_HEALTH_OVERVOLTAGE; + break; + case 0x03: + *value = POWER_SUPPLY_HEALTH_GOOD; + break; + default: + return 0; + } + return 0; +} + +static int max77705_get_battery_health(struct max77705_charger_data *charger, + int *value) +{ + struct regmap *regmap = charger->regmap; + unsigned int bat_dtls; + + regmap_read(regmap, MAX77705_CHG_REG_DETAILS_01, &bat_dtls); + bat_dtls = ((bat_dtls & MAX77705_BAT_DTLS) >> MAX77705_BAT_DTLS_SHIFT); + + switch (bat_dtls) { + case MAX77705_BATTERY_NOBAT: + dev_dbg(charger->dev, "%s: No battery and the charger is suspended\n", + __func__); + *value = POWER_SUPPLY_HEALTH_NO_BATTERY; + break; + case MAX77705_BATTERY_PREQUALIFICATION: + dev_dbg(charger->dev, "%s: battery is okay but its voltage is low(~VPQLB)\n", + __func__); + break; + case MAX77705_BATTERY_DEAD: + dev_dbg(charger->dev, "%s: battery dead\n", __func__); + *value = POWER_SUPPLY_HEALTH_DEAD; + break; + case MAX77705_BATTERY_GOOD: + case MAX77705_BATTERY_LOWVOLTAGE: + *value = POWER_SUPPLY_HEALTH_GOOD; + break; + case MAX77705_BATTERY_OVERVOLTAGE: + dev_dbg(charger->dev, "%s: battery ovp\n", __func__); + *value = POWER_SUPPLY_HEALTH_OVERVOLTAGE; + break; + default: + dev_dbg(charger->dev, "%s: battery unknown\n", __func__); + *value = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; + break; + } + + return 0; +} + +static int max77705_get_health(struct max77705_charger_data *charger, int *val) +{ + struct regmap *regmap = charger->regmap; + int ret, is_online = 0; + + ret = max77705_get_online(regmap, &is_online); + if (ret) + return ret; + if (is_online) { + ret = max77705_get_vbus_state(regmap, val); + if (ret || (*val != POWER_SUPPLY_HEALTH_GOOD)) + return ret; + } + return max77705_get_battery_health(charger, val); +} + +static int max77705_get_input_current(struct max77705_charger_data *charger, + int *val) +{ + unsigned int reg_data; + int get_current = 0; + struct regmap *regmap = charger->regmap; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_09, ®_data); + + reg_data &= MAX77705_CHG_CHGIN_LIM_MASK; + + if (reg_data <= 3) + get_current = 100; + else if (reg_data >= MAX77705_CHG_CHGIN_LIM_MASK) + get_current = MAX77705_CURRENT_CHGIN_MAX; + else + get_current = (reg_data + 1) * 25; + + *val = get_current; + + return 0; +} + +static int max77705_get_charge_current(struct max77705_charger_data *charger, + int *val) +{ + unsigned int reg_data; + struct regmap *regmap = charger->regmap; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_02, ®_data); + reg_data &= MAX77705_CHG_CC; + + *val = reg_data <= 0x2 ? 100 : reg_data * 50; + + return 0; +} + +static int max77705_set_float_voltage(struct max77705_charger_data *charger, + int float_voltage) +{ + int float_voltage_mv; + unsigned int reg_data = 0; + struct regmap *regmap = charger->regmap; + + float_voltage_mv = float_voltage / 1000; + reg_data = float_voltage_mv <= 4000 ? 0x0 : + float_voltage_mv >= 4500 ? 0x23 : + (float_voltage_mv <= 4200) ? (float_voltage_mv - 4000) / 50 : + (((float_voltage_mv - 4200) / 10) + 0x04); + + return regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_04, + MAX77705_CHG_CV_PRM_MASK, + (reg_data << MAX77705_CHG_CV_PRM_SHIFT)); +} + +static int max77705_get_float_voltage(struct max77705_charger_data *charger, + int *val) +{ + unsigned int reg_data = 0; + struct regmap *regmap = charger->regmap; + + regmap_read(regmap, MAX77705_CHG_REG_CNFG_04, ®_data); + reg_data &= MAX77705_CHG_PRM_MASK; + *val = reg_data <= 0x04 ? reg_data * 50 + 4000 : + (reg_data - 4) * 10 + 4200; + + return 0; +} + +static int max77705_chg_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct max77705_charger_data *charger = power_supply_get_drvdata(psy); + struct regmap *regmap = charger->regmap; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + return max77705_get_online(regmap, &val->intval); + case POWER_SUPPLY_PROP_PRESENT: + return max77705_check_battery(charger, &val->intval); + case POWER_SUPPLY_PROP_STATUS: + return max77705_get_status(charger, &val->intval); + case POWER_SUPPLY_PROP_CHARGE_TYPE: + return max77705_get_charge_type(charger, &val->intval); + case POWER_SUPPLY_PROP_HEALTH: + return max77705_get_health(charger, &val->intval); + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: + return max77705_get_input_current(charger, &val->intval); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: + return max77705_get_charge_current(charger, &val->intval); + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: + return max77705_get_float_voltage(charger, &val->intval); + case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: + val->intval = charger->bat_info->voltage_max_design_uv; + break; + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = max77705_charger_model; + break; + case POWER_SUPPLY_PROP_MANUFACTURER: + val->strval = max77705_charger_manufacturer; + break; + default: + return -EINVAL; + } + return 0; +} + +static const struct power_supply_desc max77705_charger_psy_desc = { + .name = "max77705-charger", + .type = POWER_SUPPLY_TYPE_USB, + .properties = max77705_charger_props, + .num_properties = ARRAY_SIZE(max77705_charger_props), + .get_property = max77705_chg_get_property, +}; + +static void max77705_chgin_isr_work(struct work_struct *work) +{ + struct max77705_charger_data *charger = + container_of(work, struct max77705_charger_data, chgin_work); + + power_supply_changed(charger->psy_chg); +} + +static void max77705_charger_initialize(struct max77705_charger_data *chg) +{ + u8 reg_data; + struct power_supply_battery_info *info; + struct regmap *regmap = chg->regmap; + + if (power_supply_get_battery_info(chg->psy_chg, &info) < 0) + return; + + chg->bat_info = info; + + /* unlock charger setting protect */ + /* slowest LX slope */ + reg_data = MAX77705_CHGPROT_MASK | MAX77705_SLOWEST_LX_SLOPE; + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_06, reg_data, + reg_data); + + /* fast charge timer disable */ + /* restart threshold disable */ + /* pre-qual charge disable */ + reg_data = (MAX77705_FCHGTIME_DISABLE << MAX77705_FCHGTIME_SHIFT) | + (MAX77705_CHG_RSTRT_DISABLE << MAX77705_CHG_RSTRT_SHIFT) | + (MAX77705_CHG_PQEN_DISABLE << MAX77705_PQEN_SHIFT); + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_01, + (MAX77705_FCHGTIME_MASK | + MAX77705_CHG_RSTRT_MASK | + MAX77705_PQEN_MASK), + reg_data); + + /* OTG off(UNO on), boost off */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_00, + MAX77705_OTG_CTRL, 0); + + /* charge current 450mA(default) */ + /* otg current limit 900mA */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_02, + MAX77705_OTG_ILIM_MASK, + MAX77705_OTG_ILIM_900 << MAX77705_OTG_ILIM_SHIFT); + + /* BAT to SYS OCP 4.80A */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_05, + MAX77705_REG_B2SOVRC_MASK, + MAX77705_B2SOVRC_4_8A << MAX77705_REG_B2SOVRC_SHIFT); + /* top off current 150mA */ + /* top off timer 30min */ + reg_data = (MAX77705_TO_ITH_150MA << MAX77705_TO_ITH_SHIFT) | + (MAX77705_TO_TIME_30M << MAX77705_TO_TIME_SHIFT) | + (MAX77705_SYS_TRACK_DISABLE << MAX77705_SYS_TRACK_DIS_SHIFT); + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_03, + (MAX77705_TO_ITH_MASK | + MAX77705_TO_TIME_MASK | + MAX77705_SYS_TRACK_DIS_MASK), reg_data); + + /* cv voltage 4.2V or 4.35V */ + /* MINVSYS 3.6V(default) */ + if (info->voltage_max_design_uv < 0) { + dev_warn(chg->dev, "missing battery:voltage-max-design-microvolt\n"); + max77705_set_float_voltage(chg, 4200000); + } else { + max77705_set_float_voltage(chg, info->voltage_max_design_uv); + } + + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_12, + MAX77705_VCHGIN_REG_MASK, MAX77705_VCHGIN_4_5); + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_12, + MAX77705_WCIN_REG_MASK, MAX77705_WCIN_4_5); + + /* Watchdog timer */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_00, + MAX77705_WDTEN_MASK, 0); + + /* Active Discharge Enable */ + regmap_update_bits(regmap, MAX77705_PMIC_REG_MAINCTRL1, 1, 1); + + /* VBYPSET=5.0V */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_11, MAX77705_VBYPSET_MASK, 0); + + /* Switching Frequency : 1.5MHz */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_08, MAX77705_REG_FSW_MASK, + (MAX77705_CHG_FSW_1_5MHz << MAX77705_REG_FSW_SHIFT)); + + /* Auto skip mode */ + regmap_update_bits(regmap, MAX77705_CHG_REG_CNFG_12, MAX77705_REG_DISKIP_MASK, + (MAX77705_AUTO_SKIP << MAX77705_REG_DISKIP_SHIFT)); +} + +static int max77705_charger_probe(struct i2c_client *i2c) +{ + struct power_supply_config pscfg = {}; + struct max77705_charger_data *chg; + struct device *dev; + struct regmap_irq_chip_data *irq_data; + int ret; + + dev = &i2c->dev; + + chg = devm_kzalloc(dev, sizeof(*chg), GFP_KERNEL); + if (!chg) + return -ENOMEM; + + chg->dev = dev; + i2c_set_clientdata(i2c, chg); + + chg->regmap = devm_regmap_init_i2c(i2c, &max77705_chg_regmap_config); + if (IS_ERR(chg->regmap)) + return PTR_ERR(chg->regmap); + + ret = regmap_update_bits(chg->regmap, + MAX77705_CHG_REG_INT_MASK, + MAX77705_CHGIN_IM, 0); + if (ret) + return ret; + + pscfg.of_node = dev->of_node; + pscfg.drv_data = chg; + + chg->psy_chg = devm_power_supply_register(dev, &max77705_charger_psy_desc, &pscfg); + if (IS_ERR(chg->psy_chg)) + return PTR_ERR(chg->psy_chg); + + max77705_charger_irq_chip.irq_drv_data = chg; + ret = devm_regmap_add_irq_chip(chg->dev, chg->regmap, i2c->irq, + IRQF_ONESHOT | IRQF_SHARED, 0, + &max77705_charger_irq_chip, + &irq_data); + if (ret) + return dev_err_probe(dev, ret, "failed to add irq chip\n"); + + chg->wqueue = create_singlethread_workqueue(dev_name(dev)); + if (IS_ERR(chg->wqueue)) + return dev_err_probe(dev, PTR_ERR(chg->wqueue), "failed to create workqueue\n"); + + INIT_WORK(&chg->chgin_work, max77705_chgin_isr_work); + + max77705_charger_initialize(chg); + + ret = max77705_charger_enable(chg); + if (ret) + return dev_err_probe(dev, ret, "failed to enable charge\n"); + else + return devm_add_action_or_reset(dev, max77705_charger_disable, chg); +} + +static const struct of_device_id max77705_charger_of_match[] = { + { .compatible = "maxim,max77705-charger" }, + { } +}; +MODULE_DEVICE_TABLE(of, max77705_charger_of_match); + +static struct i2c_driver max77705_charger_driver = { + .driver = { + .name = "max77705-charger", + .of_match_table = max77705_charger_of_match, + }, + .probe = max77705_charger_probe, +}; +module_i2c_driver(max77705_charger_driver); + +MODULE_AUTHOR("Dzmitry Sankouski "); +MODULE_DESCRIPTION("Maxim MAX77705 charger driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/power/max77705_charger.h b/include/linux/power/max77705_charger.h new file mode 100644 index 000000000000..cb5cd03e54e2 --- /dev/null +++ b/include/linux/power/max77705_charger.h @@ -0,0 +1,194 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Maxim MAX77705 definitions. + * + * Copyright (C) 2015 Samsung Electronics, Inc. + * Copyright (C) 2024 Dzmitry Sankouski + */ + +#ifndef __MAX77705_CHARGER_H +#define __MAX77705_CHARGER_H __FILE__ + +/* MAX77705_CHG_REG_CHG_INT */ +#define MAX77705_BYP_I BIT(0) +#define MAX77705_INP_LIMIT_I BIT(1) +#define MAX77705_BATP_I BIT(2) +#define MAX77705_BAT_I BIT(3) +#define MAX77705_CHG_I BIT(4) +#define MAX77705_WCIN_I BIT(5) +#define MAX77705_CHGIN_I BIT(6) +#define MAX77705_AICL_I BIT(7) + +/* MAX77705_CHG_REG_CHG_INT_MASK */ +#define MAX77705_BYP_IM BIT(0) +#define MAX77705_INP_LIMIT_IM BIT(1) +#define MAX77705_BATP_IM BIT(2) +#define MAX77705_BAT_IM BIT(3) +#define MAX77705_CHG_IM BIT(4) +#define MAX77705_WCIN_IM BIT(5) +#define MAX77705_CHGIN_IM BIT(6) +#define MAX77705_AICL_IM BIT(7) + +/* MAX77705_CHG_REG_CHG_INT_OK */ +#define MAX77705_BYP_OK BIT(0) +#define MAX77705_DISQBAT_OK BIT(1) +#define MAX77705_BATP_OK BIT(2) +#define MAX77705_BAT_OK BIT(3) +#define MAX77705_CHG_OK BIT(4) +#define MAX77705_WCIN_OK BIT(5) +#define MAX77705_CHGIN_OK BIT(6) +#define MAX77705_AICL_OK BIT(7) + +/* MAX77705_CHG_REG_DETAILS_00 */ +#define MAX77705_BATP_DTLS BIT(0) +#define MAX77705_WCIN_DTLS GENMASK(4, 3) +#define MAX77705_WCIN_DTLS_SHIFT 3 +#define MAX77705_CHGIN_DTLS GENMASK(6, 5) +#define MAX77705_CHGIN_DTLS_SHIFT 5 + +/* MAX77705_CHG_REG_DETAILS_01 */ +#define MAX77705_CHG_DTLS GENMASK(3, 0) +#define MAX77705_CHG_DTLS_SHIFT 0 +#define MAX77705_BAT_DTLS GENMASK(6, 4) +#define MAX77705_BAT_DTLS_SHIFT 4 + +/* MAX77705_CHG_REG_DETAILS_02 */ +#define MAX77705_BYP_DTLS GENMASK(3, 0) +#define MAX77705_BYP_DTLS_SHIFT 0 + +/* MAX77705_CHG_REG_CNFG_00 */ +#define MAX77705_CHG_SHIFT 0 +#define MAX77705_UNO_SHIFT 1 +#define MAX77705_OTG_SHIFT 1 +#define MAX77705_BUCK_SHIFT 2 +#define MAX77705_BOOST_SHIFT 3 +#define MAX77705_WDTEN_SHIFT 4 +#define MAX77705_MODE_MASK GENMASK(3, 0) +#define MAX77705_CHG_MASK BIT(MAX77705_CHG_SHIFT) +#define MAX77705_UNO_MASK BIT(MAX77705_UNO_SHIFT) +#define MAX77705_OTG_MASK BIT(MAX77705_OTG_SHIFT) +#define MAX77705_BUCK_MASK BIT(MAX77705_BUCK_SHIFT) +#define MAX77705_BOOST_MASK BIT(MAX77705_BOOST_SHIFT) +#define MAX77705_WDTEN_MASK BIT(MAX77705_WDTEN_SHIFT) +#define MAX77705_UNO_CTRL (MAX77705_UNO_MASK | MAX77705_BOOST_MASK) +#define MAX77705_OTG_CTRL (MAX77705_OTG_MASK | MAX77705_BOOST_MASK) + +/* MAX77705_CHG_REG_CNFG_01 */ +#define MAX77705_FCHGTIME_SHIFT 0 +#define MAX77705_FCHGTIME_MASK GENMASK(2, 0) +#define MAX77705_CHG_RSTRT_SHIFT 4 +#define MAX77705_CHG_RSTRT_MASK GENMASK(5, 4) +#define MAX77705_FCHGTIME_DISABLE 0 +#define MAX77705_CHG_RSTRT_DISABLE 0x3 + +#define MAX77705_PQEN_SHIFT 7 +#define MAX77705_PQEN_MASK BIT(7) +#define MAX77705_CHG_PQEN_DISABLE 0 +#define MAX77705_CHG_PQEN_ENABLE 1 + +/* MAX77705_CHG_REG_CNFG_02 */ +#define MAX77705_OTG_ILIM_SHIFT 6 +#define MAX77705_OTG_ILIM_MASK GENMASK(7, 6) +#define MAX77705_OTG_ILIM_500 0 +#define MAX77705_OTG_ILIM_900 1 +#define MAX77705_OTG_ILIM_1200 2 +#define MAX77705_OTG_ILIM_1500 3 +#define MAX77705_CHG_CC GENMASK(5, 0) + +/* MAX77705_CHG_REG_CNFG_03 */ +#define MAX77705_TO_ITH_SHIFT 0 +#define MAX77705_TO_ITH_MASK GENMASK(2, 0) +#define MAX77705_TO_TIME_SHIFT 3 +#define MAX77705_TO_TIME_MASK GENMASK(5, 3) +#define MAX77705_SYS_TRACK_DIS_SHIFT 7 +#define MAX77705_SYS_TRACK_DIS_MASK BIT(7) +#define MAX77705_TO_ITH_150MA 0 +#define MAX77705_TO_TIME_30M 3 +#define MAX77705_SYS_TRACK_ENABLE 0 +#define MAX77705_SYS_TRACK_DISABLE 1 + +/* MAX77705_CHG_REG_CNFG_04 */ +#define MAX77705_CHG_MINVSYS_SHIFT 6 +#define MAX77705_CHG_MINVSYS_MASK GENMASK(7, 6) +#define MAX77705_CHG_PRM_SHIFT 0 +#define MAX77705_CHG_PRM_MASK GENMASK(5, 0) + +#define MAX77705_CHG_CV_PRM_SHIFT 0 +#define MAX77705_CHG_CV_PRM_MASK GENMASK(5, 0) + +/* MAX77705_CHG_REG_CNFG_05 */ +#define MAX77705_REG_B2SOVRC_SHIFT 0 +#define MAX77705_REG_B2SOVRC_MASK GENMASK(3, 0) +#define MAX77705_B2SOVRC_DISABLE 0 +#define MAX77705_B2SOVRC_4_5A 6 +#define MAX77705_B2SOVRC_4_8A 8 +#define MAX77705_B2SOVRC_5_0A 9 + +/* MAX77705_CHG_CNFG_06 */ +#define MAX77705_WDTCLR_SHIFT 0 +#define MAX77705_WDTCLR_MASK GENMASK(1, 0) +#define MAX77705_WDTCLR 1 +#define MAX77705_CHGPROT_MASK GENMASK(3, 2) +#define MAX77705_CHGPROT_UNLOCKED GENMASK(3, 2) +#define MAX77705_SLOWEST_LX_SLOPE GENMASK(6, 5) + +/* MAX77705_CHG_REG_CNFG_07 */ +#define MAX77705_CHG_FMBST 4 +#define MAX77705_REG_FMBST_SHIFT 2 +#define MAX77705_REG_FMBST_MASK BIT(MAX77705_REG_FMBST_SHIFT) +#define MAX77705_REG_FGSRC_SHIFT 1 +#define MAX77705_REG_FGSRC_MASK BIT(MAX77705_REG_FGSRC_SHIFT) + +/* MAX77705_CHG_REG_CNFG_08 */ +#define MAX77705_REG_FSW_SHIFT 0 +#define MAX77705_REG_FSW_MASK GENMASK(1, 0) +#define MAX77705_CHG_FSW_3MHz 0 +#define MAX77705_CHG_FSW_2MHz 1 +#define MAX77705_CHG_FSW_1_5MHz 2 + +/* MAX77705_CHG_REG_CNFG_09 */ +#define MAX77705_CHG_CHGIN_LIM_MASK GENMASK(6, 0) +#define MAX77705_CHG_EN_MASK BIT(7) +#define MAX77705_CHG_DISABLE 0 +#define MAX77705_CHARGER_CHG_CHARGING(_reg) \ + (((_reg) & MAX77705_CHG_EN_MASK) > 1) + + +/* MAX77705_CHG_REG_CNFG_10 */ +#define MAX77705_CHG_WCIN_LIM GENMASK(5, 0) + +/* MAX77705_CHG_REG_CNFG_11 */ +#define MAX77705_VBYPSET_SHIFT 0 +#define MAX77705_VBYPSET_MASK GENMASK(6, 0) + +/* MAX77705_CHG_REG_CNFG_12 */ +#define MAX77705_CHGINSEL_SHIFT 5 +#define MAX77705_CHGINSEL_MASK BIT(MAX77705_CHGINSEL_SHIFT) +#define MAX77705_WCINSEL_SHIFT 6 +#define MAX77705_WCINSEL_MASK BIT(MAX77705_WCINSEL_SHIFT) +#define MAX77705_VCHGIN_REG_MASK GENMASK(4, 3) +#define MAX77705_WCIN_REG_MASK GENMASK(2, 1) +#define MAX77705_REG_DISKIP_SHIFT 0 +#define MAX77705_REG_DISKIP_MASK BIT(MAX77705_REG_DISKIP_SHIFT) +/* REG=4.5V, UVLO=4.7V */ +#define MAX77705_VCHGIN_4_5 0 +/* REG=4.5V, UVLO=4.7V */ +#define MAX77705_WCIN_4_5 0 +#define MAX77705_DISABLE_SKIP 1 +#define MAX77705_AUTO_SKIP 0 + +/* mA */ +#define MAX77705_CURRENT_STEP 25 +#define MAX77705_CURRENT_WCIN_MAX 1600 +#define MAX77705_CURRENT_CHGIN_MAX 3200 + +struct max77705_charger_data { + struct device *dev; + struct regmap *regmap; + struct power_supply_battery_info *bat_info; + struct workqueue_struct *wqueue; + struct work_struct chgin_work; + struct power_supply *psy_chg; +}; + +#endif /* __MAX77705_CHARGER_H */ From patchwork Wed Jan 8 14:13:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dzmitry Sankouski X-Patchwork-Id: 855851 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 203B81FECD9; Wed, 8 Jan 2025 14:14:19 +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=1736345663; cv=none; b=AvP8H0jtkpS7hN1o/iqkSpM/kKB3rx+laJOolM4c8XG9l3pYbNooXVGPM6Ar9dXlzwW8Em1hwHtjJ8/LnElOQsfzd/K70EOeRIQULEhKcsmNX1M6Dq5r7bZkvFqCAu5/KUkoZG4e4KRQGz17zG1WTCJtuwwGROnYFrwlAAE0uKo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736345663; c=relaxed/simple; bh=Fh43QZccsW4SdyIXlbBXy28xwsiSEQt19p40YP8loqM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HAQACPj8W8myYJy4kSpd0u2Uh6SHoprphXdmyisjCFVwJ4TVUXRQXzbHxYiyLzS7fxVIL/4MtwqoM+KHlCcR8FDwEqjMiJXAgxg8uiIqoSmsB0mGwITt3lzHVzP16eCNMaIsLvbDjwxaH0b26stiv2bOaKr0cSBguekRK5FJXX4= 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=CSNGGYMb; 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="CSNGGYMb" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-aafc9d75f8bso455440266b.2; Wed, 08 Jan 2025 06:14:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1736345657; x=1736950457; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=7Ifx1TfYWGjlmF7namZNNx5Wk0qc8wlAl8x55ZdaF0U=; b=CSNGGYMb/06/Ox2z19lYAqhz7YlQTVw6FoABjC2fRszMRIaiHiCUUM0S9ndJW5EKic P4rfR0LDhi9OzVxIl3w+2V84JMkzP03xG/GZG6FuJ/0XJo16slcaZg1ORXaUWbD5+exo bBdaZEZwZgg8+ljvwbucb9ZV2xGyw1La9ZZ38z8ft2d777iLZdL6ayCyrGGwody/eBMg lJlYTpomTUCiBMR8C+oX2B4jrlnVeq6eBIby12z4EwsAwwaTScjGgRhXZBn5hsu/c2fV NWxbqD0PH10Xf6r/bYGMWUvZMNQKJC+qULv9W5HfnVF5L4OtiG+rrjzaOH69xp+y5mHG wQhg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736345657; x=1736950457; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7Ifx1TfYWGjlmF7namZNNx5Wk0qc8wlAl8x55ZdaF0U=; b=kGEO7daXIcSuF79kT7UiZHPEpFxRqFBAzsSIUkgxAeFHhF/L7TxGh7gNLre/uk42um 5a7zkqt/X1XuM5uKnXdYlTKbWcGVcvh2q5+O2G4yRl5/PyQSUe4w1WDEBFLItjU4AFoU TJ7UxvqjEfvl22kUSSF+G0tQXbBY/ETNyrQnItwl6x27DrgdEkS082R6qwDHSdEK4lLv SUqJOv/IUY64ZIsPBtI2wo7AEsY/dNvviCs01rHd3v/zCoCLinQO4j38cD/IWGVqQbqv AsfUKKvrWc6x3QAT35dfddGZie9oslgM8hLozcl1UsQcX4d+HsP0Htfd8eGxAxMDfyc7 75/g== X-Forwarded-Encrypted: i=1; AJvYcCVI/2s6hpmHGfbiKBrgHeakygal31cNjTEnHveTb2sBDNrapS1RcLZnzVtegV3x5zV1gmyypZ2nqBYEvQk=@vger.kernel.org, AJvYcCWH6XtmBLvIhh78VPV8EWP5dKz1jGPR8y/qy3QJqDNiAYXH0cDLL3T2wCdAnfrSkCXL+oBDpHK4GmWRpg==@vger.kernel.org, AJvYcCXDUGr90zzdmqnoWe86M8PUP4LltaphI0vPGlwBYOb6Xo9ggDg+i00YuPQLrJ2sScJUiK4kxcCzjMDAG6qO@vger.kernel.org, AJvYcCXvuZ/3pC+I3GqvNKR7+sSDQ6orxcVjihUQY9jS5l+ol4YgobzUMMBPrFvEn/bOMDTOcyCOJUlbpCVz@vger.kernel.org X-Gm-Message-State: AOJu0Ywxn3UYioK1PFu7PcvDxxoG3nMwKtPE7wuzxfeGq2ruXnKwZ5g2 gAr829tjJIR76DUW09GIeOKISxyLY1ZAIqg3co1dddfm+AukH00oiFtX5w== X-Gm-Gg: ASbGncsbqoqYeQePwyQ+8Gfnlj52nFURlTP0w2z4J8v7fpaJab09nbnkV0ZJczwEAAz idRXfXbVZY/frzmRDyLr2uy6+H4Gcqz+GW5dWVZc52/B2NGtPHzXFP2buUgWaJdKu/iXoBSoTgi q95qFgZ5vEHINaXDO0fdYoTqIsw/0tTvPL2CHAWHecgjr4Hpx1cT9oQgIOdghUTo3JS4z+GKXHq xPqNdFqdnDSGmRycdfNDRqZgcK6p7160OIUYKwqTzwzeVpdO/WD9eI+KFP1AfHTW5HUObYZn9k3 IOaLyFtcMq72FfThtOKYauaGZw== X-Google-Smtp-Source: AGHT+IH/g0bfxS4h9kzLhYCzYSbm2CrpXoIBfRz0vId3CWhMiMgUyFTV4XGSM/BVkD8RALkzxIAocQ== X-Received: by 2002:a17:907:720e:b0:aa6:6c08:dc79 with SMTP id a640c23a62f3a-ab2ab741567mr203332466b.35.1736345657243; Wed, 08 Jan 2025 06:14:17 -0800 (PST) Received: from [127.0.1.1] (nat6-minsk-pool-46-53-210-232.telecom.by. [46.53.210.232]) by smtp.googlemail.com with ESMTPSA id a640c23a62f3a-aac0efe4941sm2500562666b.95.2025.01.08.06.14.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jan 2025 06:14:16 -0800 (PST) From: Dzmitry Sankouski Date: Wed, 08 Jan 2025 17:13:54 +0300 Subject: [PATCH v14 10/10] leds: max77705: Add LEDs support Precedence: bulk X-Mailing-List: linux-leds@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250108-starqltechn_integration_upstream-v14-10-f6e84ec20d96@gmail.com> References: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> In-Reply-To: <20250108-starqltechn_integration_upstream-v14-0-f6e84ec20d96@gmail.com> To: Sebastian Reichel , Chanwoo Choi , Krzysztof Kozlowski , Lee Jones , Rob Herring , Conor Dooley , Dmitry Torokhov , Pavel Machek , Hans de Goede , Marek Szyprowski , Sebastian Krzyszkowiak , Purism Kernel Team , Krzysztof Kozlowski Cc: linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org, Dzmitry Sankouski X-Mailer: b4 0.14.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1736345640; l=12775; i=dsankouski@gmail.com; s=20240619; h=from:subject:message-id; bh=Fh43QZccsW4SdyIXlbBXy28xwsiSEQt19p40YP8loqM=; b=VdRGPxQgX/yaOmBmcRO34Ion1hdFpnCt1wagb/CRmJ3wtGVuDJRtO/7hlWFudJpnOarv0Z/di Q9cL63sjgfeDafOeKPGGzgjn6DPncpMxGLd146X2wuCLgCy1S9OGkH7 X-Developer-Key: i=dsankouski@gmail.com; a=ed25519; pk=YJcXFcN1EWrzBYuiE2yi5Mn6WLn6L1H71J+f7X8fMag= This adds basic support for LEDs for the max77705 PMIC. Signed-off-by: Dzmitry Sankouski --- Changes for v11: - add dependency on led multicolor class Changes for v10: - remove multiple line break - replace en_shift, reg_brightness values with macros - add support for leds-class-multicolor (inspired from leds-qcom-lpg.c): - replace max77705_to_led helper with container_of, because it's no longer covers all cases - add max77705_add_led, max77705_parse_subled functions to parse device tree - split max77705_led_brightness_set into *multi and *single versions Changes for v8: - join line where possible to fit in 100 chars - change comment style C++ -> C Changes for v6: - change compatible suffix to 'rgb' - remove I2C dependency in Kconfig - remove copyright and author from 'based on' header statement - replace MFD abbreviation with PMIC - MAINTAINERS: alphabetic order - max77705_rgb_blink: replace ternary operators with if..else if sequence - max77705_rgb_blink: move hardcoded numbers to constants - max77705_led_brightness_set: move ret to the bottom - s/map/regmap - replace device_for_each_child_node with scoped version - s/rv/ret Changes for v5: - use same hardware name in Kconfig and module descriptions - remove copyrighter owner from module authors Changes in v4: - inline BLINK_(ON|OFF) macro - remove camel case - drop backwards compatibility(new driver) - drop module alias --- MAINTAINERS | 1 + drivers/leds/Kconfig | 8 +++++ drivers/leds/Makefile | 1 + drivers/leds/leds-max77705.c | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/max77705-private.h | 17 ++++++++++ 5 files changed, 294 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index eb5222a833f8..13fe5f5aea77 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14290,6 +14290,7 @@ F: Documentation/devicetree/bindings/*/maxim,max77693.yaml F: Documentation/devicetree/bindings/*/maxim,max77705*.yaml F: Documentation/devicetree/bindings/*/maxim,max77843.yaml F: Documentation/devicetree/bindings/clock/maxim,max77686.txt +F: drivers/leds/leds-max77705.c F: drivers/*/*max77843.c F: drivers/*/max14577*.c F: drivers/*/max77686*.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 011216aa45cf..9677414a64c9 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -766,6 +766,14 @@ config LEDS_MAX77650 help LEDs driver for MAX77650 family of PMICs from Maxim Integrated. +config LEDS_MAX77705 + tristate "LED support for Maxim MAX77705 PMIC" + depends on MFD_MAX77705 + depends on LEDS_CLASS + depends on LEDS_CLASS_MULTICOLOR + help + LED driver for MAX77705 PMIC from Maxim Integrated. + config LEDS_MAX8997 tristate "LED support for MAX8997 PMIC" depends on LEDS_CLASS && MFD_MAX8997 diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 52bf8bf9c4ad..2e316e5e2f24 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_LEDS_LP8860) += leds-lp8860.o obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o obj-$(CONFIG_LEDS_MAX5970) += leds-max5970.o obj-$(CONFIG_LEDS_MAX77650) += leds-max77650.o +obj-$(CONFIG_LEDS_MAX77705) += leds-max77705.o obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o obj-$(CONFIG_LEDS_MENF21BMC) += leds-menf21bmc.o diff --git a/drivers/leds/leds-max77705.c b/drivers/leds/leds-max77705.c new file mode 100644 index 000000000000..15fa4b3cbcd6 --- /dev/null +++ b/drivers/leds/leds-max77705.c @@ -0,0 +1,267 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Based on leds-max77650 driver + * + * LED driver for MAXIM 77705 PMIC. + * Copyright (C) 2024 Dzmitry Sankouski + */ + +#include +#include +#include +#include +#include +#include +#include + +#define MAX77705_LED_NUM_LEDS 4 +#define MAX77705_LED_EN_MASK GENMASK(1, 0) +#define MAX77705_LED_MAX_BRIGHTNESS 0xff +#define MAX77705_LED_EN_SHIFT(reg) (reg * MAX77705_RGBLED_EN_WIDTH) +#define MAX77705_LED_REG_BRIGHTNESS(reg) (reg + MAX77705_RGBLED_REG_LED0BRT) + +struct max77705_led { + struct led_classdev cdev; + struct led_classdev_mc mcdev; + struct regmap *regmap; + + struct mc_subled *subled_info; +}; + +static int max77705_rgb_blink(struct led_classdev *cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct max77705_led *led = container_of(cdev, struct max77705_led, cdev); + int value, on_value, off_value; + + if (*delay_on < MAX77705_RGB_DELAY_100_STEP) + on_value = 0; + else if (*delay_on < MAX77705_RGB_DELAY_100_STEP_LIM) + on_value = *delay_on / MAX77705_RGB_DELAY_100_STEP - 1; + else if (*delay_on < MAX77705_RGB_DELAY_250_STEP_LIM) + on_value = (*delay_on - MAX77705_RGB_DELAY_100_STEP_LIM) / + MAX77705_RGB_DELAY_250_STEP + + MAX77705_RGB_DELAY_100_STEP_COUNT; + else + on_value = 15; + + on_value <<= 4; + + if (*delay_off < 1) + off_value = 0; + else if (*delay_off < MAX77705_RGB_DELAY_500_STEP) + off_value = 1; + else if (*delay_off < MAX77705_RGB_DELAY_500_STEP_LIM) + off_value = *delay_off / MAX77705_RGB_DELAY_500_STEP; + else if (*delay_off < MAX77705_RGB_DELAY_1000_STEP_LIM) + off_value = (*delay_off - MAX77705_RGB_DELAY_1000_STEP_LIM) / + MAX77705_RGB_DELAY_1000_STEP + + MAX77705_RGB_DELAY_500_STEP_COUNT; + else if (*delay_off < MAX77705_RGB_DELAY_2000_STEP_LIM) + off_value = (*delay_off - MAX77705_RGB_DELAY_2000_STEP_LIM) / + MAX77705_RGB_DELAY_2000_STEP + + MAX77705_RGB_DELAY_1000_STEP_COUNT; + else + off_value = 15; + + value = on_value | off_value; + return regmap_write(led->regmap, MAX77705_RGBLED_REG_LEDBLNK, value); +} + +static int max77705_led_brightness_set(struct regmap *regmap, struct mc_subled *subled, + int num_colors) +{ + int ret; + + for (int i = 0; i < num_colors; i++) { + unsigned int channel, brightness; + + channel = subled[i].channel; + brightness = subled[i].brightness; + + if (brightness == LED_OFF) { + /* Flash OFF */ + ret = regmap_update_bits(regmap, + MAX77705_RGBLED_REG_LEDEN, + MAX77705_LED_EN_MASK << MAX77705_LED_EN_SHIFT(channel), 0); + } else { + /* Set current */ + ret = regmap_write(regmap, MAX77705_LED_REG_BRIGHTNESS(channel), + brightness); + if (ret < 0) + return ret; + + ret = regmap_update_bits(regmap, + MAX77705_RGBLED_REG_LEDEN, + LED_ON << MAX77705_LED_EN_SHIFT(channel), + MAX77705_LED_EN_MASK << MAX77705_LED_EN_SHIFT(channel)); + } + } + + return ret; +} + +static int max77705_led_brightness_set_single(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct max77705_led *led = container_of(cdev, struct max77705_led, cdev); + + led->subled_info->brightness = brightness; + + return max77705_led_brightness_set(led->regmap, led->subled_info, 1); +} + +static int max77705_led_brightness_set_multi(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct led_classdev_mc *mcdev = lcdev_to_mccdev(cdev); + struct max77705_led *led = container_of(mcdev, struct max77705_led, mcdev); + + led_mc_calc_color_components(mcdev, brightness); + + return max77705_led_brightness_set(led->regmap, led->mcdev.subled_info, mcdev->num_colors); +} + +static int max77705_parse_subled(struct device *dev, struct fwnode_handle *np, + struct mc_subled *info) +{ + u32 color = LED_COLOR_ID_GREEN; + u32 reg; + int ret; + + ret = fwnode_property_read_u32(np, "reg", ®); + if (ret || !reg || reg >= MAX77705_LED_NUM_LEDS) + return dev_err_probe(dev, -EINVAL, "invalid \"reg\" of %pOFn\n", np); + + info->channel = reg; + + ret = fwnode_property_read_u32(np, "color", &color); + if (ret < 0 && ret != -EINVAL) + return dev_err_probe(dev, ret, + "failed to parse \"color\" of %pOF\n", np); + + info->color_index = color; + + return 0; +} + +static int max77705_add_led(struct device *dev, struct regmap *regmap, struct fwnode_handle *np) +{ + int ret, i = 0; + unsigned int color, reg; + struct max77705_led *led; + struct led_classdev *cdev; + struct mc_subled *info; + struct fwnode_handle *child; + struct led_init_data init_data = {}; + + led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); + if (!led) + return -ENOMEM; + + ret = fwnode_property_read_u32(np, "color", &color); + if (ret < 0 && ret != -EINVAL) + return dev_err_probe(dev, ret, + "failed to parse \"color\" of %pOF\n", np); + + led->regmap = regmap; + init_data.fwnode = np; + + if (color == LED_COLOR_ID_RGB) { + int num_channels = of_get_available_child_count(to_of_node(np)); + + ret = fwnode_property_read_u32(np, "reg", ®); + if (ret || reg >= MAX77705_LED_NUM_LEDS) + ret = -EINVAL; + + info = devm_kcalloc(dev, num_channels, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + cdev = &led->mcdev.led_cdev; + cdev->max_brightness = MAX77705_LED_MAX_BRIGHTNESS; + cdev->brightness_set_blocking = max77705_led_brightness_set_multi; + cdev->blink_set = max77705_rgb_blink; + + fwnode_for_each_available_child_node(np, child) { + ret = max77705_parse_subled(dev, child, &info[i]); + if (ret < 0) + return ret; + + info[i].intensity = 0; + i++; + } + + led->mcdev.subled_info = info; + led->mcdev.num_colors = num_channels; + led->cdev = *cdev; + + ret = devm_led_classdev_multicolor_register_ext(dev, &led->mcdev, &init_data); + if (ret) + return ret; + + ret = max77705_led_brightness_set_multi(&led->cdev, LED_OFF); + if (ret) + return ret; + } else { + info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + max77705_parse_subled(dev, np, info); + + led->subled_info = info; + led->cdev.brightness_set_blocking = max77705_led_brightness_set_single; + led->cdev.blink_set = max77705_rgb_blink; + led->cdev.max_brightness = MAX77705_LED_MAX_BRIGHTNESS; + + ret = devm_led_classdev_register_ext(dev, &led->cdev, &init_data); + if (ret) + return ret; + + ret = max77705_led_brightness_set_single(&led->cdev, LED_OFF); + if (ret) + return ret; + } + + return 0; +} + +static int max77705_led_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *regmap; + int ret; + + regmap = dev_get_regmap(dev->parent, NULL); + if (!regmap) + return -ENODEV; + + device_for_each_child_node_scoped(dev, child) { + ret = max77705_add_led(dev, regmap, child); + if (ret) + return ret; + } + + return 0; +} + +static const struct of_device_id max77705_led_of_match[] = { + { .compatible = "maxim,max77705-rgb" }, + { } +}; +MODULE_DEVICE_TABLE(of, max77705_led_of_match); + +static struct platform_driver max77705_led_driver = { + .driver = { + .name = "max77705-led", + .of_match_table = max77705_led_of_match, + }, + .probe = max77705_led_probe, +}; +module_platform_driver(max77705_led_driver); + +MODULE_DESCRIPTION("Maxim MAX77705 LED driver"); +MODULE_AUTHOR("Dzmitry Sankouski "); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/max77705-private.h b/include/linux/mfd/max77705-private.h index e4309d3b6f2a..41bc9d1188a9 100644 --- a/include/linux/mfd/max77705-private.h +++ b/include/linux/mfd/max77705-private.h @@ -33,6 +33,23 @@ #define MAX77705_SYSTEM_IRQ_SYSOVLO_INT BIT(5) #define MAX77705_SYSTEM_IRQ_TSHDN_INT BIT(6) #define MAX77705_SYSTEM_IRQ_TM_INT BIT(7) +/* MAX77705_RGBLED_REG_LEDEN register */ +#define MAX77705_RGBLED_EN_WIDTH 2 +/* MAX77705_RGBLED_REG_LEDBLNK register */ +#define MAX77705_RGB_DELAY_100_STEP_LIM 500 +#define MAX77705_RGB_DELAY_100_STEP_COUNT 4 +#define MAX77705_RGB_DELAY_100_STEP 100 +#define MAX77705_RGB_DELAY_250_STEP_LIM 3250 +#define MAX77705_RGB_DELAY_250_STEP 250 +#define MAX77705_RGB_DELAY_500_STEP 500 +#define MAX77705_RGB_DELAY_500_STEP_COUNT 10 +#define MAX77705_RGB_DELAY_500_STEP_LIM 5000 +#define MAX77705_RGB_DELAY_1000_STEP_LIM 8000 +#define MAX77705_RGB_DELAY_1000_STEP_COUNT 13 +#define MAX77705_RGB_DELAY_1000_STEP 1000 +#define MAX77705_RGB_DELAY_2000_STEP 2000 +#define MAX77705_RGB_DELAY_2000_STEP_COUNT 13 +#define MAX77705_RGB_DELAY_2000_STEP_LIM 12000 enum max77705_hw_rev { MAX77705_PASS1 = 1,