From patchwork Mon Jul 24 17:33:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Reichel X-Patchwork-Id: 9860913 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7AF69603F9 for ; Tue, 25 Jul 2017 00:14:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6F334285D1 for ; Tue, 25 Jul 2017 00:14:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 62C5128604; Tue, 25 Jul 2017 00:14:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5B4E7285E6 for ; Tue, 25 Jul 2017 00:14:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 406A589D60; Tue, 25 Jul 2017 00:13:00 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6DB236E333 for ; Mon, 24 Jul 2017 17:33:53 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: sre) with ESMTPSA id 2D2D526C4C2 From: Sebastian Reichel To: Sebastian Reichel , Tomi Valkeinen , Tony Lindgren Subject: [PATCHv1 11/14] drm/omap: panel-dsi-cm: add external backlight support Date: Mon, 24 Jul 2017 19:33:08 +0200 Message-Id: <20170724173311.27170-12-sebastian.reichel@collabora.co.uk> X-Mailer: git-send-email 2.13.2 In-Reply-To: <20170724173311.27170-1-sebastian.reichel@collabora.co.uk> References: <20170724173311.27170-1-sebastian.reichel@collabora.co.uk> X-Mailman-Approved-At: Tue, 25 Jul 2017 00:12:30 +0000 Cc: Sebastian Reichel , linux-omap@vger.kernel.org, Laurent Pinchart , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Droid 4 has a command mode DSI panel, which does not have/use DSI based backlight support. This adds proper support for this using a backlight phandle property, which follows the common panel binding. If no backlight phandle is found, it is assumed, that the native backlight should be used instead. This is used by the Nokia N950. Signed-off-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 91 ++++++++++++++++--------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c index b50b1e81b2f5..1eeb8b0d10c2 100644 --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c @@ -51,6 +51,7 @@ struct panel_drv_data { struct mutex lock; struct backlight_device *bldev; + struct backlight_device *extbldev; unsigned long hw_guard_end; /* next value of jiffies when we can * issue the next sleep in/out command @@ -100,6 +101,30 @@ static int dsicm_panel_reset(struct panel_drv_data *ddata); static void dsicm_ulps_work(struct work_struct *work); +static void dsicm_bl_power(struct panel_drv_data *ddata, bool enable) +{ + struct backlight_device *backlight; + + if (ddata->bldev) + backlight = ddata->bldev; + else if (ddata->extbldev) + backlight = ddata->extbldev; + else + return; + + if (enable) { + backlight->props.fb_blank = FB_BLANK_UNBLANK; + backlight->props.state = ~(BL_CORE_FBBLANK | BL_CORE_SUSPENDED); + backlight->props.power = FB_BLANK_UNBLANK; + } else { + backlight->props.fb_blank = FB_BLANK_NORMAL; + backlight->props.power = FB_BLANK_POWERDOWN; + backlight->props.state |= BL_CORE_FBBLANK | BL_CORE_SUSPENDED; + } + + backlight_update_status(backlight); +} + static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec) { ddata->hw_guard_wait = msecs_to_jiffies(guard_msec); @@ -343,7 +368,7 @@ static int dsicm_bl_update_status(struct backlight_device *dev) { struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev); struct omap_dss_device *in = ddata->in; - int r; + int r = 0; int level; if (dev->props.fb_blank == FB_BLANK_UNBLANK && @@ -364,8 +389,6 @@ static int dsicm_bl_update_status(struct backlight_device *dev) r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, level); in->ops.dsi->bus_unlock(in); - } else { - r = 0; } mutex_unlock(&ddata->lock); @@ -819,6 +842,8 @@ static int dsicm_enable(struct omap_dss_device *dssdev) mutex_unlock(&ddata->lock); + dsicm_bl_power(ddata, true); + return 0; err: dev_dbg(&ddata->pdev->dev, "enable failed\n"); @@ -834,6 +859,8 @@ static void dsicm_disable(struct omap_dss_device *dssdev) dev_dbg(&ddata->pdev->dev, "disable\n"); + dsicm_bl_power(ddata, false); + mutex_lock(&ddata->lock); dsicm_cancel_ulps_work(ddata); @@ -1198,6 +1225,7 @@ static struct omap_dss_driver dsicm_ops = { static int dsicm_probe_of(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; + struct device_node *backlight; struct panel_drv_data *ddata = platform_get_drvdata(pdev); struct omap_dss_device *in; struct display_timing timing; @@ -1259,14 +1287,25 @@ static int dsicm_probe_of(struct platform_device *pdev) ddata->in = in; - /* TODO: ulps, backlight */ + backlight = of_parse_phandle(node, "backlight", 0); + if (backlight) { + ddata->extbldev = of_find_backlight_by_node(backlight); + of_node_put(backlight); + + if (!ddata->extbldev) + return -EPROBE_DEFER; + } else { + /* assume native backlight support */ + ddata->use_dsi_backlight = true; + } + + /* TODO: ulps */ return 0; } static int dsicm_probe(struct platform_device *pdev) { - struct backlight_properties props; struct panel_drv_data *ddata; struct backlight_device *bldev = NULL; struct device *dev = &pdev->dev; @@ -1319,7 +1358,7 @@ static int dsicm_probe(struct platform_device *pdev) GPIOF_OUT_INIT_LOW, "taal rst"); if (r) { dev_err(dev, "failed to request reset gpio\n"); - return r; + goto err_reg; } } @@ -1328,7 +1367,7 @@ static int dsicm_probe(struct platform_device *pdev) GPIOF_IN, "taal irq"); if (r) { dev_err(dev, "GPIO request failed\n"); - return r; + goto err_reg; } r = devm_request_irq(dev, gpio_to_irq(ddata->ext_te_gpio), @@ -1338,7 +1377,7 @@ static int dsicm_probe(struct platform_device *pdev) if (r) { dev_err(dev, "IRQ request failed\n"); - return r; + goto err_reg; } INIT_DEFERRABLE_WORK(&ddata->te_timeout_work, @@ -1348,48 +1387,43 @@ static int dsicm_probe(struct platform_device *pdev) } ddata->workqueue = create_singlethread_workqueue("dsicm_wq"); - if (ddata->workqueue == NULL) { - dev_err(dev, "can't create workqueue\n"); - return -ENOMEM; + if (!ddata->workqueue) { + r = -ENOMEM; + goto err_reg; } INIT_DELAYED_WORK(&ddata->ulps_work, dsicm_ulps_work); dsicm_hw_reset(ddata); if (ddata->use_dsi_backlight) { - memset(&props, 0, sizeof(props)); + struct backlight_properties props = { 0 }; props.max_brightness = 255; - props.type = BACKLIGHT_RAW; - bldev = backlight_device_register(dev_name(dev), - dev, ddata, &dsicm_bl_ops, &props); + + bldev = devm_backlight_device_register(dev, dev_name(dev), + dev, ddata, &dsicm_bl_ops, &props); if (IS_ERR(bldev)) { r = PTR_ERR(bldev); goto err_bl; } ddata->bldev = bldev; - - bldev->props.fb_blank = FB_BLANK_UNBLANK; - bldev->props.power = FB_BLANK_UNBLANK; - bldev->props.brightness = 255; - - dsicm_bl_update_status(bldev); } r = sysfs_create_group(&dev->kobj, &dsicm_attr_group); if (r) { dev_err(dev, "failed to create sysfs files\n"); - goto err_sysfs_create; + goto err_bl; } return 0; -err_sysfs_create: - backlight_device_unregister(bldev); err_bl: destroy_workqueue(ddata->workqueue); err_reg: + if (ddata->extbldev) + put_device(&ddata->extbldev->dev); + return r; } @@ -1397,7 +1431,6 @@ static int __exit dsicm_remove(struct platform_device *pdev) { struct panel_drv_data *ddata = platform_get_drvdata(pdev); struct omap_dss_device *dssdev = &ddata->dssdev; - struct backlight_device *bldev; dev_dbg(&pdev->dev, "remove\n"); @@ -1408,12 +1441,8 @@ static int __exit dsicm_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group); - bldev = ddata->bldev; - if (bldev != NULL) { - bldev->props.power = FB_BLANK_POWERDOWN; - dsicm_bl_update_status(bldev); - backlight_device_unregister(bldev); - } + if (ddata->extbldev) + put_device(&ddata->extbldev->dev); omap_dss_put_device(ddata->in);