From patchwork Fri Jan 2 13:41:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Kumar, Shobhit" X-Patchwork-Id: 5559101 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9C7119F1BF for ; Fri, 2 Jan 2015 13:38:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7079920108 for ; Fri, 2 Jan 2015 13:38:54 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 6050320212 for ; Fri, 2 Jan 2015 13:38:53 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DED416E37D; Fri, 2 Jan 2015 05:38:52 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTP id 128B86E37D for ; Fri, 2 Jan 2015 05:38:52 -0800 (PST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP; 02 Jan 2015 05:34:24 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,862,1389772800"; d="scan'208";a="435860337" Received: from shobhit-desk.iind.intel.com ([10.223.25.24]) by FMSMGA003.fm.intel.com with ESMTP; 02 Jan 2015 05:26:41 -0800 From: Shobhit Kumar To: intel-gfx Date: Fri, 2 Jan 2015 19:11:24 +0530 Message-Id: <1420206085-2913-4-git-send-email-shobhit.kumar@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1420206085-2913-1-git-send-email-shobhit.kumar@intel.com> References: <1420206085-2913-1-git-send-email-shobhit.kumar@intel.com> MIME-Version: 1.0 Cc: Jani Nikula , Daniel Vetter , jacob.jun.pan@intel.com, Shobhit Kumar Subject: [Intel-gfx] [RFC v2 3/4] drm/panel: Add new panel driver based on crystal cove pmic X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This driver provides support for the "crystal_cove_panel" cell device. On BYT-T pmic has to be used to enable/disable panel. Signed-off-by: Shobhit Kumar Reviewed-by: Jani Nikula --- drivers/gpu/drm/panel/Kconfig | 7 ++ drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-crystalcove.c | 191 ++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-crystalcove.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 024e98e..d813bd1 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -40,4 +40,11 @@ config DRM_PANEL_SHARP_LQ101R1SX01 To compile this driver as a module, choose M here: the module will be called panel-sharp-lq101r1sx01. +config DRM_PANEL_CRYSTALCOVE + tristate "Crystalcove PMIC controlled panel" + depends on INTEL_SOC_PMIC + help + Say Y here if you want to enable support for DSI panel and backlight + control using crystalcove pmic. This is used for BYT CR configurations + endmenu diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 4b2a043..c05824e 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o +obj-$(CONFIG_DRM_PANEL_CRYSTALCOVE) += panel-crystalcove.o diff --git a/drivers/gpu/drm/panel/panel-crystalcove.c b/drivers/gpu/drm/panel/panel-crystalcove.c new file mode 100644 index 0000000..22f7ff5 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-crystalcove.c @@ -0,0 +1,191 @@ +/* + * Copyright © 2006-2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Shobhit Kumar + */ + +#include +#include +#include +#include +#include +#include + +#define PMIC_PANEL_EN 0x52 +#define PMIC_PWM_EN 0x51 +#define PMIC_BKL_EN 0x4B +#define PMIC_PWM_LEVEL 0x4E + +struct crystalcove_panel { + struct drm_panel base; + char name[NAME_MAX]; + bool prepared; + bool enabled; + + struct mutex lock; + + /* crystal cove pmic regmap */ + struct regmap *regmap; +}; + +static inline struct crystalcove_panel *to_crystalcove_panel(struct drm_panel *panel) +{ + return container_of(panel, struct crystalcove_panel, base); +} + +static int crystalcove_panel_disable(struct drm_panel *panel) +{ + struct crystalcove_panel *p = to_crystalcove_panel(panel); + + if (!p->enabled) + return 0; + + DRM_DEBUG_KMS("\n"); + + /* invoke the pmic driver */ + regmap_write(p->regmap, PMIC_PANEL_EN, 0x00); + + /* Disable backlight as well */ + regmap_write(p->regmap, PMIC_PWM_LEVEL, 0); + msleep(20); + regmap_write(p->regmap, PMIC_PWM_EN, 0x00); + regmap_write(p->regmap, PMIC_BKL_EN, 0x7F); + + p->enabled = false; + + return 0; +} + +static int crystalcove_panel_unprepare(struct drm_panel *panel) +{ + struct crystalcove_panel *p = to_crystalcove_panel(panel); + + if (!p->prepared) + return 0; + + /* Nothing needed */ + p->prepared = false; + + return 0; +} + +static int crystalcove_panel_prepare(struct drm_panel *panel) +{ + struct crystalcove_panel *p = to_crystalcove_panel(panel); + + if (p->prepared) + return 0; + + /* Nothing needed */ + p->prepared = true; + + return 0; +} + +static int crystalcove_panel_enable(struct drm_panel *panel) +{ + struct crystalcove_panel *p = to_crystalcove_panel(panel); + + if (p->enabled) + return 0; + + DRM_DEBUG_KMS("\n"); + + /* invoke the pmic driver */ + regmap_write(p->regmap, PMIC_PANEL_EN, 0x01); + + /* Enable BKL as well */ + regmap_write(p->regmap, PMIC_BKL_EN, 0xFF); + regmap_write(p->regmap, PMIC_PWM_EN, 0x01); + msleep(20); + regmap_write(p->regmap, PMIC_PWM_LEVEL, 255); + + p->enabled = true; + + return 0; +} + +static const struct drm_panel_funcs crystalcove_panel_funcs = { + .disable = crystalcove_panel_disable, + .unprepare = crystalcove_panel_unprepare, + .prepare = crystalcove_panel_prepare, + .enable = crystalcove_panel_enable, +}; + +static int crystalcove_panel_probe(struct platform_device *pdev) +{ + struct crystalcove_panel *panel; + int retval; + struct device *dev = pdev->dev.parent; + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); + + panel = devm_kzalloc(&pdev->dev, sizeof(*panel), GFP_KERNEL); + if (!panel) + return -ENOMEM; + + DRM_DEBUG_KMS("\n"); + + platform_set_drvdata(pdev, panel); + + strcpy(panel->base.name, "crystal_cove_panel"); + panel->regmap = pmic->regmap; + + regmap_read(panel->regmap, PMIC_PANEL_EN, &retval); + panel->enabled = panel->prepared = retval ? true : false; + + drm_panel_init(&panel->base); + panel->base.dev = dev; + panel->base.funcs = &crystalcove_panel_funcs; + + drm_panel_add(&panel->base); + + return 0; +} + +static int crystalcove_panel_remove(struct platform_device *pdev) +{ + struct crystalcove_panel *panel = platform_get_drvdata(pdev); + + DRM_DEBUG_KMS("\n"); + + drm_panel_detach(&panel->base); + drm_panel_remove(&panel->base); + + crystalcove_panel_disable(&panel->base); + + return 0; +} + +static struct platform_driver crystalcove_panel_driver = { + .probe = crystalcove_panel_probe, + .remove = crystalcove_panel_remove, + .driver = { + .name = "crystal_cove_panel", + }, +}; + +module_platform_driver(crystalcove_panel_driver); + +MODULE_AUTHOR("Shobhit Kumar