From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756605AbdADHAI (ORCPT ); Wed, 4 Jan 2017 02:00:08 -0500 Received: from mailout4.samsung.com ([203.254.224.34]:59401 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751837AbdADG7z (ORCPT ); Wed, 4 Jan 2017 01:59:55 -0500 X-AuditID: b6c32a2d-f79a76d0000074b4-2c-586c9d352427 From: Hoegeun Kwon To: robh@kernel.org, thierry.reding@gmail.com, airlied@linux.ie, kgene@kernel.org, krzk@kernel.org, inki.dae@samsung.com Cc: 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, Hoegeun Kwon , Donghwa Lee , Hyungwon Hwang Subject: [PATCH v4 2/3] drm/panel: Add support for S6E3HA2 panel driver on TM2 board Date: Wed, 04 Jan 2017 15:58:34 +0900 Message-id: <1483513115-3068-3-git-send-email-hoegeun.kwon@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1483513115-3068-1-git-send-email-hoegeun.kwon@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAAzVSfUgTYRzuvdvdTmlxrK8Xy1oHlQVb3tzcVRp9YQsDpbBWIevUa5P21W4z iwIx0rJcZgU6rVZo5pCyIaWilRqlhE6sMISaoVFUIuVHpVid2+T953l+7/O8v+f98SNQ6SQW RWRbHJzdwpooPFL0qGNdjFx9w6SLHWrDmYH7PRhT3NOFMP3jnzHm1nOB9vu3MG8mRnFmtKYI Z6rLXBhTGigRMe+mCjDm8tA3lPH768XM6+ZKnCnzP0GYfy2NYuZP803RVlLb5H4v1vq8F3Dt 48lBTBu4+BLRuhq8QDvmW5GKH+ISjBybxdllnCXTmpVtMSRSyfv0O/Tq+FhaTm9kNJTMwpq5 RGrnnlR5UrZJyE3JcliTUyilsjxPbdiSYLc6HZzMaOUdidRhmlYq6FiNQqlUKlRx6ZuUakFy hDNODw8httphkBu4G8DywOtmUAQiCEiqYOH3aTSEl8DeDw/wIhBJSMlqAGs7n6IhUojA0poS 8ZzjQfN1LHRRCeDU334QIlMAdl4eFM2qcFIOJy71I7N4EXkK/q7oE82KULIDgX2324KiheR+ WDpRFRSJyNWwqvVnMIiE3AXdxdfCAVfArhdXsVkcQWrh6L/nwdaQfCKGvoBLeIgQSDT0PQt/ Yif80doZjroQfn3ZEMbL4Ez1AAh5LwL4K/8eGiIlAP7Jqw+742Bg8EMQo+QCWDw9jIQaSOD5 AmlIooWVH+emtw26yrvDs6gA8Ep+DSgByz1gnhcs4Wy82cDxaptSwbNm3mkxKDKtZh8I7tx6 eSMY9yS3A5IA1HyJba9JJ8XYHP6kuR1AAqUWSZrcQkmSxZ48xdmtervTxPHtQC0M6goatTjT KmywxaGnVfG0SrlROBpaQy2VeHI366SkgXVwxzjOxtnnfAgREZUH0tbKtp9w9Y7UdZc9TL4z fsmZUXcmy7jyXEPucLJGP2bQ6P/+XnXaW2jrzR8zpMcfWZvgOeGKS9KVezIUusOqqdqZ0rfR PUnGV9WjY2sm4vuiY1rSu5ZWbUor62ip/5QSfcv/JTLf/b6uW7fGXTSS6S04e+D40ZSDu+Nm iFei8cazlIg3svR61M6z/wGUMCAeiQMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrIIsWRmVeSWpSXmKPExsVy+t9jQV2TuTkRBm/+S1jcWneO1aL33Ekm i+tfnrNazD8C5F4/b2dx5et7Nov3y7vYLJbO6GO1mHR/AovFjV9trBb9j18zW5w/v4Hd4vKu OWwWM87vY7L4v2cHu8XPXfNYHAQ8ds66y+6xaVUnm8f2bw9YPe53H2fy6NuyitHj8ya5ALYo N5uM1MSU1CKF1Lzk/JTMvHRbpdAQN10LJYW8xNxUW6UIXd+QICWFssScUiDPyAANODgHuAcr 6dsluGX8fvKYqWDlE8aK+8vuszYwXt7F2MXIySEhYCKxftdUVghbTOLCvfVsXYxcHEICsxgl jqy5zwzh/GKUWLvjChtIFZuArsTXnutMILaIQJXEg0NLWUCKmAUOM0m8/dsANlZYIEzieNNG sCIWAVWJJXs/MYPYvALuErN6p0CtlpM4eWwy2GpOAQ+J9/+PgNlCQDWXFpxhnMDIu4CRYRWj RGpBckFxUnquUV5quV5xYm5xaV66XnJ+7iZGcPQ8k97BeHiX+yFGAQ5GJR7eDV+yI4RYE8uK K3MPMUpwMCuJ8O6clRMhxJuSWFmVWpQfX1Sak1p8iNEU6LCJzFKiyfnAyM4riTc0MTcxNzaw MLe0NDFSEudtnP0sXEggPbEkNTs1tSC1CKaPiYNTqoFRaKHcO9EV34/OOXc3yLfOavquf7wf t/ybYrdJe//r74sDZBOvfZ9V6lcx66sLm+GK1bfqptldXbPvAPPcb31pOr3R39KKdcysX0xm k9/OlpS7apVgbvuWFze6DUr5HrN1BscG62zkupvaavez/vy/vnM+8p9nO4SsYr++4tBmvqSe gHiVx0vKlFiKMxINtZiLihMBqwaJv7QCAAA= X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170104065900epcas5p2ea5eef389301b71f8f57d6166c233014 X-Msg-Generator: CA X-Sender-IP: 203.254.230.27 X-Local-Sender: =?UTF-8?B?6raM7ZqM6re8G1RpemVuIFBsYXRmb3JtIExhYihTL1fshLw=?= =?UTF-8?B?7YSwKRvsgrzshLHsoITsnpAbUzMo7IKs7JuQKS/sgqzsm5A=?= X-Global-Sender: =?UTF-8?B?SG9lZ2V1biBLd29uG1RpemVuIFBsYXRmb3JtIExhYi4bU2Ft?= =?UTF-8?B?c3VuZyBFbGVjdHJvbmljcxtTMy9Bc3Npc3RhbnQgRW5naW5lZXI=?= X-Sender-Code: =?UTF-8?B?QzEwG1NUQUYbQzEwVjgxMTE=?= CMS-TYPE: 105P DLP-Filter: Pass X-CFilter-Loop: Reflected X-HopCount: 7 X-CMS-RootMailID: 20170104065900epcas5p2ea5eef389301b71f8f57d6166c233014 X-RootMTR: 20170104065900epcas5p2ea5eef389301b71f8f57d6166c233014 References: <1483513115-3068-1-git-send-email-hoegeun.kwon@samsung.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- .../bindings/display/panel/samsung,s6e3ha2.txt | 40 ++ drivers/gpu/drm/panel/Kconfig | 6 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c | 741 +++++++++++++++++++++ 4 files changed, 788 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt new file mode 100644 index 0000000..6879f51 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt @@ -0,0 +1,40 @@ +Samsung S6E3HA2 5.7" 1440x2560 AMOLED panel + +Required properties: + - compatible: "samsung,s6e3ha2" + - reg: the virtual channel number of a DSI peripheral + - vdd3-supply: I/O voltage supply + - vci-supply: voltage supply for analog circuits + - reset-gpios: a GPIO spec for the reset pin (active low) + - enable-gpios: a GPIO spec for the panel enable pin (active high) + - te-gpios: a GPIO spec for the tearing effect synchronization signal + gpio pin (active high) + +The device node can contain one 'port' child node with one child +'endpoint' node, according to the bindings defined in [1]. This +node should describe panel's video bus. + +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt + +Example: + +&dsi { + ... + + panel@0 { + compatible = "samsung,s6e3ha2"; + reg = <0>; + vdd3-supply = <&ldo27_reg>; + vci-supply = <&ldo28_reg>; + reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>; + enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>; + te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; +}; + diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 62aba97..eea2902 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..8c5a1c2 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c @@ -0,0 +1,741 @@ +/* + * 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, 3); +} + +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 = (struct s6e3ha2 *)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 void s6e3ha2_panel_init(struct s6e3ha2 *ctx) +{ + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); + + mipi_dsi_dcs_exit_sleep_mode(dsi); + 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); +} + +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); + + mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ctx->error != 0) + goto err; + + mipi_dsi_dcs_set_display_off(dsi); + if (ctx->error != 0) + goto err; + + msleep(40); + ctx->bl_dev->props.power = FB_BLANK_NORMAL; + + return 0; +err: + return ctx->error; +} + +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; + + s6e3ha2_panel_init(ctx); + + ret = s6e3ha2_clear_error(ctx); + if (ret < 0) { + s6e3ha2_power_off(ctx); + return ret; + } + + ctx->bl_dev->props.power = FB_BLANK_NORMAL; + + return 0; +} + +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); + + /* common setting */ + mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + + 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); + + mipi_dsi_dcs_set_display_on(dsi); + if (ctx->error != 0) + return ctx->error; + + ctx->bl_dev->props.power = FB_BLANK_UNBLANK; + + return 0; +} + +static const struct drm_display_mode default_mode = { + .clock = 14874, + .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 create a new display mode\n"); + 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"); -- 1.9.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hoegeun Kwon Subject: [PATCH v4 2/3] drm/panel: Add support for S6E3HA2 panel driver on TM2 board Date: Wed, 04 Jan 2017 15:58:34 +0900 Message-ID: <1483513115-3068-3-git-send-email-hoegeun.kwon@samsung.com> References: <1483513115-3068-1-git-send-email-hoegeun.kwon@samsung.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-reply-to: <1483513115-3068-1-git-send-email-hoegeun.kwon@samsung.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: robh@kernel.org, thierry.reding@gmail.com, airlied@linux.ie, kgene@kernel.org, krzk@kernel.org, inki.dae@samsung.com Cc: devicetree@vger.kernel.org, linux-samsung-soc@vger.kernel.org, Donghwa Lee , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, jh80.chung@samsung.com, cw00.choi@samsung.com, Hyungwon Hwang , Hoegeun Kwon List-Id: devicetree@vger.kernel.org VGhpcyBwYXRjaCBhZGQgc3VwcG9ydCBmb3IgTUlQSS1EU0kgYmFzZWQgUzZFM0hBMiBBTU9MRUQg cGFuZWwKZHJpdmVyLiBUaGlzIHBhbmVsIGhhcyAxNDQweDI1NjAgcmVzb2x1dGlvbiBpbiA1Ljct aW5jaCBwaHlzaWNhbApwYW5lbCBpbiB0aGUgVE0yIGRldmljZS4KClNpZ25lZC1vZmYtYnk6IERv bmdod2EgTGVlIDxkaDA5LmxlZUBzYW1zdW5nLmNvbT4KU2lnbmVkLW9mZi1ieTogSHl1bmd3b24g SHdhbmcgPGh1bWFuLmh3YW5nQHNhbXN1bmcuY29tPgpTaWduZWQtb2ZmLWJ5OiBIb2VnZXVuIEt3 b24gPGhvZWdldW4ua3dvbkBzYW1zdW5nLmNvbT4KLS0tCiAuLi4vYmluZGluZ3MvZGlzcGxheS9w YW5lbC9zYW1zdW5nLHM2ZTNoYTIudHh0ICAgICB8ICA0MCArKwogZHJpdmVycy9ncHUvZHJtL3Bh bmVsL0tjb25maWcgICAgICAgICAgICAgICAgICAgICAgfCAgIDYgKwogZHJpdmVycy9ncHUvZHJt L3BhbmVsL01ha2VmaWxlICAgICAgICAgICAgICAgICAgICAgfCAgIDEgKwogZHJpdmVycy9ncHUv ZHJtL3BhbmVsL3BhbmVsLXNhbXN1bmctczZlM2hhMi5jICAgICAgfCA3NDEgKysrKysrKysrKysr KysrKysrKysrCiA0IGZpbGVzIGNoYW5nZWQsIDc4OCBpbnNlcnRpb25zKCspCiBjcmVhdGUgbW9k ZSAxMDA2NDQgRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Rpc3BsYXkvcGFuZWwv c2Ftc3VuZyxzNmUzaGEyLnR4dAogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS9w YW5lbC9wYW5lbC1zYW1zdW5nLXM2ZTNoYTIuYwoKZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24v ZGV2aWNldHJlZS9iaW5kaW5ncy9kaXNwbGF5L3BhbmVsL3NhbXN1bmcsczZlM2hhMi50eHQgYi9E b2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvZGlzcGxheS9wYW5lbC9zYW1zdW5nLHM2 ZTNoYTIudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4NzlmNTEKLS0t IC9kZXYvbnVsbAorKysgYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvZGlzcGxh eS9wYW5lbC9zYW1zdW5nLHM2ZTNoYTIudHh0CkBAIC0wLDAgKzEsNDAgQEAKK1NhbXN1bmcgUzZF M0hBMiA1LjciIDE0NDB4MjU2MCBBTU9MRUQgcGFuZWwKKworUmVxdWlyZWQgcHJvcGVydGllczoK KyAgLSBjb21wYXRpYmxlOiAic2Ftc3VuZyxzNmUzaGEyIgorICAtIHJlZzogdGhlIHZpcnR1YWwg Y2hhbm5lbCBudW1iZXIgb2YgYSBEU0kgcGVyaXBoZXJhbAorICAtIHZkZDMtc3VwcGx5OiBJL08g dm9sdGFnZSBzdXBwbHkKKyAgLSB2Y2ktc3VwcGx5OiB2b2x0YWdlIHN1cHBseSBmb3IgYW5hbG9n IGNpcmN1aXRzCisgIC0gcmVzZXQtZ3Bpb3M6IGEgR1BJTyBzcGVjIGZvciB0aGUgcmVzZXQgcGlu IChhY3RpdmUgbG93KQorICAtIGVuYWJsZS1ncGlvczogYSBHUElPIHNwZWMgZm9yIHRoZSBwYW5l bCBlbmFibGUgcGluIChhY3RpdmUgaGlnaCkKKyAgLSB0ZS1ncGlvczogYSBHUElPIHNwZWMgZm9y IHRoZSB0ZWFyaW5nIGVmZmVjdCBzeW5jaHJvbml6YXRpb24gc2lnbmFsCisgICAgZ3BpbyBwaW4g KGFjdGl2ZSBoaWdoKQorCitUaGUgZGV2aWNlIG5vZGUgY2FuIGNvbnRhaW4gb25lICdwb3J0JyBj aGlsZCBub2RlIHdpdGggb25lIGNoaWxkCisnZW5kcG9pbnQnIG5vZGUsIGFjY29yZGluZyB0byB0 aGUgYmluZGluZ3MgZGVmaW5lZCBpbiBbMV0uIFRoaXMKK25vZGUgc2hvdWxkIGRlc2NyaWJlIHBh bmVsJ3MgdmlkZW8gYnVzLgorCitbMV06IERvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5n cy9tZWRpYS92aWRlby1pbnRlcmZhY2VzLnR4dAorCitFeGFtcGxlOgorCismZHNpIHsKKwkuLi4K KworCXBhbmVsQDAgeworCQljb21wYXRpYmxlID0gInNhbXN1bmcsczZlM2hhMiI7CisJCXJlZyA9 IDwwPjsKKwkJdmRkMy1zdXBwbHkgPSA8JmxkbzI3X3JlZz47CisJCXZjaS1zdXBwbHkgPSA8Jmxk bzI4X3JlZz47CisJCXJlc2V0LWdwaW9zID0gPCZncGcwIDAgR1BJT19BQ1RJVkVfTE9XPjsKKwkJ ZW5hYmxlLWdwaW9zID0gPCZncGYxIDUgR1BJT19BQ1RJVkVfSElHSD47CisJCXRlLWdwaW9zID0g PCZncGYxIDMgR1BJT19BQ1RJVkVfSElHSD47CisKKwkJcG9ydCB7CisJCQlwYW5lbF9pbjogZW5k cG9pbnQgeworCQkJCXJlbW90ZS1lbmRwb2ludCA9IDwmZHNpX291dD47CisJCQl9OworCQl9Owor CX07Cit9OworCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcGFuZWwvS2NvbmZpZyBiL2Ry aXZlcnMvZ3B1L2RybS9wYW5lbC9LY29uZmlnCmluZGV4IDYyYWJhOTcuLmVlYTI5MDIgMTAwNjQ0 Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9wYW5lbC9LY29uZmlnCisrKyBiL2RyaXZlcnMvZ3B1L2Ry bS9wYW5lbC9LY29uZmlnCkBAIC01Miw2ICs1MiwxMiBAQCBjb25maWcgRFJNX1BBTkVMX1BBTkFT T05JQ19WVlgxMEYwMzROMDAKIAkgIFdVWEdBICgxOTIweDEyMDApIE5vdmF0ZWsgTlQxMzk3LWJh c2VkIERTSSBwYW5lbCBhcyBmb3VuZCBpbiBzb21lCiAJICBYcGVyaWEgWjIgdGFibGV0cwogCitj b25maWcgRFJNX1BBTkVMX1NBTVNVTkdfUzZFM0hBMgorCXRyaXN0YXRlICJTYW1zdW5nIFM2RTNI QTIgRFNJIHZpZGVvIG1vZGUgcGFuZWwiCisJZGVwZW5kcyBvbiBPRgorCWRlcGVuZHMgb24gIERS TV9NSVBJX0RTSQorCXNlbGVjdCBWSURFT01PREVfSEVMUEVSUworCiBjb25maWcgRFJNX1BBTkVM X1NBTVNVTkdfUzZFOEFBMAogCXRyaXN0YXRlICJTYW1zdW5nIFM2RThBQTAgRFNJIHZpZGVvIG1v ZGUgcGFuZWwiCiAJZGVwZW5kcyBvbiBPRgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3Bh bmVsL01ha2VmaWxlIGIvZHJpdmVycy9ncHUvZHJtL3BhbmVsL01ha2VmaWxlCmluZGV4IGE1Yzdl YzAuLjFkNDgzYjAgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9wYW5lbC9NYWtlZmlsZQor KysgYi9kcml2ZXJzL2dwdS9kcm0vcGFuZWwvTWFrZWZpbGUKQEAgLTMsNiArMyw3IEBAIG9iai0k KENPTkZJR19EUk1fUEFORUxfSkRJX0xUMDcwTUUwNTAwMCkgKz0gcGFuZWwtamRpLWx0MDcwbWUw NTAwMC5vCiBvYmotJChDT05GSUdfRFJNX1BBTkVMX0xHX0xHNDU3MykgKz0gcGFuZWwtbGctbGc0 NTczLm8KIG9iai0kKENPTkZJR19EUk1fUEFORUxfUEFOQVNPTklDX1ZWWDEwRjAzNE4wMCkgKz0g cGFuZWwtcGFuYXNvbmljLXZ2eDEwZjAzNG4wMC5vCiBvYmotJChDT05GSUdfRFJNX1BBTkVMX1NB TVNVTkdfTEQ5MDQwKSArPSBwYW5lbC1zYW1zdW5nLWxkOTA0MC5vCitvYmotJChDT05GSUdfRFJN X1BBTkVMX1NBTVNVTkdfUzZFM0hBMikgKz0gcGFuZWwtc2Ftc3VuZy1zNmUzaGEyLm8KIG9iai0k KENPTkZJR19EUk1fUEFORUxfU0FNU1VOR19TNkU4QUEwKSArPSBwYW5lbC1zYW1zdW5nLXM2ZThh YTAubwogb2JqLSQoQ09ORklHX0RSTV9QQU5FTF9TSEFSUF9MUTEwMVIxU1gwMSkgKz0gcGFuZWwt c2hhcnAtbHExMDFyMXN4MDEubwogb2JqLSQoQ09ORklHX0RSTV9QQU5FTF9TSEFSUF9MUzA0M1Qx TEUwMSkgKz0gcGFuZWwtc2hhcnAtbHMwNDN0MWxlMDEubwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9n cHUvZHJtL3BhbmVsL3BhbmVsLXNhbXN1bmctczZlM2hhMi5jIGIvZHJpdmVycy9ncHUvZHJtL3Bh bmVsL3BhbmVsLXNhbXN1bmctczZlM2hhMi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAw MDAwMDAuLjhjNWExYzIKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJzL2dwdS9kcm0vcGFuZWwv cGFuZWwtc2Ftc3VuZy1zNmUzaGEyLmMKQEAgLTAsMCArMSw3NDEgQEAKKy8qCisgKiBNSVBJLURT SSBiYXNlZCBzNmUzaGEyIEFNT0xFRCA1LjcgaW5jaCBwYW5lbCBkcml2ZXIuCisgKgorICogQ29w eXJpZ2h0IChjKSAyMDE2IFNhbXN1bmcgRWxlY3Ryb25pY3MgQ28uLCBMdGQuCisgKiBEb25naHdh IExlZSA8ZGgwOS5sZWVAc2Ftc3VuZy5jb20+CisgKiBIeXVuZ3dvbiBId2FuZyA8aHVtYW4uaHdh bmdAc2Ftc3VuZy5jb20+CisgKiBIb2VnZXVuIEt3b24gPGhvZWdldW4ua3dvbkBzYW1zdW5nLmNv bT4KKyAqCisgKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3Ry aWJ1dGUgaXQgYW5kL29yIG1vZGlmeQorICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUg R2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMKKyAqIHB1Ymxpc2hlZCBieSB0aGUg RnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLgorICovCisKKyNpbmNsdWRlIDxkcm0vZHJtUC5oPgor I2luY2x1ZGUgPGRybS9kcm1fbWlwaV9kc2kuaD4KKyNpbmNsdWRlIDxkcm0vZHJtX3BhbmVsLmg+ CisjaW5jbHVkZSA8bGludXgvYmFja2xpZ2h0Lmg+CisjaW5jbHVkZSA8bGludXgvZ3Bpby9jb25z dW1lci5oPgorI2luY2x1ZGUgPGxpbnV4L3JlZ3VsYXRvci9jb25zdW1lci5oPgorCisjZGVmaW5l IFM2RTNIQTJfTUlOX0JSSUdIVE5FU1MJCTAKKyNkZWZpbmUgUzZFM0hBMl9NQVhfQlJJR0hUTkVT UwkJMTAwCisjZGVmaW5lIFM2RTNIQTJfREVGQVVMVF9CUklHSFRORVNTCTgwCisKKyNkZWZpbmUg UzZFM0hBMl9OVU1fR0FNTUFfU1RFUFMJCTQ2CisjZGVmaW5lIFM2RTNIQTJfR0FNTUFfQ01EX0NO VAkJMzUKKyNkZWZpbmUgUzZFM0hBMl9WSU5UX1NUQVRVU19NQVgJCTEwCisKK3N0YXRpYyBjb25z dCB1OCBnYW1tYV90YmxbUzZFM0hBMl9OVU1fR0FNTUFfU1RFUFNdW1M2RTNIQTJfR0FNTUFfQ01E X0NOVF0gPSB7CisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg5LCAw eDg3LCAweDg3LCAweDgyLCAweDgzLAorCSAgMHg4NSwgMHg4OCwgMHg4YiwgMHg4YiwgMHg4NCwg MHg4OCwgMHg4MiwgMHg4MiwgMHg4OSwgMHg4NiwgMHg4YywKKwkgIDB4OTQsIDB4ODQsIDB4YjEs IDB4YWYsIDB4OGUsIDB4Y2YsIDB4YWQsIDB4YzksIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg5LCAw eDg3LCAweDg3LCAweDg0LCAweDg0LAorCSAgMHg4NSwgMHg4NywgMHg4YiwgMHg4YSwgMHg4NCwg MHg4OCwgMHg4MiwgMHg4MiwgMHg4OSwgMHg4NiwgMHg4YSwKKwkgIDB4OTMsIDB4ODQsIDB4YjAs IDB4YWUsIDB4OGUsIDB4YzksIDB4YTgsIDB4YzUsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg5LCAw eDg3LCAweDg3LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NiwgMHg4YSwgMHg4YSwgMHg4NCwg MHg4OCwgMHg4MSwgMHg4NCwgMHg4YSwgMHg4OCwgMHg4YSwKKwkgIDB4OTEsIDB4ODQsIDB4YjEs IDB4YWUsIDB4OGIsIDB4ZDUsIDB4YjIsIDB4Y2MsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg5LCAw eDg3LCAweDg3LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NiwgMHg4YSwgMHg4YSwgMHg4NCwg MHg4NywgMHg4MSwgMHg4NCwgMHg4YSwgMHg4NywgMHg4YSwKKwkgIDB4OTEsIDB4ODUsIDB4YWUs IDB4YWMsIDB4OGEsIDB4YzMsIDB4YTMsIDB4YzAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDg1LCAweDg1LAorCSAgMHg4NiwgMHg4NSwgMHg4OCwgMHg4OSwgMHg4NCwg MHg4OSwgMHg4MiwgMHg4NCwgMHg4NywgMHg4NSwgMHg4YiwKKwkgIDB4OTEsIDB4ODgsIDB4YWQs IDB4YWIsIDB4OGEsIDB4YjcsIDB4OWIsIDB4YjYsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg5LCAw eDg3LCAweDg3LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NiwgMHg4OSwgMHg4YSwgMHg4NCwg MHg4OSwgMHg4MywgMHg4MywgMHg4NiwgMHg4NCwgMHg4YiwKKwkgIDB4OTAsIDB4ODQsIDB4YjAs IDB4YWUsIDB4OGIsIDB4Y2UsIDB4YWQsIDB4YzgsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg5LCAw eDg3LCAweDg3LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NywgMHg4OSwgMHg4YSwgMHg4Mywg MHg4NywgMHg4MiwgMHg4NSwgMHg4OCwgMHg4NywgMHg4OSwKKwkgIDB4OGYsIDB4ODQsIDB4YWMs IDB4YWEsIDB4ODksIDB4YjEsIDB4OTgsIDB4YWYsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg5LCAw eDg3LCAweDg3LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NiwgMHg4OCwgMHg4OSwgMHg4NCwg MHg4OCwgMHg4MywgMHg4MiwgMHg4NSwgMHg4NCwgMHg4YywKKwkgIDB4OTEsIDB4ODYsIDB4YWMs IDB4YWEsIDB4ODksIDB4YzIsIDB4YTUsIDB4YmQsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDg0LCAweDg0LAorCSAgMHg4NSwgMHg4NywgMHg4OSwgMHg4YSwgMHg4Mywg MHg4NywgMHg4MiwgMHg4NSwgMHg4OCwgMHg4NywgMHg4OCwKKwkgIDB4OGIsIDB4ODIsIDB4YWQs IDB4YWEsIDB4OGEsIDB4YzIsIDB4YTUsIDB4YmQsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg5LCAw eDg3LCAweDg3LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NiwgMHg4NywgMHg4OSwgMHg4NCwg MHg4OCwgMHg4MywgMHg4MiwgMHg4NSwgMHg4NCwgMHg4YSwKKwkgIDB4OGUsIDB4ODQsIDB4YWUs IDB4YWMsIDB4ODksIDB4ZGEsIDB4YjcsIDB4ZDAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDg0LCAweDg0LAorCSAgMHg4NSwgMHg4NiwgMHg4NywgMHg4OSwgMHg4NCwg MHg4OCwgMHg4MywgMHg4MCwgMHg4MywgMHg4MiwgMHg4YiwKKwkgIDB4OGUsIDB4ODUsIDB4YWMs IDB4YWEsIDB4ODksIDB4YzgsIDB4YWEsIDB4YzEsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDg0LCAweDg0LAorCSAgMHg4NSwgMHg4NiwgMHg4NywgMHg4OSwgMHg4MSwg MHg4NSwgMHg4MSwgMHg4NCwgMHg4NiwgMHg4NCwgMHg4YywKKwkgIDB4OGMsIDB4ODQsIDB4YTks IDB4YTgsIDB4ODcsIDB4YTMsIDB4OTIsIDB4YTEsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDg0LCAweDg0LAorCSAgMHg4NSwgMHg4NiwgMHg4NywgMHg4OSwgMHg4NCwg MHg4NiwgMHg4MywgMHg4MCwgMHg4MywgMHg4MSwgMHg4YywKKwkgIDB4OGQsIDB4ODQsIDB4YWEs IDB4YWEsIDB4ODksIDB4Y2UsIDB4YWYsIDB4YzUsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDg0LCAweDg0LAorCSAgMHg4NSwgMHg4NiwgMHg4NywgMHg4OSwgMHg4MSwg MHg4MywgMHg4MCwgMHg4MywgMHg4NSwgMHg4NSwgMHg4YywKKwkgIDB4OGMsIDB4ODQsIDB4YTgs IDB4YTgsIDB4ODgsIDB4YjUsIDB4OWYsIDB4YjAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDg0LCAweDg0LAorCSAgMHg4NiwgMHg4NiwgMHg4NywgMHg4OCwgMHg4MSwg MHg4MywgMHg4MCwgMHg4MywgMHg4NSwgMHg4NSwgMHg4YywKKwkgIDB4OGIsIDB4ODQsIDB4YWIs IDB4YTgsIDB4ODYsIDB4ZDQsIDB4YjQsIDB4YzksIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDg0LCAweDg0LAorCSAgMHg4NiwgMHg4NiwgMHg4NywgMHg4OCwgMHg4MSwg MHg4MywgMHg4MCwgMHg4NCwgMHg4NCwgMHg4NSwgMHg4YiwKKwkgIDB4OGEsIDB4ODMsIDB4YTYs IDB4YTUsIDB4ODQsIDB4YmIsIDB4YTQsIDB4YjMsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDg0LCAweDg0LAorCSAgMHg4NiwgMHg4NSwgMHg4NiwgMHg4NiwgMHg4Miwg MHg4NSwgMHg4MSwgMHg4MiwgMHg4MywgMHg4NCwgMHg4ZSwKKwkgIDB4OGIsIDB4ODMsIDB4YTQs IDB4YTMsIDB4OGEsIDB4YTEsIDB4OTMsIDB4OWQsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NiwgMHg4NywgMHg4NywgMHg4Miwg MHg4NSwgMHg4MSwgMHg4MiwgMHg4MiwgMHg4NCwgMHg4ZSwKKwkgIDB4OGIsIDB4ODMsIDB4YTQs IDB4YTIsIDB4ODYsIDB4YzEsIDB4YTksIDB4YjcsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NiwgMHg4NywgMHg4NywgMHg4Miwg MHg4NSwgMHg4MSwgMHg4MiwgMHg4MiwgMHg4NCwgMHg4ZCwKKwkgIDB4ODksIDB4ODIsIDB4YTIs IDB4YTEsIDB4ODQsIDB4YTcsIDB4OTgsIDB4YTEsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGI4LCAweDAwLCAweGMzLCAweDAwLCAweGIxLCAweDg4LCAw eDg2LCAweDg3LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NiwgMHg4NywgMHg4NywgMHg4Miwg MHg4NSwgMHg4MSwgMHg4MywgMHg4MywgMHg4NSwgMHg4YywKKwkgIDB4ODcsIDB4N2YsIDB4YTIs IDB4OWQsIDB4ODgsIDB4OGQsIDB4ODgsIDB4OGIsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGJiLCAweDAwLCAweGM1LCAweDAwLCAweGI0LCAweDg3LCAw eDg2LCAweDg2LCAweDg0LCAweDgzLAorCSAgMHg4NiwgMHg4NywgMHg4NywgMHg4NywgMHg4MCwg MHg4MiwgMHg3ZiwgMHg4NiwgMHg4NiwgMHg4OCwgMHg4YSwKKwkgIDB4ODQsIDB4N2UsIDB4OWQs IDB4OWMsIDB4ODIsIDB4OGQsIDB4ODgsIDB4OGIsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGJkLCAweDAwLCAweGM3LCAweDAwLCAweGI3LCAweDg3LCAw eDg1LCAweDg1LCAweDg0LCAweDgzLAorCSAgMHg4NiwgMHg4NiwgMHg4NiwgMHg4OCwgMHg4MSwg MHg4MywgMHg4MCwgMHg4MywgMHg4NCwgMHg4NSwgMHg4YSwKKwkgIDB4ODUsIDB4N2UsIDB4OWMs IDB4OWIsIDB4ODUsIDB4ODAsIDB4ODAsIDB4ODAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGMwLCAweDAwLCAweGNhLCAweDAwLCAweGJiLCAweDg3LCAw eDg2LCAweDg1LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NiwgMHg4NiwgMHg4OCwgMHg4MSwg MHg4MywgMHg4MCwgMHg4NCwgMHg4NSwgMHg4NiwgMHg4OSwKKwkgIDB4ODMsIDB4N2QsIDB4OWMs IDB4OTksIDB4ODcsIDB4N2IsIDB4N2IsIDB4N2MsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGM0LCAweDAwLCAweGNkLCAweDAwLCAweGJlLCAweDg3LCAw eDg2LCAweDg1LCAweDgzLCAweDgzLAorCSAgMHg4NiwgMHg4NSwgMHg4NSwgMHg4NywgMHg4MSwg MHg4MiwgMHg4MCwgMHg4MiwgMHg4MiwgMHg4MywgMHg4YSwKKwkgIDB4ODUsIDB4N2YsIDB4OWYs IDB4OWIsIDB4ODYsIDB4YjQsIDB4YTEsIDB4YWMsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGM3LCAweDAwLCAweGQwLCAweDAwLCAweGMyLCAweDg3LCAw eDg1LCAweDg1LCAweDgzLCAweDgyLAorCSAgMHg4NSwgMHg4NSwgMHg4NSwgMHg4NiwgMHg4Miwg MHg4MywgMHg4MCwgMHg4MiwgMHg4MiwgMHg4NCwgMHg4NywKKwkgIDB4ODYsIDB4ODAsIDB4OWUs IDB4OWEsIDB4ODcsIDB4YTcsIDB4OTgsIDB4YTEsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGNhLCAweDAwLCAweGQyLCAweDAwLCAweGM1LCAweDg3LCAw eDg1LCAweDg0LCAweDgyLCAweDgyLAorCSAgMHg4NCwgMHg4NSwgMHg4NSwgMHg4NiwgMHg4MSwg MHg4MiwgMHg3ZiwgMHg4MiwgMHg4MiwgMHg4NCwgMHg4OCwKKwkgIDB4ODYsIDB4ODEsIDB4OWQs IDB4OTgsIDB4ODYsIDB4OGQsIDB4ODgsIDB4OGIsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGNlLCAweDAwLCAweGQ2LCAweDAwLCAweGNhLCAweDg2LCAw eDg1LCAweDg0LCAweDgzLCAweDgzLAorCSAgMHg4NSwgMHg4NCwgMHg4NCwgMHg4NSwgMHg4MSwg MHg4MiwgMHg4MCwgMHg4MSwgMHg4MSwgMHg4MiwgMHg4OSwKKwkgIDB4ODYsIDB4ODEsIDB4OWMs IDB4OTcsIDB4ODYsIDB4YTcsIDB4OTgsIDB4YTEsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGQxLCAweDAwLCAweGQ5LCAweDAwLCAweGNlLCAweDg2LCAw eDg0LCAweDgzLCAweDgzLCAweDgyLAorCSAgMHg4NSwgMHg4NSwgMHg4NSwgMHg4NiwgMHg4MSwg MHg4MywgMHg4MSwgMHg4MiwgMHg4MiwgMHg4MywgMHg4NiwKKwkgIDB4ODMsIDB4N2YsIDB4OTks IDB4OTUsIDB4ODYsIDB4YmIsIDB4YTQsIDB4YjMsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGQ0LCAweDAwLCAweGRiLCAweDAwLCAweGQxLCAweDg2LCAw eDg1LCAweDgzLCAweDgzLCAweDgyLAorCSAgMHg4NSwgMHg4NCwgMHg4NCwgMHg4NSwgMHg4MCwg MHg4MywgMHg4MiwgMHg4MCwgMHg4MCwgMHg4MSwgMHg4NywKKwkgIDB4ODQsIDB4ODEsIDB4OTgs IDB4OTMsIDB4ODUsIDB4YWUsIDB4OWMsIDB4YTgsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGQ4LCAweDAwLCAweGRlLCAweDAwLCAweGQ2LCAweDg2LCAw eDg0LCAweDgzLCAweDgxLCAweDgxLAorCSAgMHg4MywgMHg4NSwgMHg4NSwgMHg4NSwgMHg4Miwg MHg4MywgMHg4MSwgMHg4MSwgMHg4MSwgMHg4MywgMHg4NiwKKwkgIDB4ODQsIDB4ODAsIDB4OTgs IDB4OTEsIDB4ODUsIDB4N2IsIDB4N2IsIDB4N2MsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGRjLCAweDAwLCAweGUyLCAweDAwLCAweGRhLCAweDg1LCAw eDg0LCAweDgzLCAweDgyLCAweDgyLAorCSAgMHg4NCwgMHg4NCwgMHg4NCwgMHg4NSwgMHg4MSwg MHg4MiwgMHg4MiwgMHg4MCwgMHg4MCwgMHg4MSwgMHg4MywKKwkgIDB4ODIsIDB4N2YsIDB4OTks IDB4OTMsIDB4ODYsIDB4OTQsIDB4OGIsIDB4OTIsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGRmLCAweDAwLCAweGU1LCAweDAwLCAweGRlLCAweDg1LCAw eDg0LCAweDgyLCAweDgyLCAweDgyLAorCSAgMHg4NCwgMHg4MywgMHg4MywgMHg4NCwgMHg4MSwg MHg4MSwgMHg4MCwgMHg4MywgMHg4MiwgMHg4NCwgMHg4MiwKKwkgIDB4ODEsIDB4N2YsIDB4OTks IDB4OTIsIDB4ODYsIDB4N2IsIDB4N2IsIDB4N2MsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGU0LCAweDAwLCAweGU5LCAweDAwLCAweGUzLCAweDg0LCAw eDgzLCAweDgyLCAweDgxLCAweDgxLAorCSAgMHg4MiwgMHg4MywgMHg4MywgMHg4NCwgMHg4MCwg MHg4MSwgMHg4MCwgMHg4MywgMHg4MywgMHg4NCwgMHg4MCwKKwkgIDB4ODEsIDB4N2MsIDB4OTks IDB4OTIsIDB4ODcsIDB4YTEsIDB4OTMsIDB4OWQsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGU0LCAweDAwLCAweGU5LCAweDAwLCAweGUzLCAweDg1LCAw eDg0LCAweDgzLCAweDgxLCAweDgxLAorCSAgMHg4MiwgMHg4MiwgMHg4MiwgMHg4MywgMHg4MCwg MHg4MSwgMHg4MCwgMHg4MSwgMHg4MCwgMHg4MiwgMHg4MywKKwkgIDB4ODIsIDB4ODAsIDB4OTEs IDB4OGQsIDB4ODMsIDB4OWEsIDB4OTAsIDB4OTYsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGU0LCAweDAwLCAweGU5LCAweDAwLCAweGUzLCAweDg0LCAw eDgzLCAweDgyLCAweDgxLCAweDgxLAorCSAgMHg4MiwgMHg4MywgMHg4MywgMHg4NCwgMHg4MCwg MHg4MSwgMHg4MCwgMHg4MSwgMHg4MCwgMHg4MiwgMHg4MywKKwkgIDB4ODEsIDB4N2YsIDB4OTEs IDB4OGMsIDB4ODIsIDB4OGQsIDB4ODgsIDB4OGIsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGU0LCAweDAwLCAweGU5LCAweDAwLCAweGUzLCAweDg0LCAw eDgzLCAweDgyLCAweDgxLCAweDgxLAorCSAgMHg4MiwgMHg4MywgMHg4MywgMHg4MywgMHg4Miwg MHg4MiwgMHg4MSwgMHg4MSwgMHg4MCwgMHg4MiwgMHg4MiwKKwkgIDB4ODIsIDB4N2YsIDB4OTQs IDB4ODksIDB4ODQsIDB4ODAsIDB4ODAsIDB4ODAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGU0LCAweDAwLCAweGU5LCAweDAwLCAweGUzLCAweDg0LCAw eDgzLCAweDgyLCAweDgxLCAweDgxLAorCSAgMHg4MiwgMHg4MywgMHg4MywgMHg4MywgMHg4Miwg MHg4MiwgMHg4MSwgMHg4MSwgMHg4MCwgMHg4MiwgMHg4MywKKwkgIDB4ODIsIDB4N2YsIDB4OTEs IDB4ODUsIDB4ODEsIDB4ODAsIDB4ODAsIDB4ODAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGU0LCAweDAwLCAweGU5LCAweDAwLCAweGUzLCAweDg0LCAw eDgzLCAweDgyLCAweDgxLCAweDgxLAorCSAgMHg4MiwgMHg4MywgMHg4MywgMHg4MywgMHg4MCwg MHg4MCwgMHg3ZiwgMHg4MywgMHg4MiwgMHg4NCwgMHg4MywKKwkgIDB4ODIsIDB4N2YsIDB4OTAs IDB4ODQsIDB4ODEsIDB4OWEsIDB4OTAsIDB4OTYsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGU0LCAweDAwLCAweGU5LCAweDAwLCAweGUzLCAweDg0LCAw eDgzLCAweDgyLCAweDgwLCAweDgwLAorCSAgMHg4MiwgMHg4MywgMHg4MywgMHg4MywgMHg4MCwg MHg4MCwgMHg3ZiwgMHg4MCwgMHg4MCwgMHg4MSwgMHg4MSwKKwkgIDB4ODIsIDB4ODMsIDB4N2Us IDB4ODAsIDB4N2MsIDB4YTQsIDB4OTcsIDB4OWYsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGU5LCAweDAwLCAweGVjLCAweDAwLCAweGU4LCAweDg0LCAw eDgzLCAweDgyLCAweDgxLCAweDgxLAorCSAgMHg4MiwgMHg4MiwgMHg4MiwgMHg4MywgMHg3Ziwg MHg3ZiwgMHg3ZiwgMHg4MSwgMHg4MCwgMHg4MiwgMHg4MywKKwkgIDB4ODMsIDB4ODQsIDB4Nzks IDB4N2MsIDB4NzksIDB4YjEsIDB4YTAsIDB4YWEsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGVkLCAweDAwLCAweGYwLCAweDAwLCAweGVjLCAweDgzLCAw eDgzLCAweDgyLCAweDgwLCAweDgwLAorCSAgMHg4MSwgMHg4MiwgMHg4MiwgMHg4MiwgMHg3Ziwg MHg3ZiwgMHg3ZSwgMHg4MSwgMHg4MSwgMHg4MiwgMHg4MCwKKwkgIDB4ODEsIDB4ODEsIDB4ODQs IDB4ODQsIDB4ODMsIDB4ODAsIDB4ODAsIDB4ODAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGYxLCAweDAwLCAweGY0LCAweDAwLCAweGYxLCAweDgzLCAw eDgyLCAweDgyLCAweDgwLCAweDgwLAorCSAgMHg4MSwgMHg4MiwgMHg4MiwgMHg4MiwgMHg4MCwg MHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MSwgMHg3ZCwKKwkgIDB4N2UsIDB4N2YsIDB4ODQs IDB4ODQsIDB4ODMsIDB4ODAsIDB4ODAsIDB4ODAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGY2LCAweDAwLCAweGY3LCAweDAwLCAweGY1LCAweDgyLCAw eDgyLCAweDgxLCAweDgwLCAweDgwLAorCSAgMHg4MCwgMHg4MiwgMHg4MiwgMHg4MiwgMHg4MCwg MHg4MCwgMHg4MCwgMHg3ZiwgMHg3ZiwgMHg3ZiwgMHg4MiwKKwkgIDB4ODIsIDB4ODIsIDB4ODAs IDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAwLCAweGZhLCAweDAwLCAweGZiLCAweDAwLCAweGZhLCAweDgxLCAw eDgxLCAweDgxLCAweDgwLCAweDgwLAorCSAgMHg4MCwgMHg4MiwgMHg4MiwgMHg4MiwgMHg4MCwg MHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwKKwkgIDB4ODAsIDB4ODAsIDB4ODAs IDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAxLCAweDAwLCAweDAxLCAweDAwLCAweDAxLCAweDAwLCAweDgwLCAw eDgwLCAweDgwLCAweDgwLCAweDgwLAorCSAgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwg MHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwKKwkgIDB4ODAsIDB4ODAsIDB4ODAs IDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0sCisJeyAweDAxLCAweDAwLCAweDAxLCAweDAwLCAweDAxLCAweDAwLCAweDgwLCAw eDgwLCAweDgwLCAweDgwLCAweDgwLAorCSAgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwg MHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwgMHg4MCwKKwkgIDB4ODAsIDB4ODAsIDB4ODAs IDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4ODAsIDB4MDAsIDB4MDAsIDB4MDAsCisJICAweDAw LCAweDAwIH0KK307CisKK3Vuc2lnbmVkIGNoYXIgdmludF90YWJsZVtTNkUzSEEyX1ZJTlRfU1RB VFVTX01BWF0gPSB7CisJMHgxOCwgMHgxOSwgMHgxYSwgMHgxYiwgMHgxYywKKwkweDFkLCAweDFl LCAweDFmLCAweDIwLCAweDIxCit9OworCitzdHJ1Y3QgczZlM2hhMiB7CisJc3RydWN0IGRldmlj ZSAqZGV2OworCXN0cnVjdCBkcm1fcGFuZWwgcGFuZWw7CisJc3RydWN0IGJhY2tsaWdodF9kZXZp Y2UgKmJsX2RldjsKKworCXN0cnVjdCByZWd1bGF0b3JfYnVsa19kYXRhIHN1cHBsaWVzWzJdOwor CXN0cnVjdCBncGlvX2Rlc2MgKnJlc2V0X2dwaW87CisJc3RydWN0IGdwaW9fZGVzYyAqZW5hYmxl X2dwaW87CisKKwkvKiBUaGlzIGZpZWxkIGlzIHRlc3RlZCBieSBmdW5jdGlvbnMgZGlyZWN0bHkg YWNjZXNzaW5nIERTSSBidXMgYmVmb3JlCisJICogdHJhbnNmZXIsIHRyYW5zZmVyIGlzIHNraXBw ZWQgaWYgaXQgaXMgc2V0LiBJbiBjYXNlIG9mIHRyYW5zZmVyCisJICogZmFpbHVyZSBvciB1bmV4 cGVjdGVkIHJlc3BvbnNlIHRoZSBmaWVsZCBpcyBzZXQgdG8gZXJyb3IgdmFsdWUuCisJICogU3Vj aCBjb25zdHJ1Y3QgYWxsb3dzIHRvIGVsaW1pbmF0ZSBtYW55IGNoZWNrcyBpbiBoaWdoZXIgbGV2 ZWwKKwkgKiBmdW5jdGlvbnMuCisJICovCisJaW50IGVycm9yOworfTsKKworc3RhdGljIGludCAg czZlM2hhMl9jbGVhcl9lcnJvcihzdHJ1Y3QgczZlM2hhMiAqY3R4KQoreworCWludCByZXQgPSBj dHgtPmVycm9yOworCisJY3R4LT5lcnJvciA9IDA7CisJcmV0dXJuIHJldDsKK30KKworc3RhdGlj IHZvaWQgczZlM2hhMl9kY3Nfd3JpdGUoc3RydWN0IHM2ZTNoYTIgKmN0eCwgY29uc3Qgdm9pZCAq ZGF0YSwgc2l6ZV90IGxlbikKK3sKKwlzdHJ1Y3QgbWlwaV9kc2lfZGV2aWNlICpkc2kgPSB0b19t aXBpX2RzaV9kZXZpY2UoY3R4LT5kZXYpOworCXNzaXplX3QgcmV0OworCisJaWYgKGN0eC0+ZXJy b3IgPCAwKQorCQlyZXR1cm47CisKKwlyZXQgPSBtaXBpX2RzaV9kY3Nfd3JpdGVfYnVmZmVyKGRz aSwgZGF0YSwgbGVuKTsKKwlpZiAocmV0IDwgMCkgeworCQlkZXZfZXJyKGN0eC0+ZGV2LCAiZXJy b3IgJXpkIHdyaXRpbmcgZGNzIHNlcTogJSpwaFxuIiwKKwkJCQkJCXJldCwgKGludClsZW4sIGRh dGEpOworCQljdHgtPmVycm9yID0gcmV0OworCX0KK30KKworI2RlZmluZSBzNmUzaGEyX2Rjc193 cml0ZV9zZXFfc3RhdGljKGN0eCwgc2VxLi4uKSBkbyB7CVwKKwlzdGF0aWMgY29uc3QgdTggZFtd ID0geyBzZXEgfTsJCQlcCisJczZlM2hhMl9kY3Nfd3JpdGUoY3R4LCBkLCBBUlJBWV9TSVpFKGQp KTsJXAorfSB3aGlsZSAoMCkKKworc3RhdGljIHZvaWQgczZlM2hhMl90ZXN0X2tleV9vbl9mMChz dHJ1Y3QgczZlM2hhMiAqY3R4KQoreworCXM2ZTNoYTJfZGNzX3dyaXRlX3NlcV9zdGF0aWMoY3R4 LCAweGYwLCAweDVhLCAweDVhKTsKK30KKworc3RhdGljIHZvaWQgczZlM2hhMl90ZXN0X2tleV9v ZmZfZjAoc3RydWN0IHM2ZTNoYTIgKmN0eCkKK3sKKwlzNmUzaGEyX2Rjc193cml0ZV9zZXFfc3Rh dGljKGN0eCwgMHhmMCwgMHhhNSwgMHhhNSk7Cit9CisKK3N0YXRpYyB2b2lkIHM2ZTNoYTJfdGVz dF9rZXlfb25fZmMoc3RydWN0IHM2ZTNoYTIgKmN0eCkKK3sKKwlzNmUzaGEyX2Rjc193cml0ZV9z ZXFfc3RhdGljKGN0eCwgMHhmYywgMHg1YSwgMHg1YSk7Cit9CisKK3N0YXRpYyB2b2lkIHM2ZTNo YTJfdGVzdF9rZXlfb2ZmX2ZjKHN0cnVjdCBzNmUzaGEyICpjdHgpCit7CisJczZlM2hhMl9kY3Nf d3JpdGVfc2VxX3N0YXRpYyhjdHgsIDB4ZmMsIDB4YTUsIDB4YTUpOworfQorCitzdGF0aWMgdm9p ZCBzNmUzaGEyX3NpbmdsZV9kc2lfc2V0KHN0cnVjdCBzNmUzaGEyICpjdHgpCit7CisJczZlM2hh Ml9kY3Nfd3JpdGVfc2VxX3N0YXRpYyhjdHgsIDB4ZjIsIDB4NjcpOworCXM2ZTNoYTJfZGNzX3dy aXRlX3NlcV9zdGF0aWMoY3R4LCAweGY5LCAweDA5KTsKK30KKworc3RhdGljIHZvaWQgczZlM2hh Ml9mcmVxX2NhbGlicmF0aW9uKHN0cnVjdCBzNmUzaGEyICpjdHgpCit7CisJczZlM2hhMl9kY3Nf d3JpdGVfc2VxX3N0YXRpYyhjdHgsIDB4ZmQsIDB4MWMpOworCXM2ZTNoYTJfZGNzX3dyaXRlX3Nl cV9zdGF0aWMoY3R4LCAweGZlLCAweDIwLCAweDM5KTsKKwlzNmUzaGEyX2Rjc193cml0ZV9zZXFf c3RhdGljKGN0eCwgMHhmZSwgMHhhMCk7CisJczZlM2hhMl9kY3Nfd3JpdGVfc2VxX3N0YXRpYyhj dHgsIDB4ZmUsIDB4MjApOworCXM2ZTNoYTJfZGNzX3dyaXRlX3NlcV9zdGF0aWMoY3R4LCAweGNl LCAweDAzLCAweDNiLCAweDEyLCAweDYyLAorCQkweDQwLCAweDgwLCAweGMwLCAweDI4LCAweDI4 LCAweDI4LCAweDI4LCAweDM5LCAweGM1KTsKK30KKworc3RhdGljIHZvaWQgczZlM2hhMl9hb3Jf Y29udHJvbChzdHJ1Y3QgczZlM2hhMiAqY3R4KQoreworCXM2ZTNoYTJfZGNzX3dyaXRlX3NlcV9z dGF0aWMoY3R4LCAweGIyLCAweDAzLCAweDEwKTsKK30KKworc3RhdGljIHZvaWQgczZlM2hhMl9j YXBzX2VsdnNzX3NldChzdHJ1Y3QgczZlM2hhMiAqY3R4KQoreworCXM2ZTNoYTJfZGNzX3dyaXRl X3NlcV9zdGF0aWMoY3R4LCAweGI2LCAweDljLCAweDBhKTsKK30KKworc3RhdGljIHZvaWQgczZl M2hhMl9hY2xfb2ZmKHN0cnVjdCBzNmUzaGEyICpjdHgpCit7CisJczZlM2hhMl9kY3Nfd3JpdGVf c2VxX3N0YXRpYyhjdHgsIDB4NTUsIDB4MDApOworfQorCitzdGF0aWMgdm9pZCBzNmUzaGEyX2Fj bF9vZmZfb3ByKHN0cnVjdCBzNmUzaGEyICpjdHgpCit7CisJczZlM2hhMl9kY3Nfd3JpdGVfc2Vx X3N0YXRpYyhjdHgsIDB4YjUsIDB4NDApOworfQorCitzdGF0aWMgdm9pZCBzNmUzaGEyX3Rlc3Rf Z2xvYmFsKHN0cnVjdCBzNmUzaGEyICpjdHgpCit7CisJczZlM2hhMl9kY3Nfd3JpdGVfc2VxX3N0 YXRpYyhjdHgsIDB4YjAsIDB4MDcpOworfQorCitzdGF0aWMgdm9pZCBzNmUzaGEyX3Rlc3Qoc3Ry dWN0IHM2ZTNoYTIgKmN0eCkKK3sKKwlzNmUzaGEyX2Rjc193cml0ZV9zZXFfc3RhdGljKGN0eCwg MHhiOCwgMHgxOSk7Cit9CisKK3N0YXRpYyB2b2lkIHM2ZTNoYTJfdG91Y2hfaHN5bmNfb24xKHN0 cnVjdCBzNmUzaGEyICpjdHgpCit7CisJczZlM2hhMl9kY3Nfd3JpdGVfc2VxX3N0YXRpYyhjdHgs CisJCQkweGJkLCAweDMzLCAweDExLCAweDAyLCAweDE2LCAweDAyLCAweDE2KTsKK30KKworc3Rh dGljIHZvaWQgczZlM2hhMl9wZW50aWxlX2NvbnRyb2woc3RydWN0IHM2ZTNoYTIgKmN0eCkKK3sK KwlzNmUzaGEyX2Rjc193cml0ZV9zZXFfc3RhdGljKGN0eCwgMHhjMCwgMHgwMCwgMHgwMCwgMHhk OCwgMHhkOCk7Cit9CisKK3N0YXRpYyB2b2lkIHM2ZTNoYTJfcG9jX2dsb2JhbChzdHJ1Y3QgczZl M2hhMiAqY3R4KQoreworCXM2ZTNoYTJfZGNzX3dyaXRlX3NlcV9zdGF0aWMoY3R4LCAweGIwLCAw eDIwKTsKK30KKworc3RhdGljIHZvaWQgczZlM2hhMl9wb2Nfc2V0dGluZyhzdHJ1Y3QgczZlM2hh MiAqY3R4KQoreworCXM2ZTNoYTJfZGNzX3dyaXRlX3NlcV9zdGF0aWMoY3R4LCAweGZlLCAweDA4 KTsKK30KKworc3RhdGljIHZvaWQgczZlM2hhMl9wY2Rfc2V0X29mZihzdHJ1Y3QgczZlM2hhMiAq Y3R4KQoreworCXM2ZTNoYTJfZGNzX3dyaXRlX3NlcV9zdGF0aWMoY3R4LCAweGNjLCAweDQwLCAw eDUxKTsKK30KKworc3RhdGljIHZvaWQgczZlM2hhMl9lcnJfZmdfc2V0KHN0cnVjdCBzNmUzaGEy ICpjdHgpCit7CisJczZlM2hhMl9kY3Nfd3JpdGVfc2VxX3N0YXRpYyhjdHgsIDB4ZWQsIDB4NDQp OworfQorCitzdGF0aWMgdm9pZCBzNmUzaGEyX2hibV9vZmYoc3RydWN0IHM2ZTNoYTIgKmN0eCkK K3sKKwlzNmUzaGEyX2Rjc193cml0ZV9zZXFfc3RhdGljKGN0eCwgMHg1MywgMHgwMCk7Cit9CisK K3N0YXRpYyB2b2lkIHM2ZTNoYTJfdGVfc3RhcnRfc2V0dGluZyhzdHJ1Y3QgczZlM2hhMiAqY3R4 KQoreworCXM2ZTNoYTJfZGNzX3dyaXRlX3NlcV9zdGF0aWMoY3R4LCAweGI5LCAweDEwLCAweDA5 LCAweGZmLCAweDAwLCAweDA5KTsKK30KKworc3RhdGljIHZvaWQgczZlM2hhMl9nYW1tYV91cGRh dGUoc3RydWN0IHM2ZTNoYTIgKmN0eCkKK3sKKwlzNmUzaGEyX2Rjc193cml0ZV9zZXFfc3RhdGlj KGN0eCwgMHhmNywgMHgwMyk7CisJbmRlbGF5KDEwMCk7IC8qIG5lZWQgZm9yIDEwMG5zIGRlbGF5 ICovCisJczZlM2hhMl9kY3Nfd3JpdGVfc2VxX3N0YXRpYyhjdHgsIDB4ZjcsIDB4MDApOworfQor CitzdGF0aWMgaW50IHM2ZTNoYTJfZ2V0X2JyaWdodG5lc3Moc3RydWN0IGJhY2tsaWdodF9kZXZp Y2UgKmJsX2RldikKK3sKKwlyZXR1cm4gYmxfZGV2LT5wcm9wcy5icmlnaHRuZXNzOworfQorCitz dGF0aWMgdm9pZCBzNmUzaGEyX3NldF92aW50KHN0cnVjdCBzNmUzaGEyICpjdHgpCit7CisJc3Ry dWN0IGJhY2tsaWdodF9kZXZpY2UgKmJsX2RldiA9IGN0eC0+YmxfZGV2OworCXVuc2lnbmVkIGlu dCBicmlnaHRuZXNzID0gYmxfZGV2LT5wcm9wcy5icmlnaHRuZXNzOworCXVuc2lnbmVkIGNoYXIg ZGF0YVtdID0geyAweGY0LCAweDhiLAorCQkJdmludF90YWJsZVticmlnaHRuZXNzICogKFM2RTNI QTJfVklOVF9TVEFUVVNfTUFYIC0gMSkgLworCQkJUzZFM0hBMl9NQVhfQlJJR0hUTkVTU10gfTsK KworCXM2ZTNoYTJfZGNzX3dyaXRlKGN0eCwgZGF0YSwgMyk7Cit9CisKK3N0YXRpYyB1bnNpZ25l ZCBpbnQgczZlM2hhMl9nZXRfYnJpZ2h0bmVzc19pbmRleCh1bnNpZ25lZCBpbnQgYnJpZ2h0bmVz cykKK3sKKwlyZXR1cm4gKGJyaWdodG5lc3MgKiAoUzZFM0hBMl9OVU1fR0FNTUFfU1RFUFMgLSAx KSkgLworCQlTNkUzSEEyX01BWF9CUklHSFRORVNTOworfQorCitzdGF0aWMgaW50IHM2ZTNoYTJf dXBkYXRlX2dhbW1hKHN0cnVjdCBzNmUzaGEyICpjdHgsIHVuc2lnbmVkIGludCBicmlnaHRuZXNz KQoreworCXN0cnVjdCBiYWNrbGlnaHRfZGV2aWNlICpibF9kZXYgPSBjdHgtPmJsX2RldjsKKwl1 bnNpZ25lZCBpbnQgaW5kZXggPSBzNmUzaGEyX2dldF9icmlnaHRuZXNzX2luZGV4KGJyaWdodG5l c3MpOworCXU4IGRhdGFbUzZFM0hBMl9HQU1NQV9DTURfQ05UICsgMV0gPSB7IDB4Y2EsIH07CisK KwltZW1jcHkoZGF0YSArIDEsIGdhbW1hX3RibCArIGluZGV4LCBTNkUzSEEyX0dBTU1BX0NNRF9D TlQpOworCXM2ZTNoYTJfZGNzX3dyaXRlKGN0eCwgZGF0YSwgQVJSQVlfU0laRShkYXRhKSk7CisK KwlzNmUzaGEyX2dhbW1hX3VwZGF0ZShjdHgpOworCWJsX2Rldi0+cHJvcHMuYnJpZ2h0bmVzcyA9 IGJyaWdodG5lc3M7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBzNmUzaGEyX3NldF9i cmlnaHRuZXNzKHN0cnVjdCBiYWNrbGlnaHRfZGV2aWNlICpibF9kZXYpCit7CisJc3RydWN0IHM2 ZTNoYTIgKmN0eCA9IChzdHJ1Y3QgczZlM2hhMiAqKWJsX2dldF9kYXRhKGJsX2Rldik7CisJdW5z aWduZWQgaW50IGJyaWdodG5lc3MgPSBibF9kZXYtPnByb3BzLmJyaWdodG5lc3M7CisKKwlpZiAo YnJpZ2h0bmVzcyA8IFM2RTNIQTJfTUlOX0JSSUdIVE5FU1MgfHwKKwkJYnJpZ2h0bmVzcyA+IGJs X2Rldi0+cHJvcHMubWF4X2JyaWdodG5lc3MpIHsKKwkJZGV2X2VycihjdHgtPmRldiwgIkludmFs aWQgYnJpZ2h0bmVzczogJXVcbiIsIGJyaWdodG5lc3MpOworCQlyZXR1cm4gLUVJTlZBTDsKKwl9 CisKKwlpZiAoYmxfZGV2LT5wcm9wcy5wb3dlciA+IEZCX0JMQU5LX05PUk1BTCkKKwkJcmV0dXJu IC1FUEVSTTsKKworCXM2ZTNoYTJfdGVzdF9rZXlfb25fZjAoY3R4KTsKKwlzNmUzaGEyX3VwZGF0 ZV9nYW1tYShjdHgsIGJyaWdodG5lc3MpOworCXM2ZTNoYTJfYW9yX2NvbnRyb2woY3R4KTsKKwlz NmUzaGEyX3NldF92aW50KGN0eCk7CisJczZlM2hhMl90ZXN0X2tleV9vZmZfZjAoY3R4KTsKKwor CXJldHVybiBjdHgtPmVycm9yOworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IGJhY2tsaWdodF9v cHMgczZlM2hhMl9ibF9vcHMgPSB7CisJLmdldF9icmlnaHRuZXNzID0gczZlM2hhMl9nZXRfYnJp Z2h0bmVzcywKKwkudXBkYXRlX3N0YXR1cyA9IHM2ZTNoYTJfc2V0X2JyaWdodG5lc3MsCit9Owor CitzdGF0aWMgdm9pZCBzNmUzaGEyX3BhbmVsX2luaXQoc3RydWN0IHM2ZTNoYTIgKmN0eCkKK3sK KwlzdHJ1Y3QgbWlwaV9kc2lfZGV2aWNlICpkc2kgPSB0b19taXBpX2RzaV9kZXZpY2UoY3R4LT5k ZXYpOworCisJbWlwaV9kc2lfZGNzX2V4aXRfc2xlZXBfbW9kZShkc2kpOworCXVzbGVlcF9yYW5n ZSg1MDAwLCA2MDAwKTsKKworCXM2ZTNoYTJfdGVzdF9rZXlfb25fZjAoY3R4KTsKKwlzNmUzaGEy X3NpbmdsZV9kc2lfc2V0KGN0eCk7CisJczZlM2hhMl90ZXN0X2tleV9vbl9mYyhjdHgpOworCXM2 ZTNoYTJfZnJlcV9jYWxpYnJhdGlvbihjdHgpOworCXM2ZTNoYTJfdGVzdF9rZXlfb2ZmX2ZjKGN0 eCk7CisJczZlM2hhMl90ZXN0X2tleV9vZmZfZjAoY3R4KTsKK30KKworc3RhdGljIGludCBzNmUz aGEyX3Bvd2VyX29mZihzdHJ1Y3QgczZlM2hhMiAqY3R4KQoreworCXJldHVybiByZWd1bGF0b3Jf YnVsa19kaXNhYmxlKEFSUkFZX1NJWkUoY3R4LT5zdXBwbGllcyksIGN0eC0+c3VwcGxpZXMpOwor fQorCitzdGF0aWMgaW50IHM2ZTNoYTJfZGlzYWJsZShzdHJ1Y3QgZHJtX3BhbmVsICpwYW5lbCkK K3sKKwlzdHJ1Y3QgczZlM2hhMiAqY3R4ID0gY29udGFpbmVyX29mKHBhbmVsLCBzdHJ1Y3QgczZl M2hhMiwgcGFuZWwpOworCXN0cnVjdCBtaXBpX2RzaV9kZXZpY2UgKmRzaSA9IHRvX21pcGlfZHNp X2RldmljZShjdHgtPmRldik7CisKKwltaXBpX2RzaV9kY3NfZW50ZXJfc2xlZXBfbW9kZShkc2kp OworCWlmIChjdHgtPmVycm9yICE9IDApCisJCWdvdG8gZXJyOworCisJbWlwaV9kc2lfZGNzX3Nl dF9kaXNwbGF5X29mZihkc2kpOworCWlmIChjdHgtPmVycm9yICE9IDApCisJCWdvdG8gZXJyOwor CisJbXNsZWVwKDQwKTsKKwljdHgtPmJsX2Rldi0+cHJvcHMucG93ZXIgPSBGQl9CTEFOS19OT1JN QUw7CisKKwlyZXR1cm4gMDsKK2VycjoKKwlyZXR1cm4gY3R4LT5lcnJvcjsKK30KKworc3RhdGlj IGludCBzNmUzaGEyX3VucHJlcGFyZShzdHJ1Y3QgZHJtX3BhbmVsICpwYW5lbCkKK3sKKwlzdHJ1 Y3QgczZlM2hhMiAqY3R4ID0gY29udGFpbmVyX29mKHBhbmVsLCBzdHJ1Y3QgczZlM2hhMiwgcGFu ZWwpOworCWludCByZXQ7CisKKwlyZXQgPSBzNmUzaGEyX2NsZWFyX2Vycm9yKGN0eCk7CisJaWYg KCFyZXQpCisJCWN0eC0+YmxfZGV2LT5wcm9wcy5wb3dlciA9IEZCX0JMQU5LX1BPV0VSRE9XTjsK KworCXJldHVybiBzNmUzaGEyX3Bvd2VyX29mZihjdHgpOworfQorCitzdGF0aWMgaW50IHM2ZTNo YTJfcG93ZXJfb24oc3RydWN0IHM2ZTNoYTIgKmN0eCkKK3sKKwlpbnQgcmV0OworCisJcmV0ID0g cmVndWxhdG9yX2J1bGtfZW5hYmxlKEFSUkFZX1NJWkUoY3R4LT5zdXBwbGllcyksIGN0eC0+c3Vw cGxpZXMpOworCWlmIChyZXQgPCAwKQorCQlyZXR1cm4gcmV0OworCisJbXNsZWVwKDEyMCk7CisK KwlncGlvZF9zZXRfdmFsdWUoY3R4LT5lbmFibGVfZ3BpbywgMCk7CisJdXNsZWVwX3JhbmdlKDUw MDAsIDYwMDApOworCWdwaW9kX3NldF92YWx1ZShjdHgtPmVuYWJsZV9ncGlvLCAxKTsKKworCWdw aW9kX3NldF92YWx1ZShjdHgtPnJlc2V0X2dwaW8sIDEpOworCXVzbGVlcF9yYW5nZSg1MDAwLCA2 MDAwKTsKKwlncGlvZF9zZXRfdmFsdWUoY3R4LT5yZXNldF9ncGlvLCAwKTsKKwl1c2xlZXBfcmFu Z2UoNTAwMCwgNjAwMCk7CisKKwlyZXR1cm4gMDsKK30KK3N0YXRpYyBpbnQgczZlM2hhMl9wcmVw YXJlKHN0cnVjdCBkcm1fcGFuZWwgKnBhbmVsKQoreworCXN0cnVjdCBzNmUzaGEyICpjdHggPSBj b250YWluZXJfb2YocGFuZWwsIHN0cnVjdCBzNmUzaGEyLCBwYW5lbCk7CisJaW50IHJldDsKKwor CXJldCA9IHM2ZTNoYTJfcG93ZXJfb24oY3R4KTsKKwlpZiAocmV0IDwgMCkKKwkJcmV0dXJuIHJl dDsKKworCXM2ZTNoYTJfcGFuZWxfaW5pdChjdHgpOworCisJcmV0ID0gczZlM2hhMl9jbGVhcl9l cnJvcihjdHgpOworCWlmIChyZXQgPCAwKSB7CisJCXM2ZTNoYTJfcG93ZXJfb2ZmKGN0eCk7CisJ CXJldHVybiByZXQ7CisJfQorCisJY3R4LT5ibF9kZXYtPnByb3BzLnBvd2VyID0gRkJfQkxBTktf Tk9STUFMOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgczZlM2hhMl9lbmFibGUoc3Ry dWN0IGRybV9wYW5lbCAqcGFuZWwpCit7CisJc3RydWN0IHM2ZTNoYTIgKmN0eCA9IGNvbnRhaW5l cl9vZihwYW5lbCwgc3RydWN0IHM2ZTNoYTIsIHBhbmVsKTsKKwlzdHJ1Y3QgbWlwaV9kc2lfZGV2 aWNlICpkc2kgPSB0b19taXBpX2RzaV9kZXZpY2UoY3R4LT5kZXYpOworCisJLyogY29tbW9uIHNl dHRpbmcgKi8KKwltaXBpX2RzaV9kY3Nfc2V0X3RlYXJfb24oZHNpLCBNSVBJX0RTSV9EQ1NfVEVB Ul9NT0RFX1ZCTEFOSyk7CisKKwlzNmUzaGEyX3Rlc3Rfa2V5X29uX2YwKGN0eCk7CisJczZlM2hh Ml90ZXN0X2tleV9vbl9mYyhjdHgpOworCXM2ZTNoYTJfdG91Y2hfaHN5bmNfb24xKGN0eCk7CisJ czZlM2hhMl9wZW50aWxlX2NvbnRyb2woY3R4KTsKKwlzNmUzaGEyX3BvY19nbG9iYWwoY3R4KTsK KwlzNmUzaGEyX3BvY19zZXR0aW5nKGN0eCk7CisJczZlM2hhMl90ZXN0X2tleV9vZmZfZmMoY3R4 KTsKKworCS8qIHBjZCBzZXR0aW5nIG9mZiBmb3IgVEIgKi8KKwlzNmUzaGEyX3BjZF9zZXRfb2Zm KGN0eCk7CisJczZlM2hhMl9lcnJfZmdfc2V0KGN0eCk7CisJczZlM2hhMl90ZV9zdGFydF9zZXR0 aW5nKGN0eCk7CisKKwkvKiBicmlnaHRuZXNzIHNldHRpbmcgKi8KKwlzNmUzaGEyX3NldF9icmln aHRuZXNzKGN0eC0+YmxfZGV2KTsKKwlzNmUzaGEyX2Fvcl9jb250cm9sKGN0eCk7CisJczZlM2hh Ml9jYXBzX2VsdnNzX3NldChjdHgpOworCXM2ZTNoYTJfZ2FtbWFfdXBkYXRlKGN0eCk7CisJczZl M2hhMl9hY2xfb2ZmKGN0eCk7CisJczZlM2hhMl9hY2xfb2ZmX29wcihjdHgpOworCXM2ZTNoYTJf aGJtX29mZihjdHgpOworCisJLyogZWx2c3MgdGVtcCBjb21wZW5zYXRpb24gKi8KKwlzNmUzaGEy X3Rlc3RfZ2xvYmFsKGN0eCk7CisJczZlM2hhMl90ZXN0KGN0eCk7CisJczZlM2hhMl90ZXN0X2tl eV9vZmZfZjAoY3R4KTsKKworCW1pcGlfZHNpX2Rjc19zZXRfZGlzcGxheV9vbihkc2kpOworCWlm IChjdHgtPmVycm9yICE9IDApCisJCXJldHVybiBjdHgtPmVycm9yOworCisJY3R4LT5ibF9kZXYt PnByb3BzLnBvd2VyID0gRkJfQkxBTktfVU5CTEFOSzsKKworCXJldHVybiAwOworfQorCitzdGF0 aWMgY29uc3Qgc3RydWN0IGRybV9kaXNwbGF5X21vZGUgZGVmYXVsdF9tb2RlID0geworCS5jbG9j ayA9IDE0ODc0LAorCS5oZGlzcGxheSA9IDE0NDAsCisJLmhzeW5jX3N0YXJ0ID0gMTQ0MCArIDEs CisJLmhzeW5jX2VuZCA9IDE0NDAgKyAxICsgMSwKKwkuaHRvdGFsID0gMTQ0MCArIDEgKyAxICsg MSwKKwkudmRpc3BsYXkgPSAyNTYwLAorCS52c3luY19zdGFydCA9IDI1NjAgKyAxLAorCS52c3lu Y19lbmQgPSAyNTYwICsgMSArIDEsCisJLnZ0b3RhbCA9IDI1NjAgKyAxICsgMSArIDE1LAorCS52 cmVmcmVzaCA9IDYwLAorCS5mbGFncyA9IDAsCit9OworCitzdGF0aWMgaW50IHM2ZTNoYTJfZ2V0 X21vZGVzKHN0cnVjdCBkcm1fcGFuZWwgKnBhbmVsKQoreworCXN0cnVjdCBkcm1fY29ubmVjdG9y ICpjb25uZWN0b3IgPSBwYW5lbC0+Y29ubmVjdG9yOworCXN0cnVjdCBkcm1fZGlzcGxheV9tb2Rl ICptb2RlOworCisJbW9kZSA9IGRybV9tb2RlX2R1cGxpY2F0ZShwYW5lbC0+ZHJtLCAmZGVmYXVs dF9tb2RlKTsKKwlpZiAoIW1vZGUpIHsKKwkJRFJNX0VSUk9SKCJmYWlsZWQgdG8gY3JlYXRlIGEg bmV3IGRpc3BsYXkgbW9kZVxuIik7CisJCURSTV9FUlJPUigiZmFpbGVkIHRvIGFkZCBtb2RlICV1 eCV1eEAldVxuIiwKKwkJCQlkZWZhdWx0X21vZGUuaGRpc3BsYXksIGRlZmF1bHRfbW9kZS52ZGlz cGxheSwKKwkJCQlkZWZhdWx0X21vZGUudnJlZnJlc2gpOworCQlyZXR1cm4gLUVOT01FTTsKKwl9 CisKKwlkcm1fbW9kZV9zZXRfbmFtZShtb2RlKTsKKworCW1vZGUtPnR5cGUgPSBEUk1fTU9ERV9U WVBFX0RSSVZFUiB8IERSTV9NT0RFX1RZUEVfUFJFRkVSUkVEOworCWRybV9tb2RlX3Byb2JlZF9h ZGQoY29ubmVjdG9yLCBtb2RlKTsKKworCWNvbm5lY3Rvci0+ZGlzcGxheV9pbmZvLndpZHRoX21t ID0gNzE7CisJY29ubmVjdG9yLT5kaXNwbGF5X2luZm8uaGVpZ2h0X21tID0gMTI1OworCisJcmV0 dXJuIDE7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX3BhbmVsX2Z1bmNzIHM2ZTNoYTJf ZHJtX2Z1bmNzID0geworCS5kaXNhYmxlID0gczZlM2hhMl9kaXNhYmxlLAorCS51bnByZXBhcmUg PSBzNmUzaGEyX3VucHJlcGFyZSwKKwkucHJlcGFyZSA9IHM2ZTNoYTJfcHJlcGFyZSwKKwkuZW5h YmxlID0gczZlM2hhMl9lbmFibGUsCisJLmdldF9tb2RlcyA9IHM2ZTNoYTJfZ2V0X21vZGVzLAor fTsKKworc3RhdGljIGludCBzNmUzaGEyX3Byb2JlKHN0cnVjdCBtaXBpX2RzaV9kZXZpY2UgKmRz aSkKK3sKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmZHNpLT5kZXY7CisJc3RydWN0IHM2ZTNoYTIg KmN0eDsKKwlpbnQgcmV0OworCisJY3R4ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpjdHgp LCBHRlBfS0VSTkVMKTsKKwlpZiAoIWN0eCkKKwkJcmV0dXJuIC1FTk9NRU07CisKKwltaXBpX2Rz aV9zZXRfZHJ2ZGF0YShkc2ksIGN0eCk7CisKKwljdHgtPmRldiA9IGRldjsKKworCWRzaS0+bGFu ZXMgPSA0OworCWRzaS0+Zm9ybWF0ID0gTUlQSV9EU0lfRk1UX1JHQjg4ODsKKwlkc2ktPm1vZGVf ZmxhZ3MgPSBNSVBJX0RTSV9DTE9DS19OT05fQ09OVElOVU9VUzsKKworCWN0eC0+c3VwcGxpZXNb MF0uc3VwcGx5ID0gInZkZDMiOworCWN0eC0+c3VwcGxpZXNbMV0uc3VwcGx5ID0gInZjaSI7CisK KwlyZXQgPSBkZXZtX3JlZ3VsYXRvcl9idWxrX2dldChkZXYsIEFSUkFZX1NJWkUoY3R4LT5zdXBw bGllcyksCisJCQkJICAgICAgY3R4LT5zdXBwbGllcyk7CisJaWYgKHJldCA8IDApIHsKKwkJZGV2 X2VycihkZXYsICJmYWlsZWQgdG8gZ2V0IHJlZ3VsYXRvcnM6ICVkXG4iLCByZXQpOworCQlyZXR1 cm4gcmV0OworCX0KKworCWN0eC0+cmVzZXRfZ3BpbyA9IGRldm1fZ3Bpb2RfZ2V0KGRldiwgInJl c2V0IiwgR1BJT0RfT1VUX0xPVyk7CisJaWYgKElTX0VSUihjdHgtPnJlc2V0X2dwaW8pKSB7CisJ CWRldl9lcnIoZGV2LCAiY2Fubm90IGdldCByZXNldC1ncGlvcyAlbGRcbiIsCisJCQlQVFJfRVJS KGN0eC0+cmVzZXRfZ3BpbykpOworCQlyZXR1cm4gUFRSX0VSUihjdHgtPnJlc2V0X2dwaW8pOwor CX0KKworCWN0eC0+ZW5hYmxlX2dwaW8gPSBkZXZtX2dwaW9kX2dldChkZXYsICJlbmFibGUiLCBH UElPRF9PVVRfSElHSCk7CisJaWYgKElTX0VSUihjdHgtPmVuYWJsZV9ncGlvKSkgeworCQlkZXZf ZXJyKGRldiwgImNhbm5vdCBnZXQgZW5hYmxlLWdwaW9zICVsZFxuIiwKKwkJCVBUUl9FUlIoY3R4 LT5lbmFibGVfZ3BpbykpOworCQlyZXR1cm4gUFRSX0VSUihjdHgtPmVuYWJsZV9ncGlvKTsKKwl9 CisKKwljdHgtPmJsX2RldiA9IGJhY2tsaWdodF9kZXZpY2VfcmVnaXN0ZXIoInM2ZTNoYTIiLCBk ZXYsIGN0eCwKKwkJCQkJCSZzNmUzaGEyX2JsX29wcywgTlVMTCk7CisJaWYgKElTX0VSUihjdHgt PmJsX2RldikpIHsKKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gcmVnaXN0ZXIgYmFja2xpZ2h0 IGRldmljZVxuIik7CisJCXJldHVybiBQVFJfRVJSKGN0eC0+YmxfZGV2KTsKKwl9CisKKwljdHgt PmJsX2Rldi0+cHJvcHMubWF4X2JyaWdodG5lc3MgPSBTNkUzSEEyX01BWF9CUklHSFRORVNTOwor CWN0eC0+YmxfZGV2LT5wcm9wcy5icmlnaHRuZXNzID0gUzZFM0hBMl9ERUZBVUxUX0JSSUdIVE5F U1M7CisJY3R4LT5ibF9kZXYtPnByb3BzLnBvd2VyID0gRkJfQkxBTktfUE9XRVJET1dOOworCisJ ZHJtX3BhbmVsX2luaXQoJmN0eC0+cGFuZWwpOworCWN0eC0+cGFuZWwuZGV2ID0gZGV2OworCWN0 eC0+cGFuZWwuZnVuY3MgPSAmczZlM2hhMl9kcm1fZnVuY3M7CisKKwlyZXQgPSBkcm1fcGFuZWxf YWRkKCZjdHgtPnBhbmVsKTsKKwlpZiAocmV0IDwgMCkKKwkJZ290byB1bnJlZ2lzdGVyX2JhY2ts aWdodDsKKworCXJldCA9IG1pcGlfZHNpX2F0dGFjaChkc2kpOworCWlmIChyZXQgPCAwKQorCQln b3RvIHJlbW92ZV9wYW5lbDsKKworCXJldHVybiByZXQ7CisKK3JlbW92ZV9wYW5lbDoKKwlkcm1f cGFuZWxfcmVtb3ZlKCZjdHgtPnBhbmVsKTsKKwordW5yZWdpc3Rlcl9iYWNrbGlnaHQ6CisJYmFj a2xpZ2h0X2RldmljZV91bnJlZ2lzdGVyKGN0eC0+YmxfZGV2KTsKKworCXJldHVybiByZXQ7Cit9 CisKK3N0YXRpYyBpbnQgczZlM2hhMl9yZW1vdmUoc3RydWN0IG1pcGlfZHNpX2RldmljZSAqZHNp KQoreworCXN0cnVjdCBzNmUzaGEyICpjdHggPSBtaXBpX2RzaV9nZXRfZHJ2ZGF0YShkc2kpOwor CisJbWlwaV9kc2lfZGV0YWNoKGRzaSk7CisJZHJtX3BhbmVsX3JlbW92ZSgmY3R4LT5wYW5lbCk7 CisJYmFja2xpZ2h0X2RldmljZV91bnJlZ2lzdGVyKGN0eC0+YmxfZGV2KTsKKworCXJldHVybiAw OworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBzNmUzaGEyX29mX21hdGNo W10gPSB7CisJeyAuY29tcGF0aWJsZSA9ICJzYW1zdW5nLHM2ZTNoYTIiIH0sCisJeyB9Cit9Owor TU9EVUxFX0RFVklDRV9UQUJMRShvZiwgczZlM2hhMl9vZl9tYXRjaCk7CisKK3N0YXRpYyBzdHJ1 Y3QgbWlwaV9kc2lfZHJpdmVyIHM2ZTNoYTJfZHJpdmVyID0geworCS5wcm9iZSA9IHM2ZTNoYTJf cHJvYmUsCisJLnJlbW92ZSA9IHM2ZTNoYTJfcmVtb3ZlLAorCS5kcml2ZXIgPSB7CisJCS5uYW1l ID0gInBhbmVsLXNhbXN1bmctczZlM2hhMiIsCisJCS5vZl9tYXRjaF90YWJsZSA9IHM2ZTNoYTJf b2ZfbWF0Y2gsCisJfSwKK307Cittb2R1bGVfbWlwaV9kc2lfZHJpdmVyKHM2ZTNoYTJfZHJpdmVy KTsKKworTU9EVUxFX0FVVEhPUigiRG9uZ2h3YSBMZWUgPGRoMDkubGVlQHNhbXN1bmcuY29tPiIp OworTU9EVUxFX0FVVEhPUigiSHl1bmd3b24gSHdhbmcgPGh1bWFuLmh3YW5nQHNhbXN1bmcuY29t PiIpOworTU9EVUxFX0FVVEhPUigiSG9lZ2V1biBLd29uIDxob2VnZXVuLmt3b25Ac2Ftc3VuZy5j b20+Iik7CitNT0RVTEVfREVTQ1JJUFRJT04oIk1JUEktRFNJIGJhc2VkIHM2ZTNoYTIgQU1PTEVE IFBhbmVsIERyaXZlciIpOworTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwotLSAKMS45LjEKCl9f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBt YWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3Rz LmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=