From patchwork Fri Jan 17 09:44:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Vaittinen, Matti" X-Patchwork-Id: 207383 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.3 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62612C3F68F for ; Fri, 17 Jan 2020 09:44:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 424402087E for ; Fri, 17 Jan 2020 09:44:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726706AbgAQJox (ORCPT ); Fri, 17 Jan 2020 04:44:53 -0500 Received: from mail-lf1-f65.google.com ([209.85.167.65]:46477 "EHLO mail-lf1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726343AbgAQJox (ORCPT ); Fri, 17 Jan 2020 04:44:53 -0500 Received: by mail-lf1-f65.google.com with SMTP id f15so17824292lfl.13; Fri, 17 Jan 2020 01:44:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=99ZtqX1Uu/dRFujV+nE2kCO8rxV/7AKg5X0Vce9bHGo=; b=IJuyhWWa4VKOIse7zY//cwogukg++W4g33wz/BOVXqKs9PrDgcAK7ZtGWgaJpXLYSY 2dL8c7wWGDmxbunlTuIIpX/irEn9PCQbg8bfpoHRK4BjbyHj8xXY8FE5lqj5CHEdi9SH PUs87SO78x9j3p02ds61/h0xW+ozJwUfJHAAhS1ydscXJE0iUp0Ufou2oDSxp1ScgcDK QhM81P3RqcJ8ea1vgrgPFZgF0ZR+5bbkMgPMTf8xtrON5RiQxoHt5UQ8WcJ1aarlRlOw pxaYLhkjpB4P/N5c1GErqebsC62+bzyhg6zjgXXc3/Am6UzoBCf8iOzJeC/3NnWD9zDi YwlA== X-Gm-Message-State: APjAAAVSbY7/uLTyWJEG69WRmEGJsJOei+bIfjj2WIa+Be7GFx0Xj+W9 w0g9oZURNmGwIRrK5DJIa9M= X-Google-Smtp-Source: APXvYqzEerwdHySXtkb2iXVMfOiAB5TCBDbSIAASYAhPIJ8I+0kUhXrmz1VWJT/C+kGqvU3BM81Z6w== X-Received: by 2002:ac2:599c:: with SMTP id w28mr4908038lfn.78.1579254290547; Fri, 17 Jan 2020 01:44:50 -0800 (PST) Received: from localhost.localdomain ([213.255.186.46]) by smtp.gmail.com with ESMTPSA id w9sm12027578ljh.106.2020.01.17.01.44.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jan 2020 01:44:50 -0800 (PST) Date: Fri, 17 Jan 2020 11:44:38 +0200 From: Matti Vaittinen To: matti.vaittinen@fi.rohmeurope.com, mazziesaccount@gmail.com Cc: Jacek Anaszewski , Pavel Machek , Dan Murphy , Rob Herring , Mark Rutland , Lee Jones , Michael Turquette , Stephen Boyd , Linus Walleij , Bartosz Golaszewski , Liam Girdwood , Mark Brown , Alessandro Zummo , Alexandre Belloni , Matti Vaittinen , linux-leds@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org Subject: [PATCH v10 13/13] led: bd71828: Support LED outputs on ROHM BD71828 PMIC Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.12.1 (2019-06-15) Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org ROHM BD71828 power management IC has two LED outputs for charge status and button pressing indications. The LED outputs can also be forced by SW so add driver allowing to use these LEDs for other indications as well. Leds are controlled by SW using 'Force ON' bits. Please note the constrains mentioned in data-sheet: 1. If one LED is forced ON - then also the other LED is forced. => You can't use SW control to force ON one LED and allow HW to control the other. 2. You can't force both LEDs OFF. If the FORCE bit for both LED's is zero, then LEDs are controlled by HW and indicate button/charger states as explained in data-sheet. Signed-off-by: Matti Vaittinen --- no changes since v9 drivers/leds/Kconfig | 10 +++ drivers/leds/Makefile | 1 + drivers/leds/leds-bd71828.c | 118 ++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 drivers/leds/leds-bd71828.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 4b68520ac251..db408e03e296 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -545,6 +545,16 @@ config LEDS_BD2802 This option enables support for BD2802GU RGB LED driver chips accessed via the I2C bus. +config LEDS_BD71828 + tristate "LED driver for LEDS on ROHM BD71828 PMIC" + depends on LEDS_CLASS + depends on MFD_ROHM_BD71828 + help + This option enables support for LED outputs located on ROHM + BD71828 power management IC. ROHM BD71828 has two led output pins + which can be left to indicate HW states or controlled by SW. Say + yes here if you want to enable SW control for these LEDs. + config LEDS_INTEL_SS4200 tristate "LED driver for Intel NAS SS4200 series" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 2da39e896ce8..a5164acfaf51 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_LEDS_AN30259A) += leds-an30259a.o obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o obj-$(CONFIG_LEDS_BCM6358) += leds-bcm6358.o obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o +obj-$(CONFIG_LEDS_BD71828) += leds-bd71828.o obj-$(CONFIG_LEDS_CPCAP) += leds-cpcap.o obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o diff --git a/drivers/leds/leds-bd71828.c b/drivers/leds/leds-bd71828.c new file mode 100644 index 000000000000..a02c2ac4a70b --- /dev/null +++ b/drivers/leds/leds-bd71828.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (C) 2019 ROHM Semiconductors + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BD71828_LED_TO_DATA(l) ((l)->id == ID_GREEN_LED ? \ + container_of((l), struct bd71828_leds, green) : \ + container_of((l), struct bd71828_leds, amber)) + +/* Names for led identification - these match the data sheet names */ +enum { + ID_GREEN_LED, + ID_AMBER_LED, + ID_NMBR_OF, +}; + +struct bd71828_led { + struct led_init_data init_data; + int id; + struct led_classdev l; + u8 force_mask; +}; + +struct bd71828_leds { + struct rohm_regmap_dev *bd71828; + struct bd71828_led green; + struct bd71828_led amber; +}; + +static int bd71828_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct bd71828_led *l = container_of(led_cdev, struct bd71828_led, l); + struct bd71828_leds *data; + unsigned int val = BD71828_LED_OFF; + + data = BD71828_LED_TO_DATA(l); + if (value != LED_OFF) + val = BD71828_LED_ON; + + return regmap_update_bits(data->bd71828->regmap, BD71828_REG_LED_CTRL, + l->force_mask, val); +} + +static int bd71828_led_probe(struct platform_device *pdev) +{ + struct rohm_regmap_dev *bd71828; + struct bd71828_leds *l; + struct bd71828_led *g, *a; + int ret; + + bd71828 = dev_get_drvdata(pdev->dev.parent); + l = devm_kzalloc(&pdev->dev, sizeof(*l), GFP_KERNEL); + if (!l) + return -ENOMEM; + l->bd71828 = bd71828; + a = &l->amber; + g = &l->green; + + /* Fill in details for 'AMBLED' */ + a->init_data.match_property.name = "rohm,led-compatible"; + a->init_data.match_property.raw_val = "bd71828-ambled"; + a->init_data.match_property.size = strlen("bd71828-ambled"); + a->id = ID_AMBER_LED; + a->force_mask = BD71828_MASK_LED_AMBER; + + /* Fill in details for 'GRNLED' */ + g->init_data.match_property.name = "rohm,led-compatible"; + g->init_data.match_property.raw_val = "bd71828-grnled"; + g->init_data.match_property.size = strlen("bd71828-grnled"); + g->id = ID_GREEN_LED; + g->force_mask = BD71828_MASK_LED_GREEN; + + a->l.brightness_set_blocking = bd71828_led_brightness_set; + g->l.brightness_set_blocking = bd71828_led_brightness_set; + + ret = devm_led_classdev_register_ext(&pdev->dev, &g->l, &g->init_data); + if (ret) + return ret; + + return devm_led_classdev_register_ext(&pdev->dev, &a->l, &a->init_data); +} + +/* + * Device is instantiated through parent MFD device and device matching is done + * through platform_device_id. + * + * However, the *module* matching will be done trough DT aliases. This requires + * of_device_id table - but no .of_match_table as *device* matching is still + * done through platform_device_id. + */ +static const struct of_device_id bd71828_dt_match[] __used = { + { .compatible = "rohm,bd71828-leds" }, + { } +}; +MODULE_DEVICE_TABLE(of, bd71828_dt_match); + +static struct platform_driver bd71828_led_driver = { + .driver = { + .name = "bd71828-led", + }, + .probe = bd71828_led_probe, +}; + +module_platform_driver(bd71828_led_driver); + +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_DESCRIPTION("ROHM BD71828 LED driver"); +MODULE_LICENSE("GPL");