From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754639AbdAaABQ (ORCPT ); Mon, 30 Jan 2017 19:01:16 -0500 Received: from mailout3.samsung.com ([203.254.224.33]:33346 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753464AbdAaABL (ORCPT ); Mon, 30 Jan 2017 19:01:11 -0500 MIME-version: 1.0 Content-type: text/plain; charset=UTF-8 X-AuditID: b6c32a59-f79be6d0000012bb-14-588fd3c36efb Content-transfer-encoding: 8BIT Message-id: <588FD3C3.7080508@samsung.com> Date: Tue, 31 Jan 2017 09:01:07 +0900 From: Inki Dae User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 To: Hoegeun Kwon , thierry.reding@gmail.com Cc: robh@kernel.org, Krzysztof Kozlowski , airlied@linux.ie, kgene@kernel.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-samsung-soc@vger.kernel.org, a.hajda@samsung.com, cw00.choi@samsung.com, jh80.chung@samsung.com, andi.shyti@samsung.com, Donghwa Lee , Hyungwon Hwang Subject: Re: [PATCH v8 2/3] drm/panel: Add support for S6E3HA2 panel driver on TM2 board In-reply-to: <08c5d94b-c76f-af14-c08f-478e26a34a7c@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrDJsWRmVeSWpSXmKPExsWy7bCmhu6Ry/0RBhePMlrcWneO1aL33Ekm i+1HnrFaXP/ynNVi/hGg2PXzdhZXvr5ns3i/vIvNYumMPlaLG7/aWC36H79mtjh/fgO7xeVd c9gsZpzfx2Txf88Odoufu+axOAh47Jx1l91j06pONo/t3x6wetzvPs7k0bdlFaPH501yAWxR qTYZqYkpqUUKqXnJ+SmZeem2St7B8c7xpmYGhrqGlhbmSgp5ibmptkouPgG6bpk5QHcrKZQl 5pQChQISi4uV9O1sivJLS1IVMvKLS2yVog0NjfQMDcz1jIyM9EyMY62MTIFKElIzLjybzVLw 8S9jxeR715gaGE8fZOxi5OSQEDCRmHjzMhOELSZx4d56ti5GLg4hgaWMEqsOr2eBcNqZJHpf zYTr+NrQDJVYzijxZMoVsHZeAUGJH5PvASU4OJgF5CWOXMoGCTMLaEps3b2eHaL+HqPExN1H GSHqtSRONSxlBbFZBFQlPv5sArPZgOyJK+6zgdiiAhESO+d/YwexRQRcJZYfagdbzCwwgVmi YfVOsAZhgSiJyQu/gdmcAvYSa+c+YwQpkhD4yC5x4Fcv2EUSArISmw4wQ3zgInF+ySR2CFtY 4tXxLVC2tMTfpbegersZJa739LBBOB2MEn87/7NAVBlL3H9wjxniNz6J3t9PmCAW8Ep0tAlB lHhI/JpxAxpcjhJf9rZAvd/HJPFy02KmCYzys5BCbBYixGYhhdgCRuZVjGKpBcW56anFpgWm esWJucWleel6yfm5mxjBKVcrcgfjlZlBhxgFOBiVeHgVTvVHCLEmlhVX5h5ilOBgVhLhDToP FOJNSaysSi3Kjy8qzUktPsRoCgzwicxSosn5wHyQVxJvaGJmaGJkCYTmhuZK4rwLKqwjhATS E0tSs1NTC1KLYPqYODilGhgbVJZULHBW4J95+5s630K3rUeeC95/6StzykPoql+fp7DChrKo vMk7QjVvzEv+mS8esS091utj4s6pj+0VO/RWcv29++2ZlfCtSOeT7sH5gX90Y/O5eHs6fi60 nrF15ky3zy4rDsSde/lb0XGK8eSXR0XYXDLWzil6kGg86/rKynSPZ4HTVn5QYinOSDTUYi4q TgQAUxaIxs8DAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOIsWRmVeSWpSXmKPExsVy+t9jAd3Dl/sjDBqPKVjcWneO1aL33Ekm i+1HnrFaXP/ynNVi/hGg2PXzdhZXvr5ns3i/vIvNYumMPlaLG7/aWC36H79mtjh/fgO7xeVd c9gsZpzfx2Txf88Odoufu+axOAh47Jx1l91j06pONo/t3x6wetzvPs7k0bdlFaPH501yAWxR bjYZqYkpqUUKqXnJ+SmZeem2SqEhbroWSgp5ibmptkoRur4hQUoKZYk5pUCekQEacHAOcA9W 0rdLcMu48Gw2S8HHv4wVk+9dY2pgPH2QsYuRk0NCwETia0MzC4QtJnHh3nq2LkYuDiGBpYwS X77PBEvwCghK/Jh8D8jm4GAWkJc4cikbJMwsoC4xad4iZoj6B4wSD3ovskLUa0mcalgKZrMI qEp8/NkEZrMB2RNX3GcDmSMqECHRfaISJCwi4Cqx/FA7C8gcZoEJzBJnr0EcJywQJXFu+ltW iAV9TBJzX78AO4hTwF5i7dxnjBMYBWYhuW8Wwn2zkNy3gJF5FaNEakFyQXFSeq5RXmq5XnFi bnFpXrpecn7uJkZwJD+T3sF4eJf7IUYBDkYlHl6Ntv4IIdbEsuLK3EOMEhzMSiK8QeeBQrwp iZVVqUX58UWlOanFhxhNgR6cyCwlmpwPTDJ5JfGGJuYm5sYGFuaWliZGSuK8jbOfhQsJpCeW pGanphakFsH0MXFwSjUwTn7Puy7pgcy69V4pkpmxL9cqTHl8NHunv/93Nkf95Gv8B99K3I1m UFXJSeBpXZk38+LBUzM//1jMmL9s+Y7JkUvXC3rE/tuiYeB1ubHDIt3o6419V3WX/I+Ikal4 UbfkGoPBxIUBUuEs085H/JuywPeES4L9AreeHVFaRr6p1mETnQ7PdG1sVWIpzkg01GIuKk4E AAwXUQH6AgAA X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170131000107epcas5p4dc523fb5257b5d023df656ce83d094ea X-Msg-Generator: CA X-Sender-IP: 203.254.230.27 X-Local-Sender: =?UTF-8?B?64yA7J246riwG1RpemVuIFBsYXRmb3JtIExhYihTL1fshLw=?= =?UTF-8?B?7YSwKRvsgrzshLHsoITsnpAbUzUo7LGF7J6EKS/ssYXsnoQ=?= X-Global-Sender: =?UTF-8?B?SW5raSBEYWUbVGl6ZW4gUGxhdGZvcm0gTGFiLhtTYW1zdW5n?= =?UTF-8?B?IEVsZWN0cm9uaWNzG1M1L1NlbmlvciBFbmdpbmVlcg==?= X-Sender-Code: =?UTF-8?B?QzEwG1NUQUYbQzEwVjgxMTE=?= CMS-TYPE: 105P DLP-Filter: Pass X-CFilter-Loop: Reflected X-HopCount: 7 X-CMS-RootMailID: 20170111063408epcas5p2e6ec091549c3ffed8462fd95d11d3c82 X-RootMTR: 20170111063408epcas5p2e6ec091549c3ffed8462fd95d11d3c82 References: <1484116439-7275-1-git-send-email-hoegeun.kwon@samsung.com> <1484116439-7275-3-git-send-email-hoegeun.kwon@samsung.com> <08c5d94b-c76f-af14-c08f-478e26a34a7c@samsung.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 2017년 01월 24일 10:50에 Hoegeun Kwon 이(가) 쓴 글: > Dear Thierry, > > Could you please review this patch? Thierry, I think this patch has been reviewed enough but no comment from you. Seems you are busy. I will pick up this. Thanks. > > Best Regards, > Hoegeun Kwon > > On 01/11/2017 03:33 PM, Hoegeun Kwon wrote: >> This patch add support for MIPI-DSI based S6E3HA2 AMOLED panel >> driver. This panel has 1440x2560 resolution in 5.7-inch physical >> panel in the TM2 device. >> >> Signed-off-by: Donghwa Lee >> Signed-off-by: Hyungwon Hwang >> Signed-off-by: Hoegeun Kwon >> Tested-by: Chanwoo Choi >> Reviewed-by: Andrzej Hajda >> --- >> drivers/gpu/drm/panel/Kconfig | 6 + >> drivers/gpu/drm/panel/Makefile | 1 + >> drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c | 754 ++++++++++++++++++++++++++ >> 3 files changed, 761 insertions(+) >> create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c >> >> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig >> index 62aba97..d913c83 100644 >> --- a/drivers/gpu/drm/panel/Kconfig >> +++ b/drivers/gpu/drm/panel/Kconfig >> @@ -52,6 +52,12 @@ config DRM_PANEL_PANASONIC_VVX10F034N00 >> WUXGA (1920x1200) Novatek NT1397-based DSI panel as found in some >> Xperia Z2 tablets >> +config DRM_PANEL_SAMSUNG_S6E3HA2 >> + tristate "Samsung S6E3HA2 DSI video mode panel" >> + depends on OF >> + depends on DRM_MIPI_DSI >> + select VIDEOMODE_HELPERS >> + >> config DRM_PANEL_SAMSUNG_S6E8AA0 >> tristate "Samsung S6E8AA0 DSI video mode panel" >> depends on OF >> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile >> index a5c7ec0..1d483b0 100644 >> --- a/drivers/gpu/drm/panel/Makefile >> +++ b/drivers/gpu/drm/panel/Makefile >> @@ -3,6 +3,7 @@ obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o >> obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o >> obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o >> obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o >> +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o >> obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o >> obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o >> obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o >> diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c >> new file mode 100644 >> index 0000000..0b9c6f4 >> --- /dev/null >> +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c >> @@ -0,0 +1,754 @@ >> +/* >> + * MIPI-DSI based s6e3ha2 AMOLED 5.7 inch panel driver. >> + * >> + * Copyright (c) 2016 Samsung Electronics Co., Ltd. >> + * Donghwa Lee >> + * Hyungwon Hwang >> + * Hoegeun Kwon >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define S6E3HA2_MIN_BRIGHTNESS 0 >> +#define S6E3HA2_MAX_BRIGHTNESS 100 >> +#define S6E3HA2_DEFAULT_BRIGHTNESS 80 >> + >> +#define S6E3HA2_NUM_GAMMA_STEPS 46 >> +#define S6E3HA2_GAMMA_CMD_CNT 35 >> +#define S6E3HA2_VINT_STATUS_MAX 10 >> + >> +static const u8 gamma_tbl[S6E3HA2_NUM_GAMMA_STEPS][S6E3HA2_GAMMA_CMD_CNT] = { >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x82, 0x83, >> + 0x85, 0x88, 0x8b, 0x8b, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8c, >> + 0x94, 0x84, 0xb1, 0xaf, 0x8e, 0xcf, 0xad, 0xc9, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x84, 0x84, >> + 0x85, 0x87, 0x8b, 0x8a, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8a, >> + 0x93, 0x84, 0xb0, 0xae, 0x8e, 0xc9, 0xa8, 0xc5, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83, >> + 0x85, 0x86, 0x8a, 0x8a, 0x84, 0x88, 0x81, 0x84, 0x8a, 0x88, 0x8a, >> + 0x91, 0x84, 0xb1, 0xae, 0x8b, 0xd5, 0xb2, 0xcc, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83, >> + 0x85, 0x86, 0x8a, 0x8a, 0x84, 0x87, 0x81, 0x84, 0x8a, 0x87, 0x8a, >> + 0x91, 0x85, 0xae, 0xac, 0x8a, 0xc3, 0xa3, 0xc0, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x85, 0x85, >> + 0x86, 0x85, 0x88, 0x89, 0x84, 0x89, 0x82, 0x84, 0x87, 0x85, 0x8b, >> + 0x91, 0x88, 0xad, 0xab, 0x8a, 0xb7, 0x9b, 0xb6, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83, >> + 0x85, 0x86, 0x89, 0x8a, 0x84, 0x89, 0x83, 0x83, 0x86, 0x84, 0x8b, >> + 0x90, 0x84, 0xb0, 0xae, 0x8b, 0xce, 0xad, 0xc8, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83, >> + 0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x89, >> + 0x8f, 0x84, 0xac, 0xaa, 0x89, 0xb1, 0x98, 0xaf, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83, >> + 0x85, 0x86, 0x88, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8c, >> + 0x91, 0x86, 0xac, 0xaa, 0x89, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84, >> + 0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x88, >> + 0x8b, 0x82, 0xad, 0xaa, 0x8a, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83, >> + 0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8a, >> + 0x8e, 0x84, 0xae, 0xac, 0x89, 0xda, 0xb7, 0xd0, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84, >> + 0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x80, 0x83, 0x82, 0x8b, >> + 0x8e, 0x85, 0xac, 0xaa, 0x89, 0xc8, 0xaa, 0xc1, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84, >> + 0x85, 0x86, 0x87, 0x89, 0x81, 0x85, 0x81, 0x84, 0x86, 0x84, 0x8c, >> + 0x8c, 0x84, 0xa9, 0xa8, 0x87, 0xa3, 0x92, 0xa1, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84, >> + 0x85, 0x86, 0x87, 0x89, 0x84, 0x86, 0x83, 0x80, 0x83, 0x81, 0x8c, >> + 0x8d, 0x84, 0xaa, 0xaa, 0x89, 0xce, 0xaf, 0xc5, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84, >> + 0x85, 0x86, 0x87, 0x89, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c, >> + 0x8c, 0x84, 0xa8, 0xa8, 0x88, 0xb5, 0x9f, 0xb0, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84, >> + 0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c, >> + 0x8b, 0x84, 0xab, 0xa8, 0x86, 0xd4, 0xb4, 0xc9, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84, >> + 0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x84, 0x84, 0x85, 0x8b, >> + 0x8a, 0x83, 0xa6, 0xa5, 0x84, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84, >> + 0x86, 0x85, 0x86, 0x86, 0x82, 0x85, 0x81, 0x82, 0x83, 0x84, 0x8e, >> + 0x8b, 0x83, 0xa4, 0xa3, 0x8a, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83, >> + 0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8e, >> + 0x8b, 0x83, 0xa4, 0xa2, 0x86, 0xc1, 0xa9, 0xb7, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83, >> + 0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8d, >> + 0x89, 0x82, 0xa2, 0xa1, 0x84, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83, >> + 0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x83, 0x83, 0x85, 0x8c, >> + 0x87, 0x7f, 0xa2, 0x9d, 0x88, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xbb, 0x00, 0xc5, 0x00, 0xb4, 0x87, 0x86, 0x86, 0x84, 0x83, >> + 0x86, 0x87, 0x87, 0x87, 0x80, 0x82, 0x7f, 0x86, 0x86, 0x88, 0x8a, >> + 0x84, 0x7e, 0x9d, 0x9c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xbd, 0x00, 0xc7, 0x00, 0xb7, 0x87, 0x85, 0x85, 0x84, 0x83, >> + 0x86, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x83, 0x84, 0x85, 0x8a, >> + 0x85, 0x7e, 0x9c, 0x9b, 0x85, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xc0, 0x00, 0xca, 0x00, 0xbb, 0x87, 0x86, 0x85, 0x83, 0x83, >> + 0x85, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x84, 0x85, 0x86, 0x89, >> + 0x83, 0x7d, 0x9c, 0x99, 0x87, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xc4, 0x00, 0xcd, 0x00, 0xbe, 0x87, 0x86, 0x85, 0x83, 0x83, >> + 0x86, 0x85, 0x85, 0x87, 0x81, 0x82, 0x80, 0x82, 0x82, 0x83, 0x8a, >> + 0x85, 0x7f, 0x9f, 0x9b, 0x86, 0xb4, 0xa1, 0xac, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xc7, 0x00, 0xd0, 0x00, 0xc2, 0x87, 0x85, 0x85, 0x83, 0x82, >> + 0x85, 0x85, 0x85, 0x86, 0x82, 0x83, 0x80, 0x82, 0x82, 0x84, 0x87, >> + 0x86, 0x80, 0x9e, 0x9a, 0x87, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xca, 0x00, 0xd2, 0x00, 0xc5, 0x87, 0x85, 0x84, 0x82, 0x82, >> + 0x84, 0x85, 0x85, 0x86, 0x81, 0x82, 0x7f, 0x82, 0x82, 0x84, 0x88, >> + 0x86, 0x81, 0x9d, 0x98, 0x86, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xce, 0x00, 0xd6, 0x00, 0xca, 0x86, 0x85, 0x84, 0x83, 0x83, >> + 0x85, 0x84, 0x84, 0x85, 0x81, 0x82, 0x80, 0x81, 0x81, 0x82, 0x89, >> + 0x86, 0x81, 0x9c, 0x97, 0x86, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xd1, 0x00, 0xd9, 0x00, 0xce, 0x86, 0x84, 0x83, 0x83, 0x82, >> + 0x85, 0x85, 0x85, 0x86, 0x81, 0x83, 0x81, 0x82, 0x82, 0x83, 0x86, >> + 0x83, 0x7f, 0x99, 0x95, 0x86, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xd4, 0x00, 0xdb, 0x00, 0xd1, 0x86, 0x85, 0x83, 0x83, 0x82, >> + 0x85, 0x84, 0x84, 0x85, 0x80, 0x83, 0x82, 0x80, 0x80, 0x81, 0x87, >> + 0x84, 0x81, 0x98, 0x93, 0x85, 0xae, 0x9c, 0xa8, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xd8, 0x00, 0xde, 0x00, 0xd6, 0x86, 0x84, 0x83, 0x81, 0x81, >> + 0x83, 0x85, 0x85, 0x85, 0x82, 0x83, 0x81, 0x81, 0x81, 0x83, 0x86, >> + 0x84, 0x80, 0x98, 0x91, 0x85, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xdc, 0x00, 0xe2, 0x00, 0xda, 0x85, 0x84, 0x83, 0x82, 0x82, >> + 0x84, 0x84, 0x84, 0x85, 0x81, 0x82, 0x82, 0x80, 0x80, 0x81, 0x83, >> + 0x82, 0x7f, 0x99, 0x93, 0x86, 0x94, 0x8b, 0x92, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xdf, 0x00, 0xe5, 0x00, 0xde, 0x85, 0x84, 0x82, 0x82, 0x82, >> + 0x84, 0x83, 0x83, 0x84, 0x81, 0x81, 0x80, 0x83, 0x82, 0x84, 0x82, >> + 0x81, 0x7f, 0x99, 0x92, 0x86, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81, >> + 0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x83, 0x83, 0x84, 0x80, >> + 0x81, 0x7c, 0x99, 0x92, 0x87, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x85, 0x84, 0x83, 0x81, 0x81, >> + 0x82, 0x82, 0x82, 0x83, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83, >> + 0x82, 0x80, 0x91, 0x8d, 0x83, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81, >> + 0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83, >> + 0x81, 0x7f, 0x91, 0x8c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81, >> + 0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x82, >> + 0x82, 0x7f, 0x94, 0x89, 0x84, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81, >> + 0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x83, >> + 0x82, 0x7f, 0x91, 0x85, 0x81, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81, >> + 0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x83, 0x82, 0x84, 0x83, >> + 0x82, 0x7f, 0x90, 0x84, 0x81, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x80, 0x80, >> + 0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x81, 0x81, >> + 0x82, 0x83, 0x7e, 0x80, 0x7c, 0xa4, 0x97, 0x9f, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xe9, 0x00, 0xec, 0x00, 0xe8, 0x84, 0x83, 0x82, 0x81, 0x81, >> + 0x82, 0x82, 0x82, 0x83, 0x7f, 0x7f, 0x7f, 0x81, 0x80, 0x82, 0x83, >> + 0x83, 0x84, 0x79, 0x7c, 0x79, 0xb1, 0xa0, 0xaa, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xed, 0x00, 0xf0, 0x00, 0xec, 0x83, 0x83, 0x82, 0x80, 0x80, >> + 0x81, 0x82, 0x82, 0x82, 0x7f, 0x7f, 0x7e, 0x81, 0x81, 0x82, 0x80, >> + 0x81, 0x81, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xf1, 0x00, 0xf4, 0x00, 0xf1, 0x83, 0x82, 0x82, 0x80, 0x80, >> + 0x81, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x7d, >> + 0x7e, 0x7f, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xf6, 0x00, 0xf7, 0x00, 0xf5, 0x82, 0x82, 0x81, 0x80, 0x80, >> + 0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x82, >> + 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x00, 0xfa, 0x00, 0xfb, 0x00, 0xfa, 0x81, 0x81, 0x81, 0x80, 0x80, >> + 0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, >> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, >> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, >> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, >> + 0x00, 0x00 }, >> + { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, >> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, >> + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, >> + 0x00, 0x00 } >> +}; >> + >> +unsigned char vint_table[S6E3HA2_VINT_STATUS_MAX] = { >> + 0x18, 0x19, 0x1a, 0x1b, 0x1c, >> + 0x1d, 0x1e, 0x1f, 0x20, 0x21 >> +}; >> + >> +struct s6e3ha2 { >> + struct device *dev; >> + struct drm_panel panel; >> + struct backlight_device *bl_dev; >> + >> + struct regulator_bulk_data supplies[2]; >> + struct gpio_desc *reset_gpio; >> + struct gpio_desc *enable_gpio; >> + >> + /* This field is tested by functions directly accessing DSI bus before >> + * transfer, transfer is skipped if it is set. In case of transfer >> + * failure or unexpected response the field is set to error value. >> + * Such construct allows to eliminate many checks in higher level >> + * functions. >> + */ >> + int error; >> +}; >> + >> +static int s6e3ha2_clear_error(struct s6e3ha2 *ctx) >> +{ >> + int ret = ctx->error; >> + >> + ctx->error = 0; >> + return ret; >> +} >> + >> +static void s6e3ha2_dcs_write(struct s6e3ha2 *ctx, const void *data, size_t len) >> +{ >> + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); >> + ssize_t ret; >> + >> + if (ctx->error < 0) >> + return; >> + >> + ret = mipi_dsi_dcs_write_buffer(dsi, data, len); >> + if (ret < 0) { >> + dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", >> + ret, (int)len, data); >> + ctx->error = ret; >> + } >> +} >> + >> +#define s6e3ha2_dcs_write_seq_static(ctx, seq...) do { \ >> + static const u8 d[] = { seq }; \ >> + s6e3ha2_dcs_write(ctx, d, ARRAY_SIZE(d)); \ >> +} while (0) >> + >> +static void s6e3ha2_test_key_on_f0(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0x5a, 0x5a); >> +} >> + >> +static void s6e3ha2_test_key_off_f0(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0xa5, 0xa5); >> +} >> + >> +static void s6e3ha2_test_key_on_fc(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0x5a, 0x5a); >> +} >> + >> +static void s6e3ha2_test_key_off_fc(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0xa5, 0xa5); >> +} >> + >> +static void s6e3ha2_single_dsi_set(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xf2, 0x67); >> + s6e3ha2_dcs_write_seq_static(ctx, 0xf9, 0x09); >> +} >> + >> +static void s6e3ha2_freq_calibration(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xfd, 0x1c); >> + s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20, 0x39); >> + s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0xa0); >> + s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20); >> + s6e3ha2_dcs_write_seq_static(ctx, 0xce, 0x03, 0x3b, 0x12, 0x62, >> + 0x40, 0x80, 0xc0, 0x28, 0x28, 0x28, 0x28, 0x39, 0xc5); >> +} >> + >> +static void s6e3ha2_aor_control(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xb2, 0x03, 0x10); >> +} >> + >> +static void s6e3ha2_caps_elvss_set(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xb6, 0x9c, 0x0a); >> +} >> + >> +static void s6e3ha2_acl_off(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0x55, 0x00); >> +} >> + >> +static void s6e3ha2_acl_off_opr(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xb5, 0x40); >> +} >> + >> +static void s6e3ha2_test_global(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x07); >> +} >> + >> +static void s6e3ha2_test(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xb8, 0x19); >> +} >> + >> +static void s6e3ha2_touch_hsync_on1(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, >> + 0xbd, 0x33, 0x11, 0x02, 0x16, 0x02, 0x16); >> +} >> + >> +static void s6e3ha2_pentile_control(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xc0, 0x00, 0x00, 0xd8, 0xd8); >> +} >> + >> +static void s6e3ha2_poc_global(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x20); >> +} >> + >> +static void s6e3ha2_poc_setting(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x08); >> +} >> + >> +static void s6e3ha2_pcd_set_off(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xcc, 0x40, 0x51); >> +} >> + >> +static void s6e3ha2_err_fg_set(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xed, 0x44); >> +} >> + >> +static void s6e3ha2_hbm_off(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0x53, 0x00); >> +} >> + >> +static void s6e3ha2_te_start_setting(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xb9, 0x10, 0x09, 0xff, 0x00, 0x09); >> +} >> + >> +static void s6e3ha2_gamma_update(struct s6e3ha2 *ctx) >> +{ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x03); >> + ndelay(100); /* need for 100ns delay */ >> + s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x00); >> +} >> + >> +static int s6e3ha2_get_brightness(struct backlight_device *bl_dev) >> +{ >> + return bl_dev->props.brightness; >> +} >> + >> +static void s6e3ha2_set_vint(struct s6e3ha2 *ctx) >> +{ >> + struct backlight_device *bl_dev = ctx->bl_dev; >> + unsigned int brightness = bl_dev->props.brightness; >> + unsigned char data[] = { 0xf4, 0x8b, >> + vint_table[brightness * (S6E3HA2_VINT_STATUS_MAX - 1) / >> + S6E3HA2_MAX_BRIGHTNESS] }; >> + >> + s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data)); >> +} >> + >> +static unsigned int s6e3ha2_get_brightness_index(unsigned int brightness) >> +{ >> + return (brightness * (S6E3HA2_NUM_GAMMA_STEPS - 1)) / >> + S6E3HA2_MAX_BRIGHTNESS; >> +} >> + >> +static int s6e3ha2_update_gamma(struct s6e3ha2 *ctx, unsigned int brightness) >> +{ >> + struct backlight_device *bl_dev = ctx->bl_dev; >> + unsigned int index = s6e3ha2_get_brightness_index(brightness); >> + u8 data[S6E3HA2_GAMMA_CMD_CNT + 1] = { 0xca, }; >> + >> + memcpy(data + 1, gamma_tbl + index, S6E3HA2_GAMMA_CMD_CNT); >> + s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data)); >> + >> + s6e3ha2_gamma_update(ctx); >> + bl_dev->props.brightness = brightness; >> + >> + return 0; >> +} >> + >> +static int s6e3ha2_set_brightness(struct backlight_device *bl_dev) >> +{ >> + struct s6e3ha2 *ctx = bl_get_data(bl_dev); >> + unsigned int brightness = bl_dev->props.brightness; >> + >> + if (brightness < S6E3HA2_MIN_BRIGHTNESS || >> + brightness > bl_dev->props.max_brightness) { >> + dev_err(ctx->dev, "Invalid brightness: %u\n", brightness); >> + return -EINVAL; >> + } >> + >> + if (bl_dev->props.power > FB_BLANK_NORMAL) >> + return -EPERM; >> + >> + s6e3ha2_test_key_on_f0(ctx); >> + s6e3ha2_update_gamma(ctx, brightness); >> + s6e3ha2_aor_control(ctx); >> + s6e3ha2_set_vint(ctx); >> + s6e3ha2_test_key_off_f0(ctx); >> + >> + return ctx->error; >> +} >> + >> +static const struct backlight_ops s6e3ha2_bl_ops = { >> + .get_brightness = s6e3ha2_get_brightness, >> + .update_status = s6e3ha2_set_brightness, >> +}; >> + >> +static int s6e3ha2_panel_init(struct s6e3ha2 *ctx) >> +{ >> + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); >> + int ret; >> + >> + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); >> + if (ret < 0) >> + return ret; >> + usleep_range(5000, 6000); >> + >> + s6e3ha2_test_key_on_f0(ctx); >> + s6e3ha2_single_dsi_set(ctx); >> + s6e3ha2_test_key_on_fc(ctx); >> + s6e3ha2_freq_calibration(ctx); >> + s6e3ha2_test_key_off_fc(ctx); >> + s6e3ha2_test_key_off_f0(ctx); >> + >> + return 0; >> +} >> + >> +static int s6e3ha2_power_off(struct s6e3ha2 *ctx) >> +{ >> + return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); >> +} >> + >> +static int s6e3ha2_disable(struct drm_panel *panel) >> +{ >> + struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel); >> + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); >> + int ret; >> + >> + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); >> + if (ret < 0) >> + return ret; >> + >> + ret = mipi_dsi_dcs_set_display_off(dsi); >> + if (ret < 0) >> + return ret; >> + >> + msleep(40); >> + ctx->bl_dev->props.power = FB_BLANK_NORMAL; >> + >> + return 0; >> +} >> + >> +static int s6e3ha2_unprepare(struct drm_panel *panel) >> +{ >> + struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel); >> + int ret; >> + >> + ret = s6e3ha2_clear_error(ctx); >> + if (!ret) >> + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; >> + >> + return s6e3ha2_power_off(ctx); >> +} >> + >> +static int s6e3ha2_power_on(struct s6e3ha2 *ctx) >> +{ >> + int ret; >> + >> + ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); >> + if (ret < 0) >> + return ret; >> + >> + msleep(120); >> + >> + gpiod_set_value(ctx->enable_gpio, 0); >> + usleep_range(5000, 6000); >> + gpiod_set_value(ctx->enable_gpio, 1); >> + >> + gpiod_set_value(ctx->reset_gpio, 1); >> + usleep_range(5000, 6000); >> + gpiod_set_value(ctx->reset_gpio, 0); >> + usleep_range(5000, 6000); >> + >> + return 0; >> +} >> +static int s6e3ha2_prepare(struct drm_panel *panel) >> +{ >> + struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel); >> + int ret; >> + >> + ret = s6e3ha2_power_on(ctx); >> + if (ret < 0) >> + return ret; >> + >> + ret = s6e3ha2_panel_init(ctx); >> + if (ret < 0) >> + goto err; >> + >> + ret = s6e3ha2_clear_error(ctx); >> + if (ret < 0) >> + goto err; >> + >> + ctx->bl_dev->props.power = FB_BLANK_NORMAL; >> + >> + return 0; >> + >> +err: >> + s6e3ha2_power_off(ctx); >> + return ret; >> +} >> + >> +static int s6e3ha2_enable(struct drm_panel *panel) >> +{ >> + struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel); >> + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); >> + int ret; >> + >> + /* common setting */ >> + ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); >> + if (ret < 0) >> + return ret; >> + >> + s6e3ha2_test_key_on_f0(ctx); >> + s6e3ha2_test_key_on_fc(ctx); >> + s6e3ha2_touch_hsync_on1(ctx); >> + s6e3ha2_pentile_control(ctx); >> + s6e3ha2_poc_global(ctx); >> + s6e3ha2_poc_setting(ctx); >> + s6e3ha2_test_key_off_fc(ctx); >> + >> + /* pcd setting off for TB */ >> + s6e3ha2_pcd_set_off(ctx); >> + s6e3ha2_err_fg_set(ctx); >> + s6e3ha2_te_start_setting(ctx); >> + >> + /* brightness setting */ >> + s6e3ha2_set_brightness(ctx->bl_dev); >> + s6e3ha2_aor_control(ctx); >> + s6e3ha2_caps_elvss_set(ctx); >> + s6e3ha2_gamma_update(ctx); >> + s6e3ha2_acl_off(ctx); >> + s6e3ha2_acl_off_opr(ctx); >> + s6e3ha2_hbm_off(ctx); >> + >> + /* elvss temp compensation */ >> + s6e3ha2_test_global(ctx); >> + s6e3ha2_test(ctx); >> + s6e3ha2_test_key_off_f0(ctx); >> + >> + if (ctx->error != 0) >> + return ctx->error; >> + >> + ret = mipi_dsi_dcs_set_display_on(dsi); >> + if (ret < 0) >> + return ret; >> + >> + ctx->bl_dev->props.power = FB_BLANK_UNBLANK; >> + >> + return 0; >> +} >> + >> +static const struct drm_display_mode default_mode = { >> + .clock = 222372, >> + .hdisplay = 1440, >> + .hsync_start = 1440 + 1, >> + .hsync_end = 1440 + 1 + 1, >> + .htotal = 1440 + 1 + 1 + 1, >> + .vdisplay = 2560, >> + .vsync_start = 2560 + 1, >> + .vsync_end = 2560 + 1 + 1, >> + .vtotal = 2560 + 1 + 1 + 15, >> + .vrefresh = 60, >> + .flags = 0, >> +}; >> + >> +static int s6e3ha2_get_modes(struct drm_panel *panel) >> +{ >> + struct drm_connector *connector = panel->connector; >> + struct drm_display_mode *mode; >> + >> + mode = drm_mode_duplicate(panel->drm, &default_mode); >> + if (!mode) { >> + DRM_ERROR("failed to add mode %ux%ux@%u\n", >> + default_mode.hdisplay, default_mode.vdisplay, >> + default_mode.vrefresh); >> + return -ENOMEM; >> + } >> + >> + drm_mode_set_name(mode); >> + >> + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; >> + drm_mode_probed_add(connector, mode); >> + >> + connector->display_info.width_mm = 71; >> + connector->display_info.height_mm = 125; >> + >> + return 1; >> +} >> + >> +static const struct drm_panel_funcs s6e3ha2_drm_funcs = { >> + .disable = s6e3ha2_disable, >> + .unprepare = s6e3ha2_unprepare, >> + .prepare = s6e3ha2_prepare, >> + .enable = s6e3ha2_enable, >> + .get_modes = s6e3ha2_get_modes, >> +}; >> + >> +static int s6e3ha2_probe(struct mipi_dsi_device *dsi) >> +{ >> + struct device *dev = &dsi->dev; >> + struct s6e3ha2 *ctx; >> + int ret; >> + >> + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); >> + if (!ctx) >> + return -ENOMEM; >> + >> + mipi_dsi_set_drvdata(dsi, ctx); >> + >> + ctx->dev = dev; >> + >> + dsi->lanes = 4; >> + dsi->format = MIPI_DSI_FMT_RGB888; >> + dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS; >> + >> + ctx->supplies[0].supply = "vdd3"; >> + ctx->supplies[1].supply = "vci"; >> + >> + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies), >> + ctx->supplies); >> + if (ret < 0) { >> + dev_err(dev, "failed to get regulators: %d\n", ret); >> + return ret; >> + } >> + >> + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); >> + if (IS_ERR(ctx->reset_gpio)) { >> + dev_err(dev, "cannot get reset-gpios %ld\n", >> + PTR_ERR(ctx->reset_gpio)); >> + return PTR_ERR(ctx->reset_gpio); >> + } >> + >> + ctx->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); >> + if (IS_ERR(ctx->enable_gpio)) { >> + dev_err(dev, "cannot get enable-gpios %ld\n", >> + PTR_ERR(ctx->enable_gpio)); >> + return PTR_ERR(ctx->enable_gpio); >> + } >> + >> + ctx->bl_dev = backlight_device_register("s6e3ha2", dev, ctx, >> + &s6e3ha2_bl_ops, NULL); >> + if (IS_ERR(ctx->bl_dev)) { >> + dev_err(dev, "failed to register backlight device\n"); >> + return PTR_ERR(ctx->bl_dev); >> + } >> + >> + ctx->bl_dev->props.max_brightness = S6E3HA2_MAX_BRIGHTNESS; >> + ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS; >> + ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; >> + >> + drm_panel_init(&ctx->panel); >> + ctx->panel.dev = dev; >> + ctx->panel.funcs = &s6e3ha2_drm_funcs; >> + >> + ret = drm_panel_add(&ctx->panel); >> + if (ret < 0) >> + goto unregister_backlight; >> + >> + ret = mipi_dsi_attach(dsi); >> + if (ret < 0) >> + goto remove_panel; >> + >> + return ret; >> + >> +remove_panel: >> + drm_panel_remove(&ctx->panel); >> + >> +unregister_backlight: >> + backlight_device_unregister(ctx->bl_dev); >> + >> + return ret; >> +} >> + >> +static int s6e3ha2_remove(struct mipi_dsi_device *dsi) >> +{ >> + struct s6e3ha2 *ctx = mipi_dsi_get_drvdata(dsi); >> + >> + mipi_dsi_detach(dsi); >> + drm_panel_remove(&ctx->panel); >> + backlight_device_unregister(ctx->bl_dev); >> + >> + return 0; >> +} >> + >> +static const struct of_device_id s6e3ha2_of_match[] = { >> + { .compatible = "samsung,s6e3ha2" }, >> + { } >> +}; >> +MODULE_DEVICE_TABLE(of, s6e3ha2_of_match); >> + >> +static struct mipi_dsi_driver s6e3ha2_driver = { >> + .probe = s6e3ha2_probe, >> + .remove = s6e3ha2_remove, >> + .driver = { >> + .name = "panel-samsung-s6e3ha2", >> + .of_match_table = s6e3ha2_of_match, >> + }, >> +}; >> +module_mipi_dsi_driver(s6e3ha2_driver); >> + >> +MODULE_AUTHOR("Donghwa Lee "); >> +MODULE_AUTHOR("Hyungwon Hwang "); >> +MODULE_AUTHOR("Hoegeun Kwon "); >> +MODULE_DESCRIPTION("MIPI-DSI based s6e3ha2 AMOLED Panel Driver"); >> +MODULE_LICENSE("GPL v2"); > > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > >