From patchwork Thu Jan 14 15:57:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 567544 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 80C59140BEB for ; Fri, 15 Jan 2016 02:59:36 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b=aXbshvoS; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2DAA7A7732; Thu, 14 Jan 2016 16:59:19 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lVTjCvkXDS0L; Thu, 14 Jan 2016 16:59:19 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id F1019A76FE; Thu, 14 Jan 2016 16:58:57 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 86CFEA75CF for ; Thu, 14 Jan 2016 16:58:43 +0100 (CET) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OPOl-h6yBKXa for ; Thu, 14 Jan 2016 16:58:43 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-ob0-f176.google.com (mail-ob0-f176.google.com [209.85.214.176]) by theia.denx.de (Postfix) with ESMTPS id 07868A7651 for ; Thu, 14 Jan 2016 16:58:38 +0100 (CET) Received: by mail-ob0-f176.google.com with SMTP id vt7so86565325obb.1 for ; Thu, 14 Jan 2016 07:58:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=PSeQgh3tzEDvK8FN7un7RWEpZ6Cl1nBgB6J9JQXHoXs=; b=aXbshvoS0pyGOIZ7b2zON3AePvi7Tc4x967U/EDsZSOcH4PdsWJoEJWED3a0CI5daX aIB4gGoD72Wsyr5Gn5P96idEvKDf3bGGInS9E5N2Do4ipUFQ3y0G7Td3gyDDLdkKek6k +JRp5c5YhpUa4Va40JW1H0HGREzdgv4PQ7BRALfUs305rZdPaAK8g/2KizbX5N6sP4FN +EuV5vc8YEkkLFKi0YnLnaKSE/CD/fb04Mn3weKChk8/KNzVCAAfjg7joUFbBnvqR2b/ dRDfvpGXE2mQsDPisVgSEdSMsYihegXzcL7tSfeGBoPjItnpCvKiHoHp+78noKguqFal 6qUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=PSeQgh3tzEDvK8FN7un7RWEpZ6Cl1nBgB6J9JQXHoXs=; b=c66dvMOmU+etgXOd9PeJVRu8NwTjOvujJYIoN6lIxlHebeQUHZ3GHOUOd7D+OFwmPV hLsYZd7rRTX/ZU+gaayBP8pLNoOLMPhPs6b3xeLp3dS+EAIJhZGm70o4RpypfI7mAE9i 0LJhSEjGe4OoqgsK8H0Aup83mTxeWiGx6g8wuPq2588sBJ1Xh3dYeetTR6lVOnC0ONke LEtkguPCgJty1uRhNhGGS7vg7Mxchk5ZBpIBKSzwWT0hQa1Xzo9l3cZy4peSPxJ32N7Y FxOTJ+oHRQUB+y/Utt0x4BBoa48AUURGQuRd9B8JiNJlk8U+81dV7k9qfUz1Gnn0nB4H Ru7w== X-Gm-Message-State: ALoCoQmFXNuN/XABn2ERCUD3X5Of68FPee3BEw249Ty5BVjnfVD/RZ2s7KfkyJTTbK38bzpkz91zxVNtJAGr2nM+4PDhBOXXBA== X-Received: by 10.60.133.243 with SMTP id pf19mr4097659oeb.23.1452787117243; Thu, 14 Jan 2016 07:58:37 -0800 (PST) Received: from kaki.bld.corp.google.com ([172.29.216.32]) by smtp.gmail.com with ESMTPSA id cd5sm3687527oec.15.2016.01.14.07.58.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 14 Jan 2016 07:58:35 -0800 (PST) Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id B6B2F22038D; Thu, 14 Jan 2016 08:58:32 -0700 (MST) From: Simon Glass To: U-Boot Mailing List Date: Thu, 14 Jan 2016 08:57:52 -0700 Message-Id: <1452787100-21782-10-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.6.0.rc2.230.g3dd15c0 In-Reply-To: <1452787100-21782-1-git-send-email-sjg@chromium.org> References: <1452787100-21782-1-git-send-email-sjg@chromium.org> Cc: Tom Cubie , Jeffy Chen Subject: [U-Boot] [PATCH 09/37] dm: backlight: Add a driver for a PWM backlight X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Many backlights need to use a PWM to control the brightness. Add a driver for this. It understands the standard device tree binding. Signed-off-by: Simon Glass --- drivers/video/Makefile | 3 + drivers/video/pwm_backlight.c | 134 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 drivers/video/pwm_backlight.c diff --git a/drivers/video/Makefile b/drivers/video/Makefile index fa90721..6d89532 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -10,6 +10,9 @@ obj-$(CONFIG_DISPLAY_PORT) += dp-uclass.o obj-$(CONFIG_DM_VIDEO) += backlight-uclass.o obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o console_normal.o obj-$(CONFIG_DM_VIDEO) += video_bmp.o +ifdef CONFIG_DM_VIDEO +obj-$(CONFIG_DM_PWM) += pwm_backlight.o +endif obj-$(CONFIG_VIDEO_ROTATION) += console_rotate.o endif diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c new file mode 100644 index 0000000..de6277f --- /dev/null +++ b/drivers/video/pwm_backlight.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct pwm_backlight_priv { + struct udevice *reg; + struct gpio_desc enable; + struct udevice *pwm; + uint channel; + uint period_ns; + uint default_level; + uint min_level; + uint max_level; +}; + +static int pwm_backlight_enable(struct udevice *dev) +{ + struct pwm_backlight_priv *priv = dev_get_priv(dev); + uint duty_cycle; + int ret; + + debug("%s: Enable '%s', regulator '%s'\n", __func__, dev->name, + priv->reg->name); + ret = regulator_set_enable(priv->reg, true); + if (ret) { + debug("%s: Cannot enable regulator for PWM '%s'\n", __func__, + dev->name); + return ret; + } + mdelay(120); + + duty_cycle = priv->period_ns * (priv->default_level - priv->min_level) / + (priv->max_level - priv->min_level + 1); + ret = pwm_set_config(priv->pwm, priv->channel, priv->period_ns, + duty_cycle); + if (ret) + return ret; + ret = pwm_set_enable(priv->pwm, priv->channel, true); + if (ret) + return ret; + mdelay(10); + dm_gpio_set_value(&priv->enable, 1); + + return 0; +} + +static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) +{ + struct pwm_backlight_priv *priv = dev_get_priv(dev); + struct fdtdec_phandle_args args; + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + int index, ret, count, len; + const u32 *cell; + + ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, + "power-supply", &priv->reg); + if (ret) { + debug("%s: Cannot get power supply: ret=%d\n", __func__, ret); + return ret; + } + ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, + GPIOD_IS_OUT); + if (ret) { + debug("%s: Warning: cannot get enable GPIO: ret=%d\n", + __func__, ret); + if (ret != -ENOENT) + return ret; + } + ret = fdtdec_parse_phandle_with_args(blob, node, "pwms", "#pwm-cells", + 0, 0, &args); + if (ret) { + debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret); + return ret; + } + + ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm); + if (ret) { + debug("%s: Cannot get PWM: ret=%d\n", __func__, ret); + return ret; + } + priv->channel = args.args[0]; + priv->period_ns = args.args[1]; + + index = fdtdec_get_int(blob, node, "default-brightness-level", 255); + cell = fdt_getprop(blob, node, "brightness-levels", &len); + count = len / sizeof(u32); + if (cell && count > index) { + priv->default_level = fdt32_to_cpu(cell[index]); + priv->max_level = fdt32_to_cpu(cell[count - 1]); + } else { + priv->default_level = index; + priv->max_level = 255; + } + + + return 0; +} + +static int pwm_backlight_probe(struct udevice *dev) +{ + return 0; +} + +static const struct backlight_ops pwm_backlight_ops = { + .enable = pwm_backlight_enable, +}; + +static const struct udevice_id pwm_backlight_ids[] = { + { .compatible = "pwm-backlight" }, + { } +}; + +U_BOOT_DRIVER(pwm_backlight) = { + .name = "pwm_backlight", + .id = UCLASS_PANEL_BACKLIGHT, + .of_match = pwm_backlight_ids, + .ops = &pwm_backlight_ops, + .ofdata_to_platdata = pwm_backlight_ofdata_to_platdata, + .probe = pwm_backlight_probe, + .priv_auto_alloc_size = sizeof(struct pwm_backlight_priv), +};