All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Osipenko <digetx@gmail.com>
To: Lee Jones <lee.jones@linaro.org>,
	Rob Herring <robh+dt@kernel.org>,
	Thierry Reding <thierry.reding@gmail.com>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	Pavel Machek <pavel@ucw.cz>, Dan Murphy <dmurphy@ti.com>,
	Sebastian Reichel <sre@kernel.org>,
	Lubomir Rintel <lkundrak@v3.sk>
Cc: devicetree@vger.kernel.org, linux-tegra@vger.kernel.org,
	linux-leds@vger.kernel.org, linux-pm@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH v1 3/6] leds: Add driver for Acer Iconia Tab A500
Date: Sun, 23 Aug 2020 17:08:43 +0300	[thread overview]
Message-ID: <20200823140846.19299-4-digetx@gmail.com> (raw)
In-Reply-To: <20200823140846.19299-1-digetx@gmail.com>

Acer Iconia Tab A500 is an Android tablet device which has two LEDs
embedded into the Power Button. Orange LED indicates "battery charging"
status and white LED indicates "wake-up/charge-done" status. The new LED
driver provides control over both LEDs to userspace.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/leds/Kconfig          |   7 ++
 drivers/leds/Makefile         |   1 +
 drivers/leds/leds-acer-a500.c | 121 ++++++++++++++++++++++++++++++++++
 3 files changed, 129 insertions(+)
 create mode 100644 drivers/leds/leds-acer-a500.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 4f6464a169d5..4c39b53bcf1f 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -921,6 +921,13 @@ config LEDS_SGM3140
 	  This option enables support for the SGM3140 500mA Buck/Boost Charge
 	  Pump LED Driver.
 
+config LEDS_ACER_A500
+	tristate "Power button LED support for Acer Iconia Tab A500"
+	depends on LEDS_CLASS && MFD_ACER_A500_EC
+	help
+	  This option enables support for the Power Button LED of
+	  Acer Iconia Tab A500.
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 778cb4bb8c52..73e603e1727e 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_LEDS_TRIGGERS)		+= led-triggers.o
 # LED Platform Drivers (keep this sorted, M-| sort)
 obj-$(CONFIG_LEDS_88PM860X)		+= leds-88pm860x.o
 obj-$(CONFIG_LEDS_AAT1290)		+= leds-aat1290.o
+obj-$(CONFIG_LEDS_ACER_A500)		+= leds-acer-a500.o
 obj-$(CONFIG_LEDS_ADP5520)		+= leds-adp5520.o
 obj-$(CONFIG_LEDS_AN30259A)		+= leds-an30259a.o
 obj-$(CONFIG_LEDS_APU)			+= leds-apu.o
diff --git a/drivers/leds/leds-acer-a500.c b/drivers/leds/leds-acer-a500.c
new file mode 100644
index 000000000000..65e69a40a91a
--- /dev/null
+++ b/drivers/leds/leds-acer-a500.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Power button LED driver for Acer Iconia Tab A500.
+ *
+ * Copyright 2020 GRATE-driver project.
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/acer-ec-a500.h>
+
+struct a500_ec_led {
+	struct led_classdev cdev;
+	struct a500_ec_led *other_led;
+	const struct a500_ec_cmd *cmd;
+};
+
+/*					cmd	delay ms */
+A500_EC_COMMAND(RESET_LEDS,		0x40,	100);
+A500_EC_COMMAND(POWER_LED_ON,		0x42,	100);
+A500_EC_COMMAND(CHARGE_LED_ON,		0x43,	100);
+A500_EC_COMMAND(ANDROID_LEDS_OFF,	0x5A,	100);
+
+static int a500_ec_led_brightness_set(struct led_classdev *led_cdev,
+				      enum led_brightness value)
+{
+	struct device *a500_ec_leds_dev = led_cdev->dev->parent;
+	struct a500_ec *ec_chip = dev_get_drvdata(a500_ec_leds_dev->parent);
+	struct a500_ec_led *led = container_of(led_cdev, struct a500_ec_led,
+					       cdev);
+	int ret;
+
+	a500_ec_lock(ec_chip);
+
+	if (value) {
+		ret = a500_ec_write_locked(ec_chip, led->cmd, 0);
+	} else {
+		/*
+		 * There is no separate controls which can disable LEDs
+		 * individually, there is only RESET_LEDS command that turns
+		 * off both LEDs.
+		 */
+		ret = a500_ec_write_locked(ec_chip, RESET_LEDS, 0);
+		if (ret)
+			goto unlock;
+
+		led = led->other_led;
+
+		/* RESET_LEDS turns off both LEDs, thus restore other LED */
+		if (led->cdev.brightness == LED_ON)
+			ret = a500_ec_write_locked(ec_chip, led->cmd, 0);
+	}
+
+unlock:
+	a500_ec_unlock(ec_chip);
+
+	return ret;
+}
+
+static int a500_ec_leds_probe(struct platform_device *pdev)
+{
+	struct a500_ec *ec_chip = dev_get_drvdata(pdev->dev.parent);
+	struct a500_ec_led *white_led, *orange_led;
+	int err;
+
+	/* reset and turn off all LEDs */
+	a500_ec_write(ec_chip, RESET_LEDS, 0);
+	a500_ec_write(ec_chip, ANDROID_LEDS_OFF, 0);
+
+	white_led = devm_kzalloc(&pdev->dev, sizeof(*white_led), GFP_KERNEL);
+	if (!white_led)
+		return -ENOMEM;
+
+	white_led->cdev.name = "power-button-white";
+	white_led->cdev.brightness_set_blocking = a500_ec_led_brightness_set;
+	white_led->cdev.flags = LED_CORE_SUSPENDRESUME;
+	white_led->cdev.max_brightness = LED_ON;
+	white_led->cmd = &A500_EC_POWER_LED_ON;
+
+	orange_led = devm_kzalloc(&pdev->dev, sizeof(*orange_led), GFP_KERNEL);
+	if (!orange_led)
+		return -ENOMEM;
+
+	orange_led->cdev.name = "power-button-orange";
+	orange_led->cdev.brightness_set_blocking = a500_ec_led_brightness_set;
+	orange_led->cdev.flags = LED_CORE_SUSPENDRESUME;
+	orange_led->cdev.max_brightness = LED_ON;
+	orange_led->cmd = &A500_EC_CHARGE_LED_ON;
+
+	white_led->other_led = orange_led;
+	orange_led->other_led = white_led;
+
+	err = devm_led_classdev_register(&pdev->dev, &white_led->cdev);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register white LED\n");
+		return err;
+	}
+
+	err = devm_led_classdev_register(&pdev->dev, &orange_led->cdev);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register orange LED\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static struct platform_driver a500_ec_leds_driver = {
+	.driver = {
+		.name = "acer-a500-iconia-leds",
+	},
+	.probe = a500_ec_leds_probe,
+};
+module_platform_driver(a500_ec_leds_driver);
+
+MODULE_DESCRIPTION("LED driver for Acer Iconia Tab A500 Power Button");
+MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
+MODULE_ALIAS("platform:acer-a500-iconia-leds");
+MODULE_LICENSE("GPL v2");
-- 
2.27.0


  parent reply	other threads:[~2020-08-23 14:10 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-23 14:08 [PATCH v1 0/6] Introduce Embedded Controller driver for Acer A500 Dmitry Osipenko
2020-08-23 14:08 ` [PATCH v1 1/6] mfd: Add driver for Embedded Controller found on Acer Iconia Tab A500 Dmitry Osipenko
2020-08-23 18:16   ` Lubomir Rintel
2020-08-23 19:28     ` Dmitry Osipenko
2020-08-24  7:33       ` Lee Jones
2020-08-24 10:10         ` Dmitry Osipenko
2020-08-24 10:43           ` Lee Jones
2020-08-23 14:08 ` [PATCH v1 2/6] power: supply: Add battery gauge driver for " Dmitry Osipenko
2020-08-24 14:07   ` Sebastian Reichel
2020-08-24 18:55     ` Dmitry Osipenko
2020-08-24 21:38       ` Sebastian Reichel
2020-08-26  6:34         ` Dmitry Osipenko
2020-08-23 14:08 ` Dmitry Osipenko [this message]
2020-08-23 22:30   ` [PATCH v1 3/6] leds: Add " Pavel Machek
2020-08-24 10:11     ` Dmitry Osipenko
2020-08-24 11:38     ` Dmitry Osipenko
2020-08-23 22:34   ` Pavel Machek
2020-08-24 10:16     ` Dmitry Osipenko
2020-08-23 14:08 ` [PATCH v1 4/6] dt-bindings: mfd: ene-kb3930: Add compatibles for KB930 and Acer A500 Dmitry Osipenko
2020-08-23 18:20   ` Lubomir Rintel
2020-08-23 19:31     ` Dmitry Osipenko
2020-08-23 21:16       ` Lubomir Rintel
2020-08-24 10:09         ` Dmitry Osipenko
2020-09-08 21:53           ` Rob Herring
2020-09-08 22:01             ` Dmitry Osipenko
2020-08-23 14:08 ` [PATCH v1 5/6] dt-bindings: mfd: ene-kb3930: Document power-supplies and monitored-battery properties Dmitry Osipenko
2020-08-23 18:00   ` Lubomir Rintel
2020-08-23 14:08 ` [PATCH v1 6/6] ARM: tegra: acer-a500: Add Embedded Controller Dmitry Osipenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200823140846.19299-4-digetx@gmail.com \
    --to=digetx@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dmurphy@ti.com \
    --cc=jonathanh@nvidia.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=lkundrak@v3.sk \
    --cc=pavel@ucw.cz \
    --cc=robh+dt@kernel.org \
    --cc=sre@kernel.org \
    --cc=thierry.reding@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.