From mboxrd@z Thu Jan 1 00:00:00 1970 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.2 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=ham 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 B20E6C3404D for ; Tue, 18 Feb 2020 23:10:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7ED1124655 for ; Tue, 18 Feb 2020 23:10:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727681AbgBRXKU (ORCPT ); Tue, 18 Feb 2020 18:10:20 -0500 Received: from jabberwock.ucw.cz ([46.255.230.98]:39736 "EHLO jabberwock.ucw.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726820AbgBRXKU (ORCPT ); Tue, 18 Feb 2020 18:10:20 -0500 Received: by jabberwock.ucw.cz (Postfix, from userid 1017) id 686E91C0357; Wed, 19 Feb 2020 00:10:17 +0100 (CET) Date: Wed, 19 Feb 2020 00:10:01 +0100 From: Pavel Machek To: Tony Lindgren Cc: Lee Jones , kernel list , linux-arm-kernel , linux-omap@vger.kernel.org, sre@kernel.org, nekit1000@gmail.com, mpartap@gmx.net, merlijn@wizzup.org, martin_rysavy@centrum.cz, agx@sigxcpu.org, daniel.thompson@linaro.org, jingoohan1@gmail.com, dri-devel@lists.freedesktop.org, tomi.valkeinen@ti.com, jjhiblot@ti.com Subject: Re: LED backlight on Droid 4 and others Message-ID: <20200218231001.GA28817@amd> References: <20200105183202.GA17784@duo.ucw.cz> <20200106084549.GA14821@dell> <20200211172900.GH64767@atomide.com> <20200212201638.GB20085@amd> <20200218135219.GC3494@dell> <20200218141452.GF35972@atomide.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="dDRMvlgZJXvWKvBx" Content-Disposition: inline In-Reply-To: <20200218141452.GF35972@atomide.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --dDRMvlgZJXvWKvBx Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi! > > > > > > It would be good to get LED backlight to work in clean way for = 5.6 > > > > > > kernel. > > > > ... > > > > > > [If you have an idea what else is needed, it would be welcome; = it > > > > > > works for me in development tree but not in tree I'd like to > > > > > > upstream.] > > > > > >=20 > > > > > > Lee, would you be willing to take "backlight: add led-backlight > > > > > > driver"? Would it help if I got "leds: Add managed API to get a= LED > > > > > > from a device driver" and "leds: Add of_led_get() and led_put()= " into > > > > > > for_next tree of the LED subsystem? > > > > >=20 > > > > > It looks like you have an open question from Tony on v10. > > > > >=20 > > > > > Is that patch orthogonal, or are there depend{ants,encies}? > > > >=20 > > > > Uhh looks like we messed up a bit with integration. Now droid4 > > > > LCD backlight can no longer be enabled at all manually in v5.6-rc1 > > > > without the "add led-backlight driver" patch.. Should we just > > > > merge it to fix it rather than start scrambling with other > > > > temporary hacks? > > >=20 > > > We should just merge the "add led-backlight driver". Everything should > > > be ready for it. I'm sorry if I broke something working, I was not > > > aware it worked at all. > > >=20 > > > Unfortunately, this is backlight code, not LED, so I can't just merge= it. > >=20 > > Please go ahead. Apply my Acked-by and merge away ASAP. > >=20 > > Acked-by: Lee Jones >=20 > OK best to merge the driver via the LED tree: >=20 > Acked-by: Tony Lindgren > Tested-by: Tony Lindgren Is the patch below the one both of you are talking about? Hmm. I should s/default-brightness-level/default-brightness/ below. Lee, I can of course take it (thanks), but won't Kconfig/Makefile pieces cause rejects? It might be still better if you took it. I can hand-edit it and submit it in form for easy application... tommorow. Best regards, Pavel commit 81a2daadf8dd6c8e0cbc3b60246932436be3c714 Author: Tomi Valkeinen Date: Thu Oct 3 10:28:12 2019 +0200 backlight: add led-backlight driver =20 This patch adds a led-backlight driver (led_bl), which is similar to pwm_bl except the driver uses a LED class driver to adjust the brightness in the HW. Multiple LEDs can be used for a single backlight. =20 Signed-off-by: Tomi Valkeinen Signed-off-by: Jean-Jacques Hiblot Acked-by: Pavel Machek Reviewed-by: Daniel Thompson diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kcon= fig index 4c8f73394aac..93836ef872f5 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -463,6 +463,13 @@ config BACKLIGHT_RAVE_SP help Support for backlight control on RAVE SP device. =20 +config BACKLIGHT_LED + tristate "Generic LED based Backlight Driver" + depends on LEDS_CLASS && OF + help + If you have a LCD backlight adjustable by LED class driver, say Y + to enable this driver. + endif # BACKLIGHT_CLASS_DEVICE =20 endmenu diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Mak= efile index 961fb553b9c0..5e13242f31d6 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -60,3 +60,4 @@ obj-$(CONFIG_BACKLIGHT_TPS65217) +=3D tps65217_bl.o obj-$(CONFIG_BACKLIGHT_WM831X) +=3D wm831x_bl.o obj-$(CONFIG_BACKLIGHT_ARCXCNN) +=3D arcxcnn_bl.o obj-$(CONFIG_BACKLIGHT_RAVE_SP) +=3D rave-sp-backlight.o +obj-$(CONFIG_BACKLIGHT_LED) +=3D led_bl.o diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led= _bl.c new file mode 100644 index 000000000000..3f66549997c8 --- /dev/null +++ b/drivers/video/backlight/led_bl.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2015-2019 Texas Instruments Incorporated - http://www.ti= =2Ecom/ + * Author: Tomi Valkeinen + * + * Based on pwm_bl.c + */ + +#include +#include +#include +#include + +struct led_bl_data { + struct device *dev; + struct backlight_device *bl_dev; + struct led_classdev **leds; + bool enabled; + int nb_leds; + unsigned int *levels; + unsigned int default_brightness; + unsigned int max_brightness; +}; + +static void led_bl_set_brightness(struct led_bl_data *priv, int level) +{ + int i; + int bkl_brightness; + + if (priv->levels) + bkl_brightness =3D priv->levels[level]; + else + bkl_brightness =3D level; + + for (i =3D 0; i < priv->nb_leds; i++) + led_set_brightness(priv->leds[i], bkl_brightness); + + priv->enabled =3D true; +} + +static void led_bl_power_off(struct led_bl_data *priv) +{ + int i; + + if (!priv->enabled) + return; + + for (i =3D 0; i < priv->nb_leds; i++) + led_set_brightness(priv->leds[i], LED_OFF); + + priv->enabled =3D false; +} + +static int led_bl_update_status(struct backlight_device *bl) +{ + struct led_bl_data *priv =3D bl_get_data(bl); + int brightness =3D bl->props.brightness; + + if (bl->props.power !=3D FB_BLANK_UNBLANK || + bl->props.fb_blank !=3D FB_BLANK_UNBLANK || + bl->props.state & BL_CORE_FBBLANK) + brightness =3D 0; + + if (brightness > 0) + led_bl_set_brightness(priv, brightness); + else + led_bl_power_off(priv); + + return 0; +} + +static const struct backlight_ops led_bl_ops =3D { + .update_status =3D led_bl_update_status, +}; + +static int led_bl_get_leds(struct device *dev, + struct led_bl_data *priv) +{ + int i, nb_leds, ret; + struct device_node *node =3D dev->of_node; + struct led_classdev **leds; + unsigned int max_brightness; + unsigned int default_brightness; + + ret =3D of_count_phandle_with_args(node, "leds", NULL); + if (ret < 0) { + dev_err(dev, "Unable to get led count\n"); + return -EINVAL; + } + + nb_leds =3D ret; + if (nb_leds < 1) { + dev_err(dev, "At least one LED must be specified!\n"); + return -EINVAL; + } + + leds =3D devm_kzalloc(dev, sizeof(struct led_classdev *) * nb_leds, + GFP_KERNEL); + if (!leds) + return -ENOMEM; + + for (i =3D 0; i < nb_leds; i++) { + leds[i] =3D devm_of_led_get(dev, i); + if (IS_ERR(leds[i])) + return PTR_ERR(leds[i]); + } + + /* check that the LEDs all have the same brightness range */ + max_brightness =3D leds[0]->max_brightness; + for (i =3D 1; i < nb_leds; i++) { + if (max_brightness !=3D leds[i]->max_brightness) { + dev_err(dev, "LEDs must have identical ranges\n"); + return -EINVAL; + } + } + + /* get the default brightness from the first LED from the list */ + default_brightness =3D leds[0]->brightness; + + priv->nb_leds =3D nb_leds; + priv->leds =3D leds; + priv->max_brightness =3D max_brightness; + priv->default_brightness =3D default_brightness; + + return 0; +} + +static int led_bl_parse_levels(struct device *dev, + struct led_bl_data *priv) +{ + struct device_node *node =3D dev->of_node; + int num_levels; + u32 value; + int ret; + + if (!node) + return -ENODEV; + + num_levels =3D of_property_count_u32_elems(node, "brightness-levels"); + if (num_levels > 1) { + int i; + unsigned int db; + u32 *levels =3D NULL; + + levels =3D devm_kzalloc(dev, sizeof(u32) * num_levels, + GFP_KERNEL); + if (!levels) + return -ENOMEM; + + ret =3D of_property_read_u32_array(node, "brightness-levels", + levels, + num_levels); + if (ret < 0) + return ret; + + /* + * Try to map actual LED brightness to backlight brightness + * level + */ + db =3D priv->default_brightness; + for (i =3D 0 ; i < num_levels; i++) { + if ((i && db > levels[i-1]) && db <=3D levels[i]) + break; + } + priv->default_brightness =3D i; + priv->max_brightness =3D num_levels - 1; + priv->levels =3D levels; + } else if (num_levels >=3D 0) + dev_warn(dev, "Not enough levels defined\n"); + + ret =3D of_property_read_u32(node, "default-brightness-level", &value); + if (!ret && value <=3D priv->max_brightness) + priv->default_brightness =3D value; + else if (!ret && value > priv->max_brightness) + dev_warn(dev, "Invalid default brightness. Ignoring it\n"); + + return 0; +} + +static int led_bl_probe(struct platform_device *pdev) +{ + struct backlight_properties props; + struct led_bl_data *priv; + int ret, i; + + priv =3D devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + priv->dev =3D &pdev->dev; + + ret =3D led_bl_get_leds(&pdev->dev, priv); + if (ret) + return ret; + + ret =3D led_bl_parse_levels(&pdev->dev, priv); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to parse DT data\n"); + return ret; + } + + memset(&props, 0, sizeof(struct backlight_properties)); + props.type =3D BACKLIGHT_RAW; + props.max_brightness =3D priv->max_brightness; + props.brightness =3D priv->default_brightness; + props.power =3D (priv->default_brightness > 0) ? FB_BLANK_POWERDOWN : + FB_BLANK_UNBLANK; + priv->bl_dev =3D backlight_device_register(dev_name(&pdev->dev), + &pdev->dev, priv, &led_bl_ops, &props); + if (IS_ERR(priv->bl_dev)) { + dev_err(&pdev->dev, "Failed to register backlight\n"); + return PTR_ERR(priv->bl_dev); + } + + for (i =3D 0; i < priv->nb_leds; i++) + led_sysfs_disable(priv->leds[i]); + + backlight_update_status(priv->bl_dev); + + return 0; +} + +static int led_bl_remove(struct platform_device *pdev) +{ + struct led_bl_data *priv =3D platform_get_drvdata(pdev); + struct backlight_device *bl =3D priv->bl_dev; + int i; + + backlight_device_unregister(bl); + + led_bl_power_off(priv); + for (i =3D 0; i < priv->nb_leds; i++) + led_sysfs_enable(priv->leds[i]); + + return 0; +} + +static const struct of_device_id led_bl_of_match[] =3D { + { .compatible =3D "led-backlight" }, + { } +}; + +MODULE_DEVICE_TABLE(of, led_bl_of_match); + +static struct platform_driver led_bl_driver =3D { + .driver =3D { + .name =3D "led-backlight", + .of_match_table =3D of_match_ptr(led_bl_of_match), + }, + .probe =3D led_bl_probe, + .remove =3D led_bl_remove, +}; + +module_platform_driver(led_bl_driver); + +MODULE_DESCRIPTION("LED based Backlight Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:led-backlight"); --=20 (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blo= g.html --dDRMvlgZJXvWKvBx Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEARECAAYFAl5MbskACgkQMOfwapXb+vJPOgCfRPbwsYCnPqglmm26GB4cfPSN hlsAn16I3KGEcXZB16/neBQLfxWoyjUv =NDCD -----END PGP SIGNATURE----- --dDRMvlgZJXvWKvBx-- From mboxrd@z Thu Jan 1 00:00:00 1970 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=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=ham 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 A1143C34031 for ; Tue, 18 Feb 2020 23:10:41 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6A13024125 for ; Tue, 18 Feb 2020 23:10:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="G9vzlzfH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6A13024125 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Content-Type:Cc: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: In-Reply-To:MIME-Version:References:Message-ID:Subject:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=jcFYcPaOkNiUs+kqe/lUDHUxfGjhdxg+Sbj+DK42NKY=; b=G9vzlzfHSfW/ByTCV1iWYGnia xFlFmaps7yhQiwkYdtxLrL09J1uF/uKoVBoDBt4dFUnyBzqffyhzhMjO2hfz1orN2iUJtO7Ur/Cg4 dVuKNO1ijEqRBOw7pIPZsDpx7J/tdn8GbIDd3kWW0pCKN1cn1oYtT+xaHNIwEfeszLlntuCeikeRW HMQGqn7THpDoIN91UzFQlH2sBNha3k6wB9FwtjNhLxib6FJ+idJyOdlPBrbR9eKF5e87vhmvIeyzO iuh0+oQOi5csSN5ynRkHZPn+G2XyRdhU4u3MVNKv1tmrpzX42U0666s50zvcW1mKYvbqoIIhnh/PR 25fbGluEg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1j4C0d-0003Tk-Te; Tue, 18 Feb 2020 23:10:31 +0000 Received: from jabberwock.ucw.cz ([46.255.230.98]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1j4C0W-0002DP-Lj for linux-arm-kernel@lists.infradead.org; Tue, 18 Feb 2020 23:10:28 +0000 Received: by jabberwock.ucw.cz (Postfix, from userid 1017) id 686E91C0357; Wed, 19 Feb 2020 00:10:17 +0100 (CET) Date: Wed, 19 Feb 2020 00:10:01 +0100 From: Pavel Machek To: Tony Lindgren Subject: Re: LED backlight on Droid 4 and others Message-ID: <20200218231001.GA28817@amd> References: <20200105183202.GA17784@duo.ucw.cz> <20200106084549.GA14821@dell> <20200211172900.GH64767@atomide.com> <20200212201638.GB20085@amd> <20200218135219.GC3494@dell> <20200218141452.GF35972@atomide.com> MIME-Version: 1.0 In-Reply-To: <20200218141452.GF35972@atomide.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200218_151025_105592_0EDC73DD X-CRM114-Status: GOOD ( 38.79 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.thompson@linaro.org, mpartap@gmx.net, jingoohan1@gmail.com, merlijn@wizzup.org, martin_rysavy@centrum.cz, kernel list , dri-devel@lists.freedesktop.org, sre@kernel.org, nekit1000@gmail.com, tomi.valkeinen@ti.com, jjhiblot@ti.com, linux-omap@vger.kernel.org, Lee Jones , agx@sigxcpu.org, linux-arm-kernel Content-Type: multipart/mixed; boundary="===============5920971582680367964==" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org --===============5920971582680367964== Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="dDRMvlgZJXvWKvBx" Content-Disposition: inline --dDRMvlgZJXvWKvBx Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi! > > > > > > It would be good to get LED backlight to work in clean way for = 5.6 > > > > > > kernel. > > > > ... > > > > > > [If you have an idea what else is needed, it would be welcome; = it > > > > > > works for me in development tree but not in tree I'd like to > > > > > > upstream.] > > > > > >=20 > > > > > > Lee, would you be willing to take "backlight: add led-backlight > > > > > > driver"? Would it help if I got "leds: Add managed API to get a= LED > > > > > > from a device driver" and "leds: Add of_led_get() and led_put()= " into > > > > > > for_next tree of the LED subsystem? > > > > >=20 > > > > > It looks like you have an open question from Tony on v10. > > > > >=20 > > > > > Is that patch orthogonal, or are there depend{ants,encies}? > > > >=20 > > > > Uhh looks like we messed up a bit with integration. Now droid4 > > > > LCD backlight can no longer be enabled at all manually in v5.6-rc1 > > > > without the "add led-backlight driver" patch.. Should we just > > > > merge it to fix it rather than start scrambling with other > > > > temporary hacks? > > >=20 > > > We should just merge the "add led-backlight driver". Everything should > > > be ready for it. I'm sorry if I broke something working, I was not > > > aware it worked at all. > > >=20 > > > Unfortunately, this is backlight code, not LED, so I can't just merge= it. > >=20 > > Please go ahead. Apply my Acked-by and merge away ASAP. > >=20 > > Acked-by: Lee Jones >=20 > OK best to merge the driver via the LED tree: >=20 > Acked-by: Tony Lindgren > Tested-by: Tony Lindgren Is the patch below the one both of you are talking about? Hmm. I should s/default-brightness-level/default-brightness/ below. Lee, I can of course take it (thanks), but won't Kconfig/Makefile pieces cause rejects? It might be still better if you took it. I can hand-edit it and submit it in form for easy application... tommorow. Best regards, Pavel commit 81a2daadf8dd6c8e0cbc3b60246932436be3c714 Author: Tomi Valkeinen Date: Thu Oct 3 10:28:12 2019 +0200 backlight: add led-backlight driver =20 This patch adds a led-backlight driver (led_bl), which is similar to pwm_bl except the driver uses a LED class driver to adjust the brightness in the HW. Multiple LEDs can be used for a single backlight. =20 Signed-off-by: Tomi Valkeinen Signed-off-by: Jean-Jacques Hiblot Acked-by: Pavel Machek Reviewed-by: Daniel Thompson diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kcon= fig index 4c8f73394aac..93836ef872f5 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -463,6 +463,13 @@ config BACKLIGHT_RAVE_SP help Support for backlight control on RAVE SP device. =20 +config BACKLIGHT_LED + tristate "Generic LED based Backlight Driver" + depends on LEDS_CLASS && OF + help + If you have a LCD backlight adjustable by LED class driver, say Y + to enable this driver. + endif # BACKLIGHT_CLASS_DEVICE =20 endmenu diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Mak= efile index 961fb553b9c0..5e13242f31d6 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -60,3 +60,4 @@ obj-$(CONFIG_BACKLIGHT_TPS65217) +=3D tps65217_bl.o obj-$(CONFIG_BACKLIGHT_WM831X) +=3D wm831x_bl.o obj-$(CONFIG_BACKLIGHT_ARCXCNN) +=3D arcxcnn_bl.o obj-$(CONFIG_BACKLIGHT_RAVE_SP) +=3D rave-sp-backlight.o +obj-$(CONFIG_BACKLIGHT_LED) +=3D led_bl.o diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led= _bl.c new file mode 100644 index 000000000000..3f66549997c8 --- /dev/null +++ b/drivers/video/backlight/led_bl.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2015-2019 Texas Instruments Incorporated - http://www.ti= =2Ecom/ + * Author: Tomi Valkeinen + * + * Based on pwm_bl.c + */ + +#include +#include +#include +#include + +struct led_bl_data { + struct device *dev; + struct backlight_device *bl_dev; + struct led_classdev **leds; + bool enabled; + int nb_leds; + unsigned int *levels; + unsigned int default_brightness; + unsigned int max_brightness; +}; + +static void led_bl_set_brightness(struct led_bl_data *priv, int level) +{ + int i; + int bkl_brightness; + + if (priv->levels) + bkl_brightness =3D priv->levels[level]; + else + bkl_brightness =3D level; + + for (i =3D 0; i < priv->nb_leds; i++) + led_set_brightness(priv->leds[i], bkl_brightness); + + priv->enabled =3D true; +} + +static void led_bl_power_off(struct led_bl_data *priv) +{ + int i; + + if (!priv->enabled) + return; + + for (i =3D 0; i < priv->nb_leds; i++) + led_set_brightness(priv->leds[i], LED_OFF); + + priv->enabled =3D false; +} + +static int led_bl_update_status(struct backlight_device *bl) +{ + struct led_bl_data *priv =3D bl_get_data(bl); + int brightness =3D bl->props.brightness; + + if (bl->props.power !=3D FB_BLANK_UNBLANK || + bl->props.fb_blank !=3D FB_BLANK_UNBLANK || + bl->props.state & BL_CORE_FBBLANK) + brightness =3D 0; + + if (brightness > 0) + led_bl_set_brightness(priv, brightness); + else + led_bl_power_off(priv); + + return 0; +} + +static const struct backlight_ops led_bl_ops =3D { + .update_status =3D led_bl_update_status, +}; + +static int led_bl_get_leds(struct device *dev, + struct led_bl_data *priv) +{ + int i, nb_leds, ret; + struct device_node *node =3D dev->of_node; + struct led_classdev **leds; + unsigned int max_brightness; + unsigned int default_brightness; + + ret =3D of_count_phandle_with_args(node, "leds", NULL); + if (ret < 0) { + dev_err(dev, "Unable to get led count\n"); + return -EINVAL; + } + + nb_leds =3D ret; + if (nb_leds < 1) { + dev_err(dev, "At least one LED must be specified!\n"); + return -EINVAL; + } + + leds =3D devm_kzalloc(dev, sizeof(struct led_classdev *) * nb_leds, + GFP_KERNEL); + if (!leds) + return -ENOMEM; + + for (i =3D 0; i < nb_leds; i++) { + leds[i] =3D devm_of_led_get(dev, i); + if (IS_ERR(leds[i])) + return PTR_ERR(leds[i]); + } + + /* check that the LEDs all have the same brightness range */ + max_brightness =3D leds[0]->max_brightness; + for (i =3D 1; i < nb_leds; i++) { + if (max_brightness !=3D leds[i]->max_brightness) { + dev_err(dev, "LEDs must have identical ranges\n"); + return -EINVAL; + } + } + + /* get the default brightness from the first LED from the list */ + default_brightness =3D leds[0]->brightness; + + priv->nb_leds =3D nb_leds; + priv->leds =3D leds; + priv->max_brightness =3D max_brightness; + priv->default_brightness =3D default_brightness; + + return 0; +} + +static int led_bl_parse_levels(struct device *dev, + struct led_bl_data *priv) +{ + struct device_node *node =3D dev->of_node; + int num_levels; + u32 value; + int ret; + + if (!node) + return -ENODEV; + + num_levels =3D of_property_count_u32_elems(node, "brightness-levels"); + if (num_levels > 1) { + int i; + unsigned int db; + u32 *levels =3D NULL; + + levels =3D devm_kzalloc(dev, sizeof(u32) * num_levels, + GFP_KERNEL); + if (!levels) + return -ENOMEM; + + ret =3D of_property_read_u32_array(node, "brightness-levels", + levels, + num_levels); + if (ret < 0) + return ret; + + /* + * Try to map actual LED brightness to backlight brightness + * level + */ + db =3D priv->default_brightness; + for (i =3D 0 ; i < num_levels; i++) { + if ((i && db > levels[i-1]) && db <=3D levels[i]) + break; + } + priv->default_brightness =3D i; + priv->max_brightness =3D num_levels - 1; + priv->levels =3D levels; + } else if (num_levels >=3D 0) + dev_warn(dev, "Not enough levels defined\n"); + + ret =3D of_property_read_u32(node, "default-brightness-level", &value); + if (!ret && value <=3D priv->max_brightness) + priv->default_brightness =3D value; + else if (!ret && value > priv->max_brightness) + dev_warn(dev, "Invalid default brightness. Ignoring it\n"); + + return 0; +} + +static int led_bl_probe(struct platform_device *pdev) +{ + struct backlight_properties props; + struct led_bl_data *priv; + int ret, i; + + priv =3D devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + priv->dev =3D &pdev->dev; + + ret =3D led_bl_get_leds(&pdev->dev, priv); + if (ret) + return ret; + + ret =3D led_bl_parse_levels(&pdev->dev, priv); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to parse DT data\n"); + return ret; + } + + memset(&props, 0, sizeof(struct backlight_properties)); + props.type =3D BACKLIGHT_RAW; + props.max_brightness =3D priv->max_brightness; + props.brightness =3D priv->default_brightness; + props.power =3D (priv->default_brightness > 0) ? FB_BLANK_POWERDOWN : + FB_BLANK_UNBLANK; + priv->bl_dev =3D backlight_device_register(dev_name(&pdev->dev), + &pdev->dev, priv, &led_bl_ops, &props); + if (IS_ERR(priv->bl_dev)) { + dev_err(&pdev->dev, "Failed to register backlight\n"); + return PTR_ERR(priv->bl_dev); + } + + for (i =3D 0; i < priv->nb_leds; i++) + led_sysfs_disable(priv->leds[i]); + + backlight_update_status(priv->bl_dev); + + return 0; +} + +static int led_bl_remove(struct platform_device *pdev) +{ + struct led_bl_data *priv =3D platform_get_drvdata(pdev); + struct backlight_device *bl =3D priv->bl_dev; + int i; + + backlight_device_unregister(bl); + + led_bl_power_off(priv); + for (i =3D 0; i < priv->nb_leds; i++) + led_sysfs_enable(priv->leds[i]); + + return 0; +} + +static const struct of_device_id led_bl_of_match[] =3D { + { .compatible =3D "led-backlight" }, + { } +}; + +MODULE_DEVICE_TABLE(of, led_bl_of_match); + +static struct platform_driver led_bl_driver =3D { + .driver =3D { + .name =3D "led-backlight", + .of_match_table =3D of_match_ptr(led_bl_of_match), + }, + .probe =3D led_bl_probe, + .remove =3D led_bl_remove, +}; + +module_platform_driver(led_bl_driver); + +MODULE_DESCRIPTION("LED based Backlight Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:led-backlight"); --=20 (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blo= g.html --dDRMvlgZJXvWKvBx Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEARECAAYFAl5MbskACgkQMOfwapXb+vJPOgCfRPbwsYCnPqglmm26GB4cfPSN hlsAn16I3KGEcXZB16/neBQLfxWoyjUv =NDCD -----END PGP SIGNATURE----- --dDRMvlgZJXvWKvBx-- --===============5920971582680367964== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel --===============5920971582680367964==-- From mboxrd@z Thu Jan 1 00:00:00 1970 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.2 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=ham 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 64600C34031 for ; Tue, 18 Feb 2020 23:10:22 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 41E6624655 for ; Tue, 18 Feb 2020 23:10:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 41E6624655 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D0C3D6EAE3; Tue, 18 Feb 2020 23:10:21 +0000 (UTC) Received: from jabberwock.ucw.cz (jabberwock.ucw.cz [46.255.230.98]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2A6366EAE3 for ; Tue, 18 Feb 2020 23:10:20 +0000 (UTC) Received: by jabberwock.ucw.cz (Postfix, from userid 1017) id 686E91C0357; Wed, 19 Feb 2020 00:10:17 +0100 (CET) Date: Wed, 19 Feb 2020 00:10:01 +0100 From: Pavel Machek To: Tony Lindgren Subject: Re: LED backlight on Droid 4 and others Message-ID: <20200218231001.GA28817@amd> References: <20200105183202.GA17784@duo.ucw.cz> <20200106084549.GA14821@dell> <20200211172900.GH64767@atomide.com> <20200212201638.GB20085@amd> <20200218135219.GC3494@dell> <20200218141452.GF35972@atomide.com> MIME-Version: 1.0 In-Reply-To: <20200218141452.GF35972@atomide.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.thompson@linaro.org, mpartap@gmx.net, jingoohan1@gmail.com, merlijn@wizzup.org, martin_rysavy@centrum.cz, kernel list , dri-devel@lists.freedesktop.org, sre@kernel.org, nekit1000@gmail.com, tomi.valkeinen@ti.com, jjhiblot@ti.com, linux-omap@vger.kernel.org, Lee Jones , agx@sigxcpu.org, linux-arm-kernel Content-Type: multipart/mixed; boundary="===============0536015452==" Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" --===============0536015452== Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="dDRMvlgZJXvWKvBx" Content-Disposition: inline --dDRMvlgZJXvWKvBx Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi! > > > > > > It would be good to get LED backlight to work in clean way for = 5.6 > > > > > > kernel. > > > > ... > > > > > > [If you have an idea what else is needed, it would be welcome; = it > > > > > > works for me in development tree but not in tree I'd like to > > > > > > upstream.] > > > > > >=20 > > > > > > Lee, would you be willing to take "backlight: add led-backlight > > > > > > driver"? Would it help if I got "leds: Add managed API to get a= LED > > > > > > from a device driver" and "leds: Add of_led_get() and led_put()= " into > > > > > > for_next tree of the LED subsystem? > > > > >=20 > > > > > It looks like you have an open question from Tony on v10. > > > > >=20 > > > > > Is that patch orthogonal, or are there depend{ants,encies}? > > > >=20 > > > > Uhh looks like we messed up a bit with integration. Now droid4 > > > > LCD backlight can no longer be enabled at all manually in v5.6-rc1 > > > > without the "add led-backlight driver" patch.. Should we just > > > > merge it to fix it rather than start scrambling with other > > > > temporary hacks? > > >=20 > > > We should just merge the "add led-backlight driver". Everything should > > > be ready for it. I'm sorry if I broke something working, I was not > > > aware it worked at all. > > >=20 > > > Unfortunately, this is backlight code, not LED, so I can't just merge= it. > >=20 > > Please go ahead. Apply my Acked-by and merge away ASAP. > >=20 > > Acked-by: Lee Jones >=20 > OK best to merge the driver via the LED tree: >=20 > Acked-by: Tony Lindgren > Tested-by: Tony Lindgren Is the patch below the one both of you are talking about? Hmm. I should s/default-brightness-level/default-brightness/ below. Lee, I can of course take it (thanks), but won't Kconfig/Makefile pieces cause rejects? It might be still better if you took it. I can hand-edit it and submit it in form for easy application... tommorow. Best regards, Pavel commit 81a2daadf8dd6c8e0cbc3b60246932436be3c714 Author: Tomi Valkeinen Date: Thu Oct 3 10:28:12 2019 +0200 backlight: add led-backlight driver =20 This patch adds a led-backlight driver (led_bl), which is similar to pwm_bl except the driver uses a LED class driver to adjust the brightness in the HW. Multiple LEDs can be used for a single backlight. =20 Signed-off-by: Tomi Valkeinen Signed-off-by: Jean-Jacques Hiblot Acked-by: Pavel Machek Reviewed-by: Daniel Thompson diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kcon= fig index 4c8f73394aac..93836ef872f5 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -463,6 +463,13 @@ config BACKLIGHT_RAVE_SP help Support for backlight control on RAVE SP device. =20 +config BACKLIGHT_LED + tristate "Generic LED based Backlight Driver" + depends on LEDS_CLASS && OF + help + If you have a LCD backlight adjustable by LED class driver, say Y + to enable this driver. + endif # BACKLIGHT_CLASS_DEVICE =20 endmenu diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Mak= efile index 961fb553b9c0..5e13242f31d6 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -60,3 +60,4 @@ obj-$(CONFIG_BACKLIGHT_TPS65217) +=3D tps65217_bl.o obj-$(CONFIG_BACKLIGHT_WM831X) +=3D wm831x_bl.o obj-$(CONFIG_BACKLIGHT_ARCXCNN) +=3D arcxcnn_bl.o obj-$(CONFIG_BACKLIGHT_RAVE_SP) +=3D rave-sp-backlight.o +obj-$(CONFIG_BACKLIGHT_LED) +=3D led_bl.o diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led= _bl.c new file mode 100644 index 000000000000..3f66549997c8 --- /dev/null +++ b/drivers/video/backlight/led_bl.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2015-2019 Texas Instruments Incorporated - http://www.ti= =2Ecom/ + * Author: Tomi Valkeinen + * + * Based on pwm_bl.c + */ + +#include +#include +#include +#include + +struct led_bl_data { + struct device *dev; + struct backlight_device *bl_dev; + struct led_classdev **leds; + bool enabled; + int nb_leds; + unsigned int *levels; + unsigned int default_brightness; + unsigned int max_brightness; +}; + +static void led_bl_set_brightness(struct led_bl_data *priv, int level) +{ + int i; + int bkl_brightness; + + if (priv->levels) + bkl_brightness =3D priv->levels[level]; + else + bkl_brightness =3D level; + + for (i =3D 0; i < priv->nb_leds; i++) + led_set_brightness(priv->leds[i], bkl_brightness); + + priv->enabled =3D true; +} + +static void led_bl_power_off(struct led_bl_data *priv) +{ + int i; + + if (!priv->enabled) + return; + + for (i =3D 0; i < priv->nb_leds; i++) + led_set_brightness(priv->leds[i], LED_OFF); + + priv->enabled =3D false; +} + +static int led_bl_update_status(struct backlight_device *bl) +{ + struct led_bl_data *priv =3D bl_get_data(bl); + int brightness =3D bl->props.brightness; + + if (bl->props.power !=3D FB_BLANK_UNBLANK || + bl->props.fb_blank !=3D FB_BLANK_UNBLANK || + bl->props.state & BL_CORE_FBBLANK) + brightness =3D 0; + + if (brightness > 0) + led_bl_set_brightness(priv, brightness); + else + led_bl_power_off(priv); + + return 0; +} + +static const struct backlight_ops led_bl_ops =3D { + .update_status =3D led_bl_update_status, +}; + +static int led_bl_get_leds(struct device *dev, + struct led_bl_data *priv) +{ + int i, nb_leds, ret; + struct device_node *node =3D dev->of_node; + struct led_classdev **leds; + unsigned int max_brightness; + unsigned int default_brightness; + + ret =3D of_count_phandle_with_args(node, "leds", NULL); + if (ret < 0) { + dev_err(dev, "Unable to get led count\n"); + return -EINVAL; + } + + nb_leds =3D ret; + if (nb_leds < 1) { + dev_err(dev, "At least one LED must be specified!\n"); + return -EINVAL; + } + + leds =3D devm_kzalloc(dev, sizeof(struct led_classdev *) * nb_leds, + GFP_KERNEL); + if (!leds) + return -ENOMEM; + + for (i =3D 0; i < nb_leds; i++) { + leds[i] =3D devm_of_led_get(dev, i); + if (IS_ERR(leds[i])) + return PTR_ERR(leds[i]); + } + + /* check that the LEDs all have the same brightness range */ + max_brightness =3D leds[0]->max_brightness; + for (i =3D 1; i < nb_leds; i++) { + if (max_brightness !=3D leds[i]->max_brightness) { + dev_err(dev, "LEDs must have identical ranges\n"); + return -EINVAL; + } + } + + /* get the default brightness from the first LED from the list */ + default_brightness =3D leds[0]->brightness; + + priv->nb_leds =3D nb_leds; + priv->leds =3D leds; + priv->max_brightness =3D max_brightness; + priv->default_brightness =3D default_brightness; + + return 0; +} + +static int led_bl_parse_levels(struct device *dev, + struct led_bl_data *priv) +{ + struct device_node *node =3D dev->of_node; + int num_levels; + u32 value; + int ret; + + if (!node) + return -ENODEV; + + num_levels =3D of_property_count_u32_elems(node, "brightness-levels"); + if (num_levels > 1) { + int i; + unsigned int db; + u32 *levels =3D NULL; + + levels =3D devm_kzalloc(dev, sizeof(u32) * num_levels, + GFP_KERNEL); + if (!levels) + return -ENOMEM; + + ret =3D of_property_read_u32_array(node, "brightness-levels", + levels, + num_levels); + if (ret < 0) + return ret; + + /* + * Try to map actual LED brightness to backlight brightness + * level + */ + db =3D priv->default_brightness; + for (i =3D 0 ; i < num_levels; i++) { + if ((i && db > levels[i-1]) && db <=3D levels[i]) + break; + } + priv->default_brightness =3D i; + priv->max_brightness =3D num_levels - 1; + priv->levels =3D levels; + } else if (num_levels >=3D 0) + dev_warn(dev, "Not enough levels defined\n"); + + ret =3D of_property_read_u32(node, "default-brightness-level", &value); + if (!ret && value <=3D priv->max_brightness) + priv->default_brightness =3D value; + else if (!ret && value > priv->max_brightness) + dev_warn(dev, "Invalid default brightness. Ignoring it\n"); + + return 0; +} + +static int led_bl_probe(struct platform_device *pdev) +{ + struct backlight_properties props; + struct led_bl_data *priv; + int ret, i; + + priv =3D devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + priv->dev =3D &pdev->dev; + + ret =3D led_bl_get_leds(&pdev->dev, priv); + if (ret) + return ret; + + ret =3D led_bl_parse_levels(&pdev->dev, priv); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to parse DT data\n"); + return ret; + } + + memset(&props, 0, sizeof(struct backlight_properties)); + props.type =3D BACKLIGHT_RAW; + props.max_brightness =3D priv->max_brightness; + props.brightness =3D priv->default_brightness; + props.power =3D (priv->default_brightness > 0) ? FB_BLANK_POWERDOWN : + FB_BLANK_UNBLANK; + priv->bl_dev =3D backlight_device_register(dev_name(&pdev->dev), + &pdev->dev, priv, &led_bl_ops, &props); + if (IS_ERR(priv->bl_dev)) { + dev_err(&pdev->dev, "Failed to register backlight\n"); + return PTR_ERR(priv->bl_dev); + } + + for (i =3D 0; i < priv->nb_leds; i++) + led_sysfs_disable(priv->leds[i]); + + backlight_update_status(priv->bl_dev); + + return 0; +} + +static int led_bl_remove(struct platform_device *pdev) +{ + struct led_bl_data *priv =3D platform_get_drvdata(pdev); + struct backlight_device *bl =3D priv->bl_dev; + int i; + + backlight_device_unregister(bl); + + led_bl_power_off(priv); + for (i =3D 0; i < priv->nb_leds; i++) + led_sysfs_enable(priv->leds[i]); + + return 0; +} + +static const struct of_device_id led_bl_of_match[] =3D { + { .compatible =3D "led-backlight" }, + { } +}; + +MODULE_DEVICE_TABLE(of, led_bl_of_match); + +static struct platform_driver led_bl_driver =3D { + .driver =3D { + .name =3D "led-backlight", + .of_match_table =3D of_match_ptr(led_bl_of_match), + }, + .probe =3D led_bl_probe, + .remove =3D led_bl_remove, +}; + +module_platform_driver(led_bl_driver); + +MODULE_DESCRIPTION("LED based Backlight Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:led-backlight"); --=20 (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blo= g.html --dDRMvlgZJXvWKvBx Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEARECAAYFAl5MbskACgkQMOfwapXb+vJPOgCfRPbwsYCnPqglmm26GB4cfPSN hlsAn16I3KGEcXZB16/neBQLfxWoyjUv =NDCD -----END PGP SIGNATURE----- --dDRMvlgZJXvWKvBx-- --===============0536015452== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel --===============0536015452==--