Received: by 10.192.165.148 with SMTP id m20csp1654225imm; Thu, 3 May 2018 03:14:26 -0700 (PDT) X-Google-Smtp-Source: AB8JxZr063Wi+EyILmd25ioDwXmTbZre0SqARiqIujPUWG7Ukre+9wzsajAMVtpZOfyWrpb2zwJE X-Received: by 2002:a17:902:b692:: with SMTP id c18-v6mr8863851pls.307.1525342466023; Thu, 03 May 2018 03:14:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525342465; cv=none; d=google.com; s=arc-20160816; b=ybi8Pqj0aYw9AzI5EdwpLdWKKipaZ3rizhzj7P8ORfo2vQ3rN5Tm85N2TtsG0SBJHl qrNDqMCo/pIdTeAP6b88Ow0K2Fuybv696PMaFgjAbzUY/Z8aiviN9/YIG2n9ggSCSgTj 8r+09edwghWEJ+RtaEyyYQge3bcY++Df+bygStX235gNj5B83CZfNWOItXQ8T8nVJPw+ 2bXP/j25ZrMx5pcfqJxtkdMRsPR0yKS6REHOI/x3oKZkZ5kE4Hij6d1Z53IOfLF9XgEJ 6nejMVogdwPHE1GjYA7UtokOeV9oWi1Et/fsqSd0t0Qun1m7kXLyMhdK2PlIE4kwewIy Dd0w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dmarc-filter:dkim-signature:dkim-signature :arc-authentication-results; bh=gVBnTgu8z5eLfzdbi8k8Sqcvs5BeKvzYt/nv3YmoglA=; b=Ld9bHzEd9cBbG3p5jNppk9ROO7Q6qND2ASK+aYkg3RNyFrAQvbfXNAOjDEfOk3Fb6D qQg/Py4qVursl1gW8ChDNpjcSxGrt6aFRY+K34dNHdXQQEGQ7CdLx/hqln1QbFu7D2Na q9G6CxnEDIa8/TkpzJ4QeT+Xh8hkuHHJE3sciquPaWHuqXkXj0+6vxR10VXVtIprxZsj Z67IFU0jenXWoVWWY5ZQD8PTLjI5FPsZRlN+5Kcpp47DEnNpmhh7sM1EDjye8e43KYUa rdppw8BqPnKzUrbKE9AI9wtbkLxmfUyASnfvVrUMg3A5zU1Bi/HqbvA1BdPqsoBPu7Sl 0flA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=L3Df447R; dkim=pass header.i=@codeaurora.org header.s=default header.b=aagzscSl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e20-v6si11004765pgn.130.2018.05.03.03.14.11; Thu, 03 May 2018 03:14:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=L3Df447R; dkim=pass header.i=@codeaurora.org header.s=default header.b=aagzscSl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751941AbeECKNn (ORCPT + 99 others); Thu, 3 May 2018 06:13:43 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:57604 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751403AbeECKNj (ORCPT ); Thu, 3 May 2018 06:13:39 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 2E9E96090E; Thu, 3 May 2018 10:13:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1525342419; bh=2S2mAkTROpx17tgHwBVDTb5hdaUmUYce8APaSSzPA4Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L3Df447R3CnC9tHimQtADcrUB/wdtZs/m8gSWKREYOwXOrtBsd+NkuZe0rCyszEqM ZHZZg1DNVT8lCtubDYNbStpdlzA3zOWzivKVojqvFgmLX/vQdMrCL4fDv2PiSk70Bz 5ZT4hmxnG6D9RgBP2xidxHnX/FUqG8Fg78IIZWRM= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from kgunda-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: kgunda@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 557CD60807; Thu, 3 May 2018 10:13:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1525342418; bh=2S2mAkTROpx17tgHwBVDTb5hdaUmUYce8APaSSzPA4Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aagzscSlSNGvS9J+WyJiOcxib7o7jd9YBmhCsjeNqYGAqdYO3QzWcPMX76ayJ2lhU QvZ/yntGzVocdtk+R6UkXWEgp/EwczvbciZjU6a7EC33H0DcN7uivNU86hb4c40uCP PVDVbQh1yEFDnL8pe61SS8jRkh7GZcG0tIu1Rw8Q= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 557CD60807 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=kgunda@codeaurora.org From: Kiran Gunda To: bjorn.andersson@linaro.org, Lee Jones , Daniel Thompson , Jingoo Han , Bartlomiej Zolnierkiewicz , dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: linux-arm-msm@vger.kernel.org, linux-leds@vger.kernel.org, Kiran Gunda Subject: [PATCH V2 4/5] backlight: qcom-wled: Add support for OVP interrupt handling Date: Thu, 3 May 2018 15:42:31 +0530 Message-Id: <1525342352-25072-5-git-send-email-kgunda@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1525342352-25072-1-git-send-email-kgunda@codeaurora.org> References: <1525342352-25072-1-git-send-email-kgunda@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org WLED peripheral has over voltage protection(OVP) circuitry and the OVP fault is notified through an interrupt. Though this fault condition rising is due to an incorrect hardware configuration is mitigated in the hardware, it still needs to be detected and handled. Add support for it. When WLED module is enabled, keep OVP fault interrupt disabled for 10 ms to account for soft start delay. Signed-off-by: Kiran Gunda --- drivers/video/backlight/qcom-wled.c | 118 +++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index 2cfba77..80ae084 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -23,14 +23,20 @@ /* From DT binding */ #define WLED_DEFAULT_BRIGHTNESS 2048 - +#define WLED_SOFT_START_DLY_US 10000 #define WLED3_SINK_REG_BRIGHT_MAX 0xFFF /* WLED3 Control registers */ #define WLED3_CTRL_REG_FAULT_STATUS 0x08 +#define WLED3_CTRL_REG_ILIM_FAULT_BIT BIT(0) +#define WLED3_CTRL_REG_OVP_FAULT_BIT BIT(1) +#define WLED4_CTRL_REG_SC_FAULT_BIT BIT(2) + +#define WLED3_CTRL_REG_INT_RT_STS 0x10 #define WLED3_CTRL_REG_MOD_EN 0x46 #define WLED3_CTRL_REG_MOD_EN_MASK BIT(7) +#define WLED3_CTRL_REG_MOD_EN_BIT BIT(7) #define WLED3_CTRL_REG_FREQ 0x4c #define WLED3_CTRL_REG_FREQ_MASK GENMASK(3, 0) @@ -161,9 +167,12 @@ struct wled { u32 short_count; const int *version; int short_irq; + int ovp_irq; bool force_mod_disable; + bool ovp_irq_disabled; struct wled_config cfg; + struct delayed_work ovp_work; int (*wled_set_brightness)(struct wled *wled, u16 brightness); int (*wled_sync_toggle)(struct wled *wled); }; @@ -209,6 +218,32 @@ static int wled4_set_brightness(struct wled *wled, u16 brightness) return 0; } +static void wled_ovp_work(struct work_struct *work) +{ + u32 val; + int rc; + + struct wled *wled = container_of(work, + struct wled, ovp_work.work); + + rc = regmap_read(wled->regmap, wled->ctrl_addr + WLED3_CTRL_REG_MOD_EN, + &val); + if (rc < 0) + return; + + if (val & WLED3_CTRL_REG_MOD_EN_BIT) { + if (wled->ovp_irq > 0 && wled->ovp_irq_disabled) { + enable_irq(wled->ovp_irq); + wled->ovp_irq_disabled = false; + } + } else { + if (wled->ovp_irq > 0 && !wled->ovp_irq_disabled) { + disable_irq(wled->ovp_irq); + wled->ovp_irq_disabled = true; + } + } +} + static int wled_module_enable(struct wled *wled, int val) { int rc; @@ -220,7 +255,12 @@ static int wled_module_enable(struct wled *wled, int val) WLED3_CTRL_REG_MOD_EN, WLED3_CTRL_REG_MOD_EN_MASK, WLED3_CTRL_REG_MOD_EN_MASK); - return rc; + if (rc < 0) + return rc; + + schedule_delayed_work(&wled->ovp_work, WLED_SOFT_START_DLY_US); + + return 0; } static int wled3_sync_toggle(struct wled *wled) @@ -346,6 +386,36 @@ static irqreturn_t wled_short_irq_handler(int irq, void *_wled) return IRQ_HANDLED; } +static irqreturn_t wled_ovp_irq_handler(int irq, void *_wled) +{ + struct wled *wled = _wled; + int rc; + u32 int_sts, fault_sts; + + rc = regmap_read(wled->regmap, + wled->ctrl_addr + WLED3_CTRL_REG_INT_RT_STS, &int_sts); + if (rc < 0) { + dev_err(wled->dev, "Error in reading WLED3_INT_RT_STS rc=%d\n", + rc); + return IRQ_HANDLED; + } + + rc = regmap_read(wled->regmap, wled->ctrl_addr + + WLED3_CTRL_REG_FAULT_STATUS, &fault_sts); + if (rc < 0) { + dev_err(wled->dev, "Error in reading WLED_FAULT_STATUS rc=%d\n", + rc); + return IRQ_HANDLED; + } + + if (fault_sts & + (WLED3_CTRL_REG_OVP_FAULT_BIT | WLED3_CTRL_REG_ILIM_FAULT_BIT)) + dev_dbg(wled->dev, "WLED OVP fault detected, int_sts=%x fault_sts= %x\n", + int_sts, fault_sts); + + return IRQ_HANDLED; +} + static int wled3_setup(struct wled *wled) { u16 addr; @@ -821,6 +891,44 @@ static int wled_configure_short_irq(struct wled *wled, return rc; } +static int wled_configure_ovp_irq(struct wled *wled, + struct platform_device *pdev) +{ + int rc = 0; + u32 val; + + if (*wled->version == WLED_PM8941) + return 0; + + wled->ovp_irq = platform_get_irq_byname(pdev, "ovp"); + if (wled->ovp_irq < 0) { + dev_dbg(&pdev->dev, "ovp irq is not used\n"); + return 0; + } + + rc = devm_request_threaded_irq(wled->dev, wled->ovp_irq, NULL, + wled_ovp_irq_handler, IRQF_ONESHOT, + "wled_ovp_irq", wled); + if (rc < 0) { + dev_err(wled->dev, "Unable to request ovp_irq (err:%d)\n", + rc); + return 0; + } + + rc = regmap_read(wled->regmap, wled->ctrl_addr + + WLED3_CTRL_REG_MOD_EN, &val); + if (rc < 0) + return rc; + + /* Keep OVP irq disabled until module is enabled */ + if (!rc && !(val & WLED3_CTRL_REG_MOD_EN_MASK)) { + disable_irq(wled->ovp_irq); + wled->ovp_irq_disabled = true; + } + + return rc; +} + static const struct backlight_ops wled_ops = { .update_status = wled_update_status, }; @@ -874,10 +982,16 @@ static int wled_probe(struct platform_device *pdev) } } + INIT_DELAYED_WORK(&wled->ovp_work, wled_ovp_work); + rc = wled_configure_short_irq(wled, pdev); if (rc < 0) return rc; + rc = wled_configure_ovp_irq(wled, pdev); + if (rc < 0) + return rc; + val = WLED_DEFAULT_BRIGHTNESS; of_property_read_u32(pdev->dev.of_node, "default-brightness", &val); -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project