From patchwork Mon Apr 30 14:43:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 10371903 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 164F96053E for ; Mon, 30 Apr 2018 14:43:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0639F28824 for ; Mon, 30 Apr 2018 14:43:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EEF3F288EB; Mon, 30 Apr 2018 14:43:43 +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=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 935EF28824 for ; Mon, 30 Apr 2018 14:43:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3BC866E350; Mon, 30 Apr 2018 14:43:39 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail.bootlin.com (mail.bootlin.com [62.4.15.54]) by gabe.freedesktop.org (Postfix) with ESMTP id B68106E351 for ; Mon, 30 Apr 2018 14:43:37 +0000 (UTC) Received: by mail.bootlin.com (Postfix, from userid 110) id 5190F20999; Mon, 30 Apr 2018 16:43:36 +0200 (CEST) Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.bootlin.com (Postfix) with ESMTPSA id 13FB72082C; Mon, 30 Apr 2018 16:43:26 +0200 (CEST) From: Boris Brezillon To: Thierry Reding , dri-devel@lists.freedesktop.org Subject: [RFC PATCH 3/3] drm/panel: rpi-touchscreen: Implement ->detect() Date: Mon, 30 Apr 2018 16:43:23 +0200 Message-Id: <20180430144323.9233-4-boris.brezillon@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180430144323.9233-1-boris.brezillon@bootlin.com> References: <20180430144323.9233-1-boris.brezillon@bootlin.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Airlie , Boris Brezillon MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Implement a way to determine when the panel is connected. This is done by reading REG_ID through I2C. We consider the panel as disconnect until we retrieve a valid ID. Signed-off-by: Boris Brezillon --- .../gpu/drm/panel/panel-raspberrypi-touchscreen.c | 62 ++++++++++++++++++---- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c index d964d454e4ae..e65caec590d4 100644 --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c @@ -196,6 +196,7 @@ struct rpi_touchscreen { struct drm_panel base; struct mipi_dsi_device *dsi; struct i2c_client *i2c; + bool connected; }; static const struct drm_display_mode rpi_touchscreen_modes[] = { @@ -255,6 +256,9 @@ static int rpi_touchscreen_write(struct rpi_touchscreen *ts, u16 reg, u32 val) mipi_dsi_dcs_write_buffer(ts->dsi, msg, sizeof(msg)); #else + if (!ts->connected) + return 0; + rpi_touchscreen_i2c_write(ts, REG_WR_ADDRH, reg >> 8); rpi_touchscreen_i2c_write(ts, REG_WR_ADDRL, reg); rpi_touchscreen_i2c_write(ts, REG_WRITEH, val >> 8); @@ -268,6 +272,9 @@ static int rpi_touchscreen_disable(struct drm_panel *panel) { struct rpi_touchscreen *ts = panel_to_ts(panel); + if (!ts->connected) + return 0; + rpi_touchscreen_i2c_write(ts, REG_PWM, 0); rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); @@ -286,6 +293,9 @@ static int rpi_touchscreen_enable(struct drm_panel *panel) struct rpi_touchscreen *ts = panel_to_ts(panel); int i; + if (!ts->connected) + return 0; + rpi_touchscreen_i2c_write(ts, REG_POWERON, 1); /* Wait for nPWRDWN to go low to indicate poweron is done. */ for (i = 0; i < 100; i++) { @@ -330,6 +340,10 @@ static int rpi_touchscreen_get_modes(struct drm_panel *panel) struct drm_device *drm = panel->drm; unsigned int i, num = 0; static const u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; + struct rpi_touchscreen *ts = panel_to_ts(panel); + + if (!ts->connected) + return 0; for (i = 0; i < ARRAY_SIZE(rpi_touchscreen_modes); i++) { const struct drm_display_mode *m = &rpi_touchscreen_modes[i]; @@ -362,7 +376,34 @@ static int rpi_touchscreen_get_modes(struct drm_panel *panel) return num; } +static int rpi_touchscreen_detect(struct drm_panel *panel) +{ + struct rpi_touchscreen *ts = panel_to_ts(panel); + int ver; + + if (ts->connected) + return connector_status_connected; + + ver = rpi_touchscreen_i2c_read(ts, REG_ID); + switch (ver) { + case 0xde: /* ver 1 */ + case 0xc3: /* ver 2 */ + ts->connected = true; + + /* Turn off at boot, so we can cleanly sequence powering on. */ + rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); + + return connector_status_connected; + + default: + break; + } + + return connector_status_disconnected; +} + static const struct drm_panel_funcs rpi_touchscreen_funcs = { + .detect = rpi_touchscreen_detect, .disable = rpi_touchscreen_disable, .unprepare = rpi_touchscreen_noop, .prepare = rpi_touchscreen_noop, @@ -393,22 +434,24 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c, ts->i2c = i2c; ver = rpi_touchscreen_i2c_read(ts, REG_ID); - if (ver < 0) { - dev_err(dev, "Atmel I2C read failed: %d\n", ver); - return -ENODEV; - } - switch (ver) { case 0xde: /* ver 1 */ case 0xc3: /* ver 2 */ + ts->connected = true; + + /* Turn off at boot, so we can cleanly sequence powering on. */ + rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); break; default: - dev_err(dev, "Unknown Atmel firmware revision: 0x%02x\n", ver); - return -ENODEV; + if (ver < 0) + dev_err(dev, "Atmel I2C read failed: %d\n", ver); + else + dev_err(dev, + "Unknown Atmel firmware revision: 0x%02x\n", + ver); + break; } - /* Turn off at boot, so we can cleanly sequence powering on. */ - rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); /* Look up the DSI host. It needs to probe before we do. */ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); @@ -432,6 +475,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c, ts->base.dev = dev; ts->base.funcs = &rpi_touchscreen_funcs; + ts->base.polled = DRM_CONNECTOR_POLL_CONNECT; /* This appears last, as it's what will unblock the DSI host * driver's component bind function.