1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
29ef7e25fSThierry Reding /*
39ef7e25fSThierry Reding  * MIPI-DSI based s6e8aa0 AMOLED LCD 5.3 inch panel driver.
49ef7e25fSThierry Reding  *
59ef7e25fSThierry Reding  * Copyright (c) 2013 Samsung Electronics Co., Ltd
69ef7e25fSThierry Reding  *
79ef7e25fSThierry Reding  * Inki Dae, <inki.dae@samsung.com>
89ef7e25fSThierry Reding  * Donghwa Lee, <dh09.lee@samsung.com>
99ef7e25fSThierry Reding  * Joongmock Shin <jmock.shin@samsung.com>
109ef7e25fSThierry Reding  * Eunchul Kim <chulspro.kim@samsung.com>
119ef7e25fSThierry Reding  * Tomasz Figa <t.figa@samsung.com>
129ef7e25fSThierry Reding  * Andrzej Hajda <a.hajda@samsung.com>
139ef7e25fSThierry Reding */
149ef7e25fSThierry Reding 
15cb23eae3SSam Ravnborg #include <linux/delay.h>
169ef7e25fSThierry Reding #include <linux/gpio/consumer.h>
17cb23eae3SSam Ravnborg #include <linux/module.h>
18cb23eae3SSam Ravnborg #include <linux/of.h>
199ef7e25fSThierry Reding #include <linux/regulator/consumer.h>
209ef7e25fSThierry Reding 
219ef7e25fSThierry Reding #include <video/mipi_display.h>
229ef7e25fSThierry Reding #include <video/of_videomode.h>
239ef7e25fSThierry Reding #include <video/videomode.h>
249ef7e25fSThierry Reding 
25cb23eae3SSam Ravnborg #include <drm/drm_mipi_dsi.h>
26cb23eae3SSam Ravnborg #include <drm/drm_modes.h>
27cb23eae3SSam Ravnborg #include <drm/drm_panel.h>
28cb23eae3SSam Ravnborg 
299ef7e25fSThierry Reding #define LDI_MTP_LENGTH			24
309ef7e25fSThierry Reding #define GAMMA_LEVEL_NUM			25
319ef7e25fSThierry Reding #define GAMMA_TABLE_LEN			26
329ef7e25fSThierry Reding 
339ef7e25fSThierry Reding #define PANELCTL_SS_MASK		(1 << 5)
349ef7e25fSThierry Reding #define PANELCTL_SS_1_800		(0 << 5)
359ef7e25fSThierry Reding #define PANELCTL_SS_800_1		(1 << 5)
369ef7e25fSThierry Reding #define PANELCTL_GTCON_MASK		(7 << 2)
379ef7e25fSThierry Reding #define PANELCTL_GTCON_110		(6 << 2)
389ef7e25fSThierry Reding #define PANELCTL_GTCON_111		(7 << 2)
399ef7e25fSThierry Reding 
409ef7e25fSThierry Reding #define PANELCTL_CLK1_CON_MASK		(7 << 3)
419ef7e25fSThierry Reding #define PANELCTL_CLK1_000		(0 << 3)
429ef7e25fSThierry Reding #define PANELCTL_CLK1_001		(1 << 3)
439ef7e25fSThierry Reding #define PANELCTL_CLK2_CON_MASK		(7 << 0)
449ef7e25fSThierry Reding #define PANELCTL_CLK2_000		(0 << 0)
459ef7e25fSThierry Reding #define PANELCTL_CLK2_001		(1 << 0)
469ef7e25fSThierry Reding 
479ef7e25fSThierry Reding #define PANELCTL_INT1_CON_MASK		(7 << 3)
489ef7e25fSThierry Reding #define PANELCTL_INT1_000		(0 << 3)
499ef7e25fSThierry Reding #define PANELCTL_INT1_001		(1 << 3)
509ef7e25fSThierry Reding #define PANELCTL_INT2_CON_MASK		(7 << 0)
519ef7e25fSThierry Reding #define PANELCTL_INT2_000		(0 << 0)
529ef7e25fSThierry Reding #define PANELCTL_INT2_001		(1 << 0)
539ef7e25fSThierry Reding 
549ef7e25fSThierry Reding #define PANELCTL_BICTL_CON_MASK		(7 << 3)
559ef7e25fSThierry Reding #define PANELCTL_BICTL_000		(0 << 3)
569ef7e25fSThierry Reding #define PANELCTL_BICTL_001		(1 << 3)
579ef7e25fSThierry Reding #define PANELCTL_BICTLB_CON_MASK	(7 << 0)
589ef7e25fSThierry Reding #define PANELCTL_BICTLB_000		(0 << 0)
599ef7e25fSThierry Reding #define PANELCTL_BICTLB_001		(1 << 0)
609ef7e25fSThierry Reding 
619ef7e25fSThierry Reding #define PANELCTL_EM_CLK1_CON_MASK	(7 << 3)
629ef7e25fSThierry Reding #define PANELCTL_EM_CLK1_110		(6 << 3)
639ef7e25fSThierry Reding #define PANELCTL_EM_CLK1_111		(7 << 3)
649ef7e25fSThierry Reding #define PANELCTL_EM_CLK1B_CON_MASK	(7 << 0)
659ef7e25fSThierry Reding #define PANELCTL_EM_CLK1B_110		(6 << 0)
669ef7e25fSThierry Reding #define PANELCTL_EM_CLK1B_111		(7 << 0)
679ef7e25fSThierry Reding 
689ef7e25fSThierry Reding #define PANELCTL_EM_CLK2_CON_MASK	(7 << 3)
699ef7e25fSThierry Reding #define PANELCTL_EM_CLK2_110		(6 << 3)
709ef7e25fSThierry Reding #define PANELCTL_EM_CLK2_111		(7 << 3)
719ef7e25fSThierry Reding #define PANELCTL_EM_CLK2B_CON_MASK	(7 << 0)
729ef7e25fSThierry Reding #define PANELCTL_EM_CLK2B_110		(6 << 0)
739ef7e25fSThierry Reding #define PANELCTL_EM_CLK2B_111		(7 << 0)
749ef7e25fSThierry Reding 
759ef7e25fSThierry Reding #define PANELCTL_EM_INT1_CON_MASK	(7 << 3)
769ef7e25fSThierry Reding #define PANELCTL_EM_INT1_000		(0 << 3)
779ef7e25fSThierry Reding #define PANELCTL_EM_INT1_001		(1 << 3)
789ef7e25fSThierry Reding #define PANELCTL_EM_INT2_CON_MASK	(7 << 0)
799ef7e25fSThierry Reding #define PANELCTL_EM_INT2_000		(0 << 0)
809ef7e25fSThierry Reding #define PANELCTL_EM_INT2_001		(1 << 0)
819ef7e25fSThierry Reding 
829ef7e25fSThierry Reding #define AID_DISABLE			(0x4)
839ef7e25fSThierry Reding #define AID_1				(0x5)
849ef7e25fSThierry Reding #define AID_2				(0x6)
859ef7e25fSThierry Reding #define AID_3				(0x7)
869ef7e25fSThierry Reding 
879ef7e25fSThierry Reding typedef u8 s6e8aa0_gamma_table[GAMMA_TABLE_LEN];
889ef7e25fSThierry Reding 
899ef7e25fSThierry Reding struct s6e8aa0_variant {
909ef7e25fSThierry Reding 	u8 version;
919ef7e25fSThierry Reding 	const s6e8aa0_gamma_table *gamma_tables;
929ef7e25fSThierry Reding };
939ef7e25fSThierry Reding 
949ef7e25fSThierry Reding struct s6e8aa0 {
959ef7e25fSThierry Reding 	struct device *dev;
969ef7e25fSThierry Reding 	struct drm_panel panel;
979ef7e25fSThierry Reding 
989ef7e25fSThierry Reding 	struct regulator_bulk_data supplies[2];
999ef7e25fSThierry Reding 	struct gpio_desc *reset_gpio;
1009ef7e25fSThierry Reding 	u32 power_on_delay;
1019ef7e25fSThierry Reding 	u32 reset_delay;
1029ef7e25fSThierry Reding 	u32 init_delay;
1039ef7e25fSThierry Reding 	bool flip_horizontal;
1049ef7e25fSThierry Reding 	bool flip_vertical;
1059ef7e25fSThierry Reding 	struct videomode vm;
1069ef7e25fSThierry Reding 	u32 width_mm;
1079ef7e25fSThierry Reding 	u32 height_mm;
1089ef7e25fSThierry Reding 
1099ef7e25fSThierry Reding 	u8 version;
1109ef7e25fSThierry Reding 	u8 id;
1119ef7e25fSThierry Reding 	const struct s6e8aa0_variant *variant;
1129ef7e25fSThierry Reding 	int brightness;
1139ef7e25fSThierry Reding 
1149ef7e25fSThierry Reding 	/* This field is tested by functions directly accessing DSI bus before
1159ef7e25fSThierry Reding 	 * transfer, transfer is skipped if it is set. In case of transfer
1169ef7e25fSThierry Reding 	 * failure or unexpected response the field is set to error value.
1179ef7e25fSThierry Reding 	 * Such construct allows to eliminate many checks in higher level
1189ef7e25fSThierry Reding 	 * functions.
1199ef7e25fSThierry Reding 	 */
1209ef7e25fSThierry Reding 	int error;
1219ef7e25fSThierry Reding };
1229ef7e25fSThierry Reding 
panel_to_s6e8aa0(struct drm_panel * panel)1239ef7e25fSThierry Reding static inline struct s6e8aa0 *panel_to_s6e8aa0(struct drm_panel *panel)
1249ef7e25fSThierry Reding {
1259ef7e25fSThierry Reding 	return container_of(panel, struct s6e8aa0, panel);
1269ef7e25fSThierry Reding }
1279ef7e25fSThierry Reding 
s6e8aa0_clear_error(struct s6e8aa0 * ctx)1289ef7e25fSThierry Reding static int s6e8aa0_clear_error(struct s6e8aa0 *ctx)
1299ef7e25fSThierry Reding {
1309ef7e25fSThierry Reding 	int ret = ctx->error;
1319ef7e25fSThierry Reding 
1329ef7e25fSThierry Reding 	ctx->error = 0;
1339ef7e25fSThierry Reding 	return ret;
1349ef7e25fSThierry Reding }
1359ef7e25fSThierry Reding 
s6e8aa0_dcs_write(struct s6e8aa0 * ctx,const void * data,size_t len)1369ef7e25fSThierry Reding static void s6e8aa0_dcs_write(struct s6e8aa0 *ctx, const void *data, size_t len)
1379ef7e25fSThierry Reding {
1389ef7e25fSThierry Reding 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
1399ef7e25fSThierry Reding 	ssize_t ret;
1409ef7e25fSThierry Reding 
1419ef7e25fSThierry Reding 	if (ctx->error < 0)
1429ef7e25fSThierry Reding 		return;
1439ef7e25fSThierry Reding 
1449ef7e25fSThierry Reding 	ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
1459ef7e25fSThierry Reding 	if (ret < 0) {
1469ef7e25fSThierry Reding 		dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret,
1479ef7e25fSThierry Reding 			(int)len, data);
1489ef7e25fSThierry Reding 		ctx->error = ret;
1499ef7e25fSThierry Reding 	}
1509ef7e25fSThierry Reding }
1519ef7e25fSThierry Reding 
s6e8aa0_dcs_read(struct s6e8aa0 * ctx,u8 cmd,void * data,size_t len)1529ef7e25fSThierry Reding static int s6e8aa0_dcs_read(struct s6e8aa0 *ctx, u8 cmd, void *data, size_t len)
1539ef7e25fSThierry Reding {
1549ef7e25fSThierry Reding 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
1559ef7e25fSThierry Reding 	int ret;
1569ef7e25fSThierry Reding 
1579ef7e25fSThierry Reding 	if (ctx->error < 0)
1589ef7e25fSThierry Reding 		return ctx->error;
1599ef7e25fSThierry Reding 
1609ef7e25fSThierry Reding 	ret = mipi_dsi_dcs_read(dsi, cmd, data, len);
1619ef7e25fSThierry Reding 	if (ret < 0) {
1629ef7e25fSThierry Reding 		dev_err(ctx->dev, "error %d reading dcs seq(%#x)\n", ret, cmd);
1639ef7e25fSThierry Reding 		ctx->error = ret;
1649ef7e25fSThierry Reding 	}
1659ef7e25fSThierry Reding 
1669ef7e25fSThierry Reding 	return ret;
1679ef7e25fSThierry Reding }
1689ef7e25fSThierry Reding 
1699ef7e25fSThierry Reding #define s6e8aa0_dcs_write_seq(ctx, seq...) \
1709ef7e25fSThierry Reding ({\
1719ef7e25fSThierry Reding 	const u8 d[] = { seq };\
1729ef7e25fSThierry Reding 	BUILD_BUG_ON_MSG(ARRAY_SIZE(d) > 64, "DCS sequence too big for stack");\
1739ef7e25fSThierry Reding 	s6e8aa0_dcs_write(ctx, d, ARRAY_SIZE(d));\
1749ef7e25fSThierry Reding })
1759ef7e25fSThierry Reding 
1769ef7e25fSThierry Reding #define s6e8aa0_dcs_write_seq_static(ctx, seq...) \
1779ef7e25fSThierry Reding ({\
1789ef7e25fSThierry Reding 	static const u8 d[] = { seq };\
1799ef7e25fSThierry Reding 	s6e8aa0_dcs_write(ctx, d, ARRAY_SIZE(d));\
1809ef7e25fSThierry Reding })
1819ef7e25fSThierry Reding 
s6e8aa0_apply_level_1_key(struct s6e8aa0 * ctx)1829ef7e25fSThierry Reding static void s6e8aa0_apply_level_1_key(struct s6e8aa0 *ctx)
1839ef7e25fSThierry Reding {
1849ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq_static(ctx, 0xf0, 0x5a, 0x5a);
1859ef7e25fSThierry Reding }
1869ef7e25fSThierry Reding 
s6e8aa0_panel_cond_set_v142(struct s6e8aa0 * ctx)1879ef7e25fSThierry Reding static void s6e8aa0_panel_cond_set_v142(struct s6e8aa0 *ctx)
1889ef7e25fSThierry Reding {
1899ef7e25fSThierry Reding 	static const u8 aids[] = {
1909ef7e25fSThierry Reding 		0x04, 0x04, 0x04, 0x04, 0x04, 0x60, 0x80, 0xA0
1919ef7e25fSThierry Reding 	};
1929ef7e25fSThierry Reding 	u8 aid = aids[ctx->id >> 5];
1939ef7e25fSThierry Reding 	u8 cfg = 0x3d;
1949ef7e25fSThierry Reding 	u8 clk_con = 0xc8;
1959ef7e25fSThierry Reding 	u8 int_con = 0x08;
1969ef7e25fSThierry Reding 	u8 bictl_con = 0x48;
1979ef7e25fSThierry Reding 	u8 em_clk1_con = 0xff;
1989ef7e25fSThierry Reding 	u8 em_clk2_con = 0xff;
1999ef7e25fSThierry Reding 	u8 em_int_con = 0xc8;
2009ef7e25fSThierry Reding 
2019ef7e25fSThierry Reding 	if (ctx->flip_vertical) {
2029ef7e25fSThierry Reding 		/* GTCON */
2039ef7e25fSThierry Reding 		cfg &= ~(PANELCTL_GTCON_MASK);
2049ef7e25fSThierry Reding 		cfg |= (PANELCTL_GTCON_110);
2059ef7e25fSThierry Reding 	}
2069ef7e25fSThierry Reding 
2079ef7e25fSThierry Reding 	if (ctx->flip_horizontal) {
2089ef7e25fSThierry Reding 		/* SS */
2099ef7e25fSThierry Reding 		cfg &= ~(PANELCTL_SS_MASK);
2109ef7e25fSThierry Reding 		cfg |= (PANELCTL_SS_1_800);
2119ef7e25fSThierry Reding 	}
2129ef7e25fSThierry Reding 
2139ef7e25fSThierry Reding 	if (ctx->flip_horizontal || ctx->flip_vertical) {
2149ef7e25fSThierry Reding 		/* CLK1,2_CON */
2159ef7e25fSThierry Reding 		clk_con &= ~(PANELCTL_CLK1_CON_MASK |
2169ef7e25fSThierry Reding 			PANELCTL_CLK2_CON_MASK);
2179ef7e25fSThierry Reding 		clk_con |= (PANELCTL_CLK1_000 | PANELCTL_CLK2_001);
2189ef7e25fSThierry Reding 
2199ef7e25fSThierry Reding 		/* INT1,2_CON */
2209ef7e25fSThierry Reding 		int_con &= ~(PANELCTL_INT1_CON_MASK |
2219ef7e25fSThierry Reding 			PANELCTL_INT2_CON_MASK);
2229ef7e25fSThierry Reding 		int_con |= (PANELCTL_INT1_000 | PANELCTL_INT2_001);
2239ef7e25fSThierry Reding 
2249ef7e25fSThierry Reding 		/* BICTL,B_CON */
2259ef7e25fSThierry Reding 		bictl_con &= ~(PANELCTL_BICTL_CON_MASK |
2269ef7e25fSThierry Reding 			PANELCTL_BICTLB_CON_MASK);
2279ef7e25fSThierry Reding 		bictl_con |= (PANELCTL_BICTL_000 |
2289ef7e25fSThierry Reding 			PANELCTL_BICTLB_001);
2299ef7e25fSThierry Reding 
2309ef7e25fSThierry Reding 		/* EM_CLK1,1B_CON */
2319ef7e25fSThierry Reding 		em_clk1_con &= ~(PANELCTL_EM_CLK1_CON_MASK |
2329ef7e25fSThierry Reding 			PANELCTL_EM_CLK1B_CON_MASK);
2339ef7e25fSThierry Reding 		em_clk1_con |= (PANELCTL_EM_CLK1_110 |
2349ef7e25fSThierry Reding 			PANELCTL_EM_CLK1B_110);
2359ef7e25fSThierry Reding 
2369ef7e25fSThierry Reding 		/* EM_CLK2,2B_CON */
2379ef7e25fSThierry Reding 		em_clk2_con &= ~(PANELCTL_EM_CLK2_CON_MASK |
2389ef7e25fSThierry Reding 			PANELCTL_EM_CLK2B_CON_MASK);
2399ef7e25fSThierry Reding 		em_clk2_con |= (PANELCTL_EM_CLK2_110 |
2409ef7e25fSThierry Reding 			PANELCTL_EM_CLK2B_110);
2419ef7e25fSThierry Reding 
2429ef7e25fSThierry Reding 		/* EM_INT1,2_CON */
2439ef7e25fSThierry Reding 		em_int_con &= ~(PANELCTL_EM_INT1_CON_MASK |
2449ef7e25fSThierry Reding 			PANELCTL_EM_INT2_CON_MASK);
2459ef7e25fSThierry Reding 		em_int_con |= (PANELCTL_EM_INT1_000 |
2469ef7e25fSThierry Reding 			PANELCTL_EM_INT2_001);
2479ef7e25fSThierry Reding 	}
2489ef7e25fSThierry Reding 
2499ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq(ctx,
2509ef7e25fSThierry Reding 		0xf8, cfg, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00,
2519ef7e25fSThierry Reding 		0x3c, 0x78, 0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00,
2529ef7e25fSThierry Reding 		0x00, 0x20, aid, 0x08, 0x6e, 0x00, 0x00, 0x00,
2539ef7e25fSThierry Reding 		0x02, 0x07, 0x07, 0x23, 0x23, 0xc0, clk_con, int_con,
2549ef7e25fSThierry Reding 		bictl_con, 0xc1, 0x00, 0xc1, em_clk1_con, em_clk2_con,
2559ef7e25fSThierry Reding 		em_int_con);
2569ef7e25fSThierry Reding }
2579ef7e25fSThierry Reding 
s6e8aa0_panel_cond_set(struct s6e8aa0 * ctx)2589ef7e25fSThierry Reding static void s6e8aa0_panel_cond_set(struct s6e8aa0 *ctx)
2599ef7e25fSThierry Reding {
2609ef7e25fSThierry Reding 	if (ctx->version < 142)
2619ef7e25fSThierry Reding 		s6e8aa0_dcs_write_seq_static(ctx,
2629ef7e25fSThierry Reding 			0xf8, 0x19, 0x35, 0x00, 0x00, 0x00, 0x94, 0x00,
2639ef7e25fSThierry Reding 			0x3c, 0x78, 0x10, 0x27, 0x08, 0x6e, 0x00, 0x00,
2649ef7e25fSThierry Reding 			0x00, 0x00, 0x04, 0x08, 0x6e, 0x00, 0x00, 0x00,
2659ef7e25fSThierry Reding 			0x00, 0x07, 0x07, 0x23, 0x6e, 0xc0, 0xc1, 0x01,
2669ef7e25fSThierry Reding 			0x81, 0xc1, 0x00, 0xc3, 0xf6, 0xf6, 0xc1
2679ef7e25fSThierry Reding 		);
2689ef7e25fSThierry Reding 	else
2699ef7e25fSThierry Reding 		s6e8aa0_panel_cond_set_v142(ctx);
2709ef7e25fSThierry Reding }
2719ef7e25fSThierry Reding 
s6e8aa0_display_condition_set(struct s6e8aa0 * ctx)2729ef7e25fSThierry Reding static void s6e8aa0_display_condition_set(struct s6e8aa0 *ctx)
2739ef7e25fSThierry Reding {
2749ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq_static(ctx, 0xf2, 0x80, 0x03, 0x0d);
2759ef7e25fSThierry Reding }
2769ef7e25fSThierry Reding 
s6e8aa0_etc_source_control(struct s6e8aa0 * ctx)2779ef7e25fSThierry Reding static void s6e8aa0_etc_source_control(struct s6e8aa0 *ctx)
2789ef7e25fSThierry Reding {
2799ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq_static(ctx, 0xf6, 0x00, 0x02, 0x00);
2809ef7e25fSThierry Reding }
2819ef7e25fSThierry Reding 
s6e8aa0_etc_pentile_control(struct s6e8aa0 * ctx)2829ef7e25fSThierry Reding static void s6e8aa0_etc_pentile_control(struct s6e8aa0 *ctx)
2839ef7e25fSThierry Reding {
2849ef7e25fSThierry Reding 	static const u8 pent32[] = {
2859ef7e25fSThierry Reding 		0xb6, 0x0c, 0x02, 0x03, 0x32, 0xc0, 0x44, 0x44, 0xc0, 0x00
2869ef7e25fSThierry Reding 	};
2879ef7e25fSThierry Reding 
2889ef7e25fSThierry Reding 	static const u8 pent142[] = {
2899ef7e25fSThierry Reding 		0xb6, 0x0c, 0x02, 0x03, 0x32, 0xff, 0x44, 0x44, 0xc0, 0x00
2909ef7e25fSThierry Reding 	};
2919ef7e25fSThierry Reding 
2929ef7e25fSThierry Reding 	if (ctx->version < 142)
2939ef7e25fSThierry Reding 		s6e8aa0_dcs_write(ctx, pent32, ARRAY_SIZE(pent32));
2949ef7e25fSThierry Reding 	else
2959ef7e25fSThierry Reding 		s6e8aa0_dcs_write(ctx, pent142, ARRAY_SIZE(pent142));
2969ef7e25fSThierry Reding }
2979ef7e25fSThierry Reding 
s6e8aa0_etc_power_control(struct s6e8aa0 * ctx)2989ef7e25fSThierry Reding static void s6e8aa0_etc_power_control(struct s6e8aa0 *ctx)
2999ef7e25fSThierry Reding {
3009ef7e25fSThierry Reding 	static const u8 pwr142[] = {
3019ef7e25fSThierry Reding 		0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x1e, 0x33, 0x02
3029ef7e25fSThierry Reding 	};
3039ef7e25fSThierry Reding 
3049ef7e25fSThierry Reding 	static const u8 pwr32[] = {
3059ef7e25fSThierry Reding 		0xf4, 0xcf, 0x0a, 0x15, 0x10, 0x19, 0x33, 0x02
3069ef7e25fSThierry Reding 	};
3079ef7e25fSThierry Reding 
3089ef7e25fSThierry Reding 	if (ctx->version < 142)
3099ef7e25fSThierry Reding 		s6e8aa0_dcs_write(ctx, pwr32, ARRAY_SIZE(pwr32));
3109ef7e25fSThierry Reding 	else
3119ef7e25fSThierry Reding 		s6e8aa0_dcs_write(ctx, pwr142, ARRAY_SIZE(pwr142));
3129ef7e25fSThierry Reding }
3139ef7e25fSThierry Reding 
s6e8aa0_etc_elvss_control(struct s6e8aa0 * ctx)3149ef7e25fSThierry Reding static void s6e8aa0_etc_elvss_control(struct s6e8aa0 *ctx)
3159ef7e25fSThierry Reding {
3169ef7e25fSThierry Reding 	u8 id = ctx->id ? 0 : 0x95;
3179ef7e25fSThierry Reding 
3189ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq(ctx, 0xb1, 0x04, id);
3199ef7e25fSThierry Reding }
3209ef7e25fSThierry Reding 
s6e8aa0_elvss_nvm_set_v142(struct s6e8aa0 * ctx)3219ef7e25fSThierry Reding static void s6e8aa0_elvss_nvm_set_v142(struct s6e8aa0 *ctx)
3229ef7e25fSThierry Reding {
3239ef7e25fSThierry Reding 	u8 br;
3249ef7e25fSThierry Reding 
3259ef7e25fSThierry Reding 	switch (ctx->brightness) {
3269ef7e25fSThierry Reding 	case 0 ... 6: /* 30cd ~ 100cd */
3279ef7e25fSThierry Reding 		br = 0xdf;
3289ef7e25fSThierry Reding 		break;
3299ef7e25fSThierry Reding 	case 7 ... 11: /* 120cd ~ 150cd */
3309ef7e25fSThierry Reding 		br = 0xdd;
3319ef7e25fSThierry Reding 		break;
3329ef7e25fSThierry Reding 	case 12 ... 15: /* 180cd ~ 210cd */
3339ef7e25fSThierry Reding 	default:
3349ef7e25fSThierry Reding 		br = 0xd9;
3359ef7e25fSThierry Reding 		break;
3369ef7e25fSThierry Reding 	case 16 ... 24: /* 240cd ~ 300cd */
3379ef7e25fSThierry Reding 		br = 0xd0;
3389ef7e25fSThierry Reding 		break;
3399ef7e25fSThierry Reding 	}
3409ef7e25fSThierry Reding 
3419ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq(ctx, 0xd9, 0x14, 0x40, 0x0c, 0xcb, 0xce, 0x6e,
3429ef7e25fSThierry Reding 		0xc4, 0x0f, 0x40, 0x41, br, 0x00, 0x60, 0x19);
3439ef7e25fSThierry Reding }
3449ef7e25fSThierry Reding 
s6e8aa0_elvss_nvm_set(struct s6e8aa0 * ctx)3459ef7e25fSThierry Reding static void s6e8aa0_elvss_nvm_set(struct s6e8aa0 *ctx)
3469ef7e25fSThierry Reding {
3479ef7e25fSThierry Reding 	if (ctx->version < 142)
3489ef7e25fSThierry Reding 		s6e8aa0_dcs_write_seq_static(ctx,
3499ef7e25fSThierry Reding 			0xd9, 0x14, 0x40, 0x0c, 0xcb, 0xce, 0x6e, 0xc4, 0x07,
3509ef7e25fSThierry Reding 			0x40, 0x41, 0xc1, 0x00, 0x60, 0x19);
3519ef7e25fSThierry Reding 	else
3529ef7e25fSThierry Reding 		s6e8aa0_elvss_nvm_set_v142(ctx);
3539ef7e25fSThierry Reding };
3549ef7e25fSThierry Reding 
s6e8aa0_apply_level_2_key(struct s6e8aa0 * ctx)3559ef7e25fSThierry Reding static void s6e8aa0_apply_level_2_key(struct s6e8aa0 *ctx)
3569ef7e25fSThierry Reding {
3579ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq_static(ctx, 0xfc, 0x5a, 0x5a);
3589ef7e25fSThierry Reding }
3599ef7e25fSThierry Reding 
3609ef7e25fSThierry Reding static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v142[GAMMA_LEVEL_NUM] = {
3619ef7e25fSThierry Reding 	{
3629ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x62, 0x55, 0x55,
3639ef7e25fSThierry Reding 		0xaf, 0xb1, 0xb1, 0xbd, 0xce, 0xb7, 0x9a, 0xb1,
3649ef7e25fSThierry Reding 		0x90, 0xb2, 0xc4, 0xae, 0x00, 0x60, 0x00, 0x40,
3659ef7e25fSThierry Reding 		0x00, 0x70,
3669ef7e25fSThierry Reding 	}, {
3679ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x74, 0x68, 0x69,
3689ef7e25fSThierry Reding 		0xb8, 0xc1, 0xb7, 0xbd, 0xcd, 0xb8, 0x93, 0xab,
3699ef7e25fSThierry Reding 		0x88, 0xb4, 0xc4, 0xb1, 0x00, 0x6b, 0x00, 0x4d,
3709ef7e25fSThierry Reding 		0x00, 0x7d,
3719ef7e25fSThierry Reding 	}, {
3729ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x95, 0x8a, 0x89,
3739ef7e25fSThierry Reding 		0xb4, 0xc6, 0xb2, 0xc5, 0xd2, 0xbf, 0x90, 0xa8,
3749ef7e25fSThierry Reding 		0x85, 0xb5, 0xc4, 0xb3, 0x00, 0x7b, 0x00, 0x5d,
3759ef7e25fSThierry Reding 		0x00, 0x8f,
3769ef7e25fSThierry Reding 	}, {
3779ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x9f, 0x98, 0x92,
3789ef7e25fSThierry Reding 		0xb3, 0xc4, 0xb0, 0xbc, 0xcc, 0xb4, 0x91, 0xa6,
3799ef7e25fSThierry Reding 		0x87, 0xb5, 0xc5, 0xb4, 0x00, 0x87, 0x00, 0x6a,
3809ef7e25fSThierry Reding 		0x00, 0x9e,
3819ef7e25fSThierry Reding 	}, {
3829ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x99, 0x93, 0x8b,
3839ef7e25fSThierry Reding 		0xb2, 0xc2, 0xb0, 0xbd, 0xce, 0xb4, 0x90, 0xa6,
3849ef7e25fSThierry Reding 		0x87, 0xb3, 0xc3, 0xb2, 0x00, 0x8d, 0x00, 0x70,
3859ef7e25fSThierry Reding 		0x00, 0xa4,
3869ef7e25fSThierry Reding 	}, {
3879ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xa5, 0x99,
3889ef7e25fSThierry Reding 		0xb2, 0xc2, 0xb0, 0xbb, 0xcd, 0xb1, 0x93, 0xa7,
3899ef7e25fSThierry Reding 		0x8a, 0xb2, 0xc1, 0xb0, 0x00, 0x92, 0x00, 0x75,
3909ef7e25fSThierry Reding 		0x00, 0xaa,
3919ef7e25fSThierry Reding 	}, {
3929ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa0, 0xa0, 0x93,
3939ef7e25fSThierry Reding 		0xb6, 0xc4, 0xb4, 0xb5, 0xc8, 0xaa, 0x94, 0xa9,
3949ef7e25fSThierry Reding 		0x8c, 0xb2, 0xc0, 0xb0, 0x00, 0x97, 0x00, 0x7a,
3959ef7e25fSThierry Reding 		0x00, 0xaf,
3969ef7e25fSThierry Reding 	}, {
3979ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xa7, 0x96,
3989ef7e25fSThierry Reding 		0xb3, 0xc2, 0xb0, 0xba, 0xcb, 0xb0, 0x94, 0xa8,
3999ef7e25fSThierry Reding 		0x8c, 0xb0, 0xbf, 0xaf, 0x00, 0x9f, 0x00, 0x83,
4009ef7e25fSThierry Reding 		0x00, 0xb9,
4019ef7e25fSThierry Reding 	}, {
4029ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x9d, 0xa2, 0x90,
4039ef7e25fSThierry Reding 		0xb6, 0xc5, 0xb3, 0xb8, 0xc9, 0xae, 0x94, 0xa8,
4049ef7e25fSThierry Reding 		0x8d, 0xaf, 0xbd, 0xad, 0x00, 0xa4, 0x00, 0x88,
4059ef7e25fSThierry Reding 		0x00, 0xbf,
4069ef7e25fSThierry Reding 	}, {
4079ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa6, 0xac, 0x97,
4089ef7e25fSThierry Reding 		0xb4, 0xc4, 0xb1, 0xbb, 0xcb, 0xb2, 0x93, 0xa7,
4099ef7e25fSThierry Reding 		0x8d, 0xae, 0xbc, 0xad, 0x00, 0xa7, 0x00, 0x8c,
4109ef7e25fSThierry Reding 		0x00, 0xc3,
4119ef7e25fSThierry Reding 	}, {
4129ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa2, 0xa9, 0x93,
4139ef7e25fSThierry Reding 		0xb6, 0xc5, 0xb2, 0xba, 0xc9, 0xb0, 0x93, 0xa7,
4149ef7e25fSThierry Reding 		0x8d, 0xae, 0xbb, 0xac, 0x00, 0xab, 0x00, 0x90,
4159ef7e25fSThierry Reding 		0x00, 0xc8,
4169ef7e25fSThierry Reding 	}, {
4179ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0x9e, 0xa6, 0x8f,
4189ef7e25fSThierry Reding 		0xb7, 0xc6, 0xb3, 0xb8, 0xc8, 0xb0, 0x93, 0xa6,
4199ef7e25fSThierry Reding 		0x8c, 0xae, 0xbb, 0xad, 0x00, 0xae, 0x00, 0x93,
4209ef7e25fSThierry Reding 		0x00, 0xcc,
4219ef7e25fSThierry Reding 	}, {
4229ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xab, 0xb4, 0x9c,
4239ef7e25fSThierry Reding 		0xb3, 0xc3, 0xaf, 0xb7, 0xc7, 0xaf, 0x93, 0xa6,
4249ef7e25fSThierry Reding 		0x8c, 0xaf, 0xbc, 0xad, 0x00, 0xb1, 0x00, 0x97,
4259ef7e25fSThierry Reding 		0x00, 0xcf,
4269ef7e25fSThierry Reding 	}, {
4279ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa6, 0xb1, 0x98,
4289ef7e25fSThierry Reding 		0xb1, 0xc2, 0xab, 0xba, 0xc9, 0xb2, 0x93, 0xa6,
4299ef7e25fSThierry Reding 		0x8d, 0xae, 0xba, 0xab, 0x00, 0xb5, 0x00, 0x9b,
4309ef7e25fSThierry Reding 		0x00, 0xd4,
4319ef7e25fSThierry Reding 	}, {
4329ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xae, 0x94,
4339ef7e25fSThierry Reding 		0xb2, 0xc3, 0xac, 0xbb, 0xca, 0xb4, 0x91, 0xa4,
4349ef7e25fSThierry Reding 		0x8a, 0xae, 0xba, 0xac, 0x00, 0xb8, 0x00, 0x9e,
4359ef7e25fSThierry Reding 		0x00, 0xd8,
4369ef7e25fSThierry Reding 	}, {
4379ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xab, 0xb7, 0x9c,
4389ef7e25fSThierry Reding 		0xae, 0xc0, 0xa9, 0xba, 0xc9, 0xb3, 0x92, 0xa5,
4399ef7e25fSThierry Reding 		0x8b, 0xad, 0xb9, 0xab, 0x00, 0xbb, 0x00, 0xa1,
4409ef7e25fSThierry Reding 		0x00, 0xdc,
4419ef7e25fSThierry Reding 	}, {
4429ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xb4, 0x97,
4439ef7e25fSThierry Reding 		0xb0, 0xc1, 0xaa, 0xb9, 0xc8, 0xb2, 0x92, 0xa5,
4449ef7e25fSThierry Reding 		0x8c, 0xae, 0xb9, 0xab, 0x00, 0xbe, 0x00, 0xa4,
4459ef7e25fSThierry Reding 		0x00, 0xdf,
4469ef7e25fSThierry Reding 	}, {
4479ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xb0, 0x94,
4489ef7e25fSThierry Reding 		0xb0, 0xc2, 0xab, 0xbb, 0xc9, 0xb3, 0x91, 0xa4,
4499ef7e25fSThierry Reding 		0x8b, 0xad, 0xb8, 0xaa, 0x00, 0xc1, 0x00, 0xa8,
4509ef7e25fSThierry Reding 		0x00, 0xe2,
4519ef7e25fSThierry Reding 	}, {
4529ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa3, 0xb0, 0x94,
4539ef7e25fSThierry Reding 		0xae, 0xbf, 0xa8, 0xb9, 0xc8, 0xb3, 0x92, 0xa4,
4549ef7e25fSThierry Reding 		0x8b, 0xad, 0xb7, 0xa9, 0x00, 0xc4, 0x00, 0xab,
4559ef7e25fSThierry Reding 		0x00, 0xe6,
4569ef7e25fSThierry Reding 	}, {
4579ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xb6, 0x98,
4589ef7e25fSThierry Reding 		0xaf, 0xc0, 0xa8, 0xb8, 0xc7, 0xb2, 0x93, 0xa5,
4599ef7e25fSThierry Reding 		0x8d, 0xad, 0xb7, 0xa9, 0x00, 0xc7, 0x00, 0xae,
4609ef7e25fSThierry Reding 		0x00, 0xe9,
4619ef7e25fSThierry Reding 	}, {
4629ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa4, 0xb3, 0x95,
4639ef7e25fSThierry Reding 		0xaf, 0xc1, 0xa9, 0xb9, 0xc8, 0xb3, 0x92, 0xa4,
4649ef7e25fSThierry Reding 		0x8b, 0xad, 0xb7, 0xaa, 0x00, 0xc9, 0x00, 0xb0,
4659ef7e25fSThierry Reding 		0x00, 0xec,
4669ef7e25fSThierry Reding 	}, {
4679ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa4, 0xb3, 0x95,
4689ef7e25fSThierry Reding 		0xac, 0xbe, 0xa6, 0xbb, 0xc9, 0xb4, 0x90, 0xa3,
4699ef7e25fSThierry Reding 		0x8a, 0xad, 0xb7, 0xa9, 0x00, 0xcc, 0x00, 0xb4,
4709ef7e25fSThierry Reding 		0x00, 0xf0,
4719ef7e25fSThierry Reding 	}, {
4729ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa0, 0xb0, 0x91,
4739ef7e25fSThierry Reding 		0xae, 0xc0, 0xa6, 0xba, 0xc8, 0xb4, 0x91, 0xa4,
4749ef7e25fSThierry Reding 		0x8b, 0xad, 0xb7, 0xa9, 0x00, 0xcf, 0x00, 0xb7,
4759ef7e25fSThierry Reding 		0x00, 0xf3,
4769ef7e25fSThierry Reding 	}, {
4779ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa7, 0xb8, 0x98,
4789ef7e25fSThierry Reding 		0xab, 0xbd, 0xa4, 0xbb, 0xc9, 0xb5, 0x91, 0xa3,
4799ef7e25fSThierry Reding 		0x8b, 0xac, 0xb6, 0xa8, 0x00, 0xd1, 0x00, 0xb9,
4809ef7e25fSThierry Reding 		0x00, 0xf6,
4819ef7e25fSThierry Reding 	}, {
4829ef7e25fSThierry Reding 		0xfa, 0x01, 0x71, 0x31, 0x7b, 0xa4, 0xb5, 0x95,
4839ef7e25fSThierry Reding 		0xa9, 0xbc, 0xa1, 0xbb, 0xc9, 0xb5, 0x91, 0xa3,
4849ef7e25fSThierry Reding 		0x8a, 0xad, 0xb6, 0xa8, 0x00, 0xd6, 0x00, 0xbf,
4859ef7e25fSThierry Reding 		0x00, 0xfc,
4869ef7e25fSThierry Reding 	},
4879ef7e25fSThierry Reding };
4889ef7e25fSThierry Reding 
4899ef7e25fSThierry Reding static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v96[GAMMA_LEVEL_NUM] = {
4909ef7e25fSThierry Reding 	{
4919ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
4929ef7e25fSThierry Reding 		0xdf, 0x1f, 0xd7, 0xdc, 0xb7, 0xe1, 0xc0, 0xaf,
4939ef7e25fSThierry Reding 		0xc4, 0xd2, 0xd0, 0xcf, 0x00, 0x4d, 0x00, 0x40,
4949ef7e25fSThierry Reding 		0x00, 0x5f,
4959ef7e25fSThierry Reding 	}, {
4969ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
4979ef7e25fSThierry Reding 		0xd5, 0x35, 0xcf, 0xdc, 0xc1, 0xe1, 0xbf, 0xb3,
4989ef7e25fSThierry Reding 		0xc1, 0xd2, 0xd1, 0xce,	0x00, 0x53, 0x00, 0x46,
4999ef7e25fSThierry Reding 		0x00, 0x67,
5009ef7e25fSThierry Reding 	}, {
5019ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
5029ef7e25fSThierry Reding 		0xd2, 0x64, 0xcf, 0xdb, 0xc6, 0xe1, 0xbd, 0xb3,
5039ef7e25fSThierry Reding 		0xbd, 0xd2, 0xd2, 0xce,	0x00, 0x59, 0x00, 0x4b,
5049ef7e25fSThierry Reding 		0x00, 0x6e,
5059ef7e25fSThierry Reding 	}, {
5069ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
5079ef7e25fSThierry Reding 		0xd0, 0x7c, 0xcf, 0xdb, 0xc9, 0xe0, 0xbc, 0xb4,
5089ef7e25fSThierry Reding 		0xbb, 0xcf, 0xd1, 0xcc, 0x00, 0x5f, 0x00, 0x50,
5099ef7e25fSThierry Reding 		0x00, 0x75,
5109ef7e25fSThierry Reding 	}, {
5119ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
5129ef7e25fSThierry Reding 		0xd0, 0x8e, 0xd1, 0xdb, 0xcc, 0xdf, 0xbb, 0xb6,
5139ef7e25fSThierry Reding 		0xb9, 0xd0, 0xd1, 0xcd,	0x00, 0x63, 0x00, 0x54,
5149ef7e25fSThierry Reding 		0x00, 0x7a,
5159ef7e25fSThierry Reding 	}, {
5169ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
5179ef7e25fSThierry Reding 		0xd1, 0x9e, 0xd5, 0xda, 0xcd, 0xdd, 0xbb, 0xb7,
5189ef7e25fSThierry Reding 		0xb9, 0xce, 0xce, 0xc9,	0x00, 0x68, 0x00, 0x59,
5199ef7e25fSThierry Reding 		0x00, 0x81,
5209ef7e25fSThierry Reding 	}, {
5219ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x00, 0xff,
5229ef7e25fSThierry Reding 		0xd0, 0xa5, 0xd6, 0xda, 0xcf, 0xdd, 0xbb, 0xb7,
5239ef7e25fSThierry Reding 		0xb8, 0xcc, 0xcd, 0xc7,	0x00, 0x6c, 0x00, 0x5c,
5249ef7e25fSThierry Reding 		0x00, 0x86,
5259ef7e25fSThierry Reding 	}, {
5269ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x1f, 0xfe,
5279ef7e25fSThierry Reding 		0xd0, 0xae, 0xd7, 0xd9, 0xd0, 0xdb, 0xb9, 0xb6,
5289ef7e25fSThierry Reding 		0xb5, 0xca, 0xcc, 0xc5,	0x00, 0x74, 0x00, 0x63,
5299ef7e25fSThierry Reding 		0x00, 0x90,
5309ef7e25fSThierry Reding 	}, {
5319ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x1f, 0xf9,
5329ef7e25fSThierry Reding 		0xcf, 0xb0, 0xd6, 0xd9, 0xd1, 0xdb, 0xb9, 0xb6,
5339ef7e25fSThierry Reding 		0xb4, 0xca, 0xcb, 0xc5,	0x00, 0x77, 0x00, 0x66,
5349ef7e25fSThierry Reding 		0x00, 0x94,
5359ef7e25fSThierry Reding 	}, {
5369ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xff, 0x1f, 0xf7,
5379ef7e25fSThierry Reding 		0xcf, 0xb3, 0xd7, 0xd8, 0xd1, 0xd9, 0xb7, 0xb6,
5389ef7e25fSThierry Reding 		0xb3, 0xc9, 0xca, 0xc3,	0x00, 0x7b, 0x00, 0x69,
5399ef7e25fSThierry Reding 		0x00, 0x99,
5409ef7e25fSThierry Reding 
5419ef7e25fSThierry Reding 	}, {
5429ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xfd, 0x2f, 0xf7,
5439ef7e25fSThierry Reding 		0xdf, 0xb5, 0xd6, 0xd8, 0xd1, 0xd8, 0xb6, 0xb5,
5449ef7e25fSThierry Reding 		0xb2, 0xca, 0xcb, 0xc4,	0x00, 0x7e, 0x00, 0x6c,
5459ef7e25fSThierry Reding 		0x00, 0x9d,
5469ef7e25fSThierry Reding 	}, {
5479ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xfa, 0x2f, 0xf5,
5489ef7e25fSThierry Reding 		0xce, 0xb6, 0xd5, 0xd7, 0xd2, 0xd8, 0xb6, 0xb4,
5499ef7e25fSThierry Reding 		0xb0, 0xc7, 0xc9, 0xc1,	0x00, 0x84, 0x00, 0x71,
5509ef7e25fSThierry Reding 		0x00, 0xa5,
5519ef7e25fSThierry Reding 	}, {
5529ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xf7, 0x2f, 0xf2,
5539ef7e25fSThierry Reding 		0xce, 0xb9, 0xd5, 0xd8, 0xd2, 0xd8, 0xb4, 0xb4,
5549ef7e25fSThierry Reding 		0xaf, 0xc7, 0xc9, 0xc1,	0x00, 0x87, 0x00, 0x73,
5559ef7e25fSThierry Reding 		0x00, 0xa8,
5569ef7e25fSThierry Reding 	}, {
5579ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xf5, 0x2f, 0xf0,
5589ef7e25fSThierry Reding 		0xdf, 0xba, 0xd5, 0xd7, 0xd2, 0xd7, 0xb4, 0xb4,
5599ef7e25fSThierry Reding 		0xaf, 0xc5, 0xc7, 0xbf,	0x00, 0x8a, 0x00, 0x76,
5609ef7e25fSThierry Reding 		0x00, 0xac,
5619ef7e25fSThierry Reding 	}, {
5629ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xf2, 0x2f, 0xed,
5639ef7e25fSThierry Reding 		0xcE, 0xbb, 0xd4, 0xd6, 0xd2, 0xd6, 0xb5, 0xb4,
5649ef7e25fSThierry Reding 		0xaF, 0xc5, 0xc7, 0xbf,	0x00, 0x8c, 0x00, 0x78,
5659ef7e25fSThierry Reding 		0x00, 0xaf,
5669ef7e25fSThierry Reding 	}, {
5679ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xef, 0x2f, 0xeb,
5689ef7e25fSThierry Reding 		0xcd, 0xbb, 0xd2, 0xd7, 0xd3, 0xd6, 0xb3, 0xb4,
5699ef7e25fSThierry Reding 		0xae, 0xc5, 0xc6, 0xbe,	0x00, 0x91, 0x00, 0x7d,
5709ef7e25fSThierry Reding 		0x00, 0xb6,
5719ef7e25fSThierry Reding 	}, {
5729ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xee, 0x2f, 0xea,
5739ef7e25fSThierry Reding 		0xce, 0xbd, 0xd4, 0xd6, 0xd2, 0xd5, 0xb2, 0xb3,
5749ef7e25fSThierry Reding 		0xad, 0xc3, 0xc4, 0xbb,	0x00, 0x94, 0x00, 0x7f,
5759ef7e25fSThierry Reding 		0x00, 0xba,
5769ef7e25fSThierry Reding 	}, {
5779ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xec, 0x2f, 0xe8,
5789ef7e25fSThierry Reding 		0xce, 0xbe, 0xd3, 0xd6, 0xd3, 0xd5, 0xb2, 0xb2,
5799ef7e25fSThierry Reding 		0xac, 0xc3, 0xc5, 0xbc,	0x00, 0x96, 0x00, 0x81,
5809ef7e25fSThierry Reding 		0x00, 0xbd,
5819ef7e25fSThierry Reding 	}, {
5829ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xeb, 0x2f, 0xe7,
5839ef7e25fSThierry Reding 		0xce, 0xbf, 0xd3, 0xd6, 0xd2, 0xd5, 0xb1, 0xb2,
5849ef7e25fSThierry Reding 		0xab, 0xc2, 0xc4, 0xbb,	0x00, 0x99, 0x00, 0x83,
5859ef7e25fSThierry Reding 		0x00, 0xc0,
5869ef7e25fSThierry Reding 	}, {
5879ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xef, 0x5f, 0xe9,
5889ef7e25fSThierry Reding 		0xca, 0xbf, 0xd3, 0xd5, 0xd2, 0xd4, 0xb2, 0xb2,
5899ef7e25fSThierry Reding 		0xab, 0xc1, 0xc4, 0xba,	0x00, 0x9b, 0x00, 0x85,
5909ef7e25fSThierry Reding 		0x00, 0xc3,
5919ef7e25fSThierry Reding 	}, {
5929ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xea, 0x5f, 0xe8,
5939ef7e25fSThierry Reding 		0xee, 0xbf, 0xd2, 0xd5, 0xd2, 0xd4, 0xb1, 0xb2,
5949ef7e25fSThierry Reding 		0xab, 0xc1, 0xc2, 0xb9,	0x00, 0x9D, 0x00, 0x87,
5959ef7e25fSThierry Reding 		0x00, 0xc6,
5969ef7e25fSThierry Reding 	}, {
5979ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe9, 0x5f, 0xe7,
5989ef7e25fSThierry Reding 		0xcd, 0xbf, 0xd2, 0xd6, 0xd2, 0xd4, 0xb1, 0xb2,
5999ef7e25fSThierry Reding 		0xab, 0xbe, 0xc0, 0xb7,	0x00, 0xa1, 0x00, 0x8a,
6009ef7e25fSThierry Reding 		0x00, 0xca,
6019ef7e25fSThierry Reding 	}, {
6029ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe8, 0x61, 0xe6,
6039ef7e25fSThierry Reding 		0xcd, 0xbf, 0xd1, 0xd6, 0xd3, 0xd4, 0xaf, 0xb0,
6049ef7e25fSThierry Reding 		0xa9, 0xbe, 0xc1, 0xb7,	0x00, 0xa3, 0x00, 0x8b,
6059ef7e25fSThierry Reding 		0x00, 0xce,
6069ef7e25fSThierry Reding 	}, {
6079ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe8, 0x62, 0xe5,
6089ef7e25fSThierry Reding 		0xcc, 0xc0, 0xd0, 0xd6, 0xd2, 0xd4, 0xaf, 0xb1,
6099ef7e25fSThierry Reding 		0xa9, 0xbd, 0xc0, 0xb6,	0x00, 0xa5, 0x00, 0x8d,
6109ef7e25fSThierry Reding 		0x00, 0xd0,
6119ef7e25fSThierry Reding 	}, {
6129ef7e25fSThierry Reding 		0xfa, 0x01, 0x1f, 0x1f, 0x1f, 0xe7, 0x7f, 0xe3,
6139ef7e25fSThierry Reding 		0xcc, 0xc1, 0xd0, 0xd5, 0xd3, 0xd3, 0xae, 0xaf,
6149ef7e25fSThierry Reding 		0xa8, 0xbe, 0xc0, 0xb7,	0x00, 0xa8, 0x00, 0x90,
6159ef7e25fSThierry Reding 		0x00, 0xd3,
6169ef7e25fSThierry Reding 	}
6179ef7e25fSThierry Reding };
6189ef7e25fSThierry Reding 
6199ef7e25fSThierry Reding static const s6e8aa0_gamma_table s6e8aa0_gamma_tables_v32[GAMMA_LEVEL_NUM] = {
6209ef7e25fSThierry Reding 	{
6219ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0x72, 0x5e, 0x6b,
6229ef7e25fSThierry Reding 		0xa1, 0xa7, 0x9a, 0xb4, 0xcb, 0xb8, 0x92, 0xac,
6239ef7e25fSThierry Reding 		0x97, 0xb4, 0xc3, 0xb5, 0x00, 0x4e, 0x00, 0x37,
6249ef7e25fSThierry Reding 		0x00, 0x58,
6259ef7e25fSThierry Reding 	}, {
6269ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0x85, 0x71, 0x7d,
6279ef7e25fSThierry Reding 		0xa6, 0xb6, 0xa1, 0xb5, 0xca, 0xba, 0x93, 0xac,
6289ef7e25fSThierry Reding 		0x98, 0xb2, 0xc0, 0xaf, 0x00, 0x59, 0x00, 0x43,
6299ef7e25fSThierry Reding 		0x00, 0x64,
6309ef7e25fSThierry Reding 	}, {
6319ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa4, 0x94, 0x9e,
6329ef7e25fSThierry Reding 		0xa0, 0xbb, 0x9c, 0xc3, 0xd2, 0xc6, 0x93, 0xaa,
6339ef7e25fSThierry Reding 		0x95, 0xb7, 0xc2, 0xb4, 0x00, 0x65, 0x00, 0x50,
6349ef7e25fSThierry Reding 		0x00, 0x74,
6359ef7e25fSThierry Reding 	}, {
6369ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xa1, 0xa6,
6379ef7e25fSThierry Reding 		0xa0, 0xb9, 0x9b, 0xc3, 0xd1, 0xc8, 0x90, 0xa6,
6389ef7e25fSThierry Reding 		0x90, 0xbb, 0xc3, 0xb7, 0x00, 0x6f, 0x00, 0x5b,
6399ef7e25fSThierry Reding 		0x00, 0x80,
6409ef7e25fSThierry Reding 	}, {
6419ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa6, 0x9d, 0x9f,
6429ef7e25fSThierry Reding 		0x9f, 0xb8, 0x9a, 0xc7, 0xd5, 0xcc, 0x90, 0xa5,
6439ef7e25fSThierry Reding 		0x8f, 0xb8, 0xc1, 0xb6, 0x00, 0x74, 0x00, 0x60,
6449ef7e25fSThierry Reding 		0x00, 0x85,
6459ef7e25fSThierry Reding 	}, {
6469ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb3, 0xae, 0xae,
6479ef7e25fSThierry Reding 		0x9e, 0xb7, 0x9a, 0xc8, 0xd6, 0xce, 0x91, 0xa6,
6489ef7e25fSThierry Reding 		0x90, 0xb6, 0xc0, 0xb3, 0x00, 0x78, 0x00, 0x65,
6499ef7e25fSThierry Reding 		0x00, 0x8a,
6509ef7e25fSThierry Reding 	}, {
6519ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xa9, 0xa8,
6529ef7e25fSThierry Reding 		0xa3, 0xb9, 0x9e, 0xc4, 0xd3, 0xcb, 0x94, 0xa6,
6539ef7e25fSThierry Reding 		0x90, 0xb6, 0xbf, 0xb3, 0x00, 0x7c, 0x00, 0x69,
6549ef7e25fSThierry Reding 		0x00, 0x8e,
6559ef7e25fSThierry Reding 	}, {
6569ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xaf, 0xaf, 0xa9,
6579ef7e25fSThierry Reding 		0xa5, 0xbc, 0xa2, 0xc7, 0xd5, 0xcd, 0x93, 0xa5,
6589ef7e25fSThierry Reding 		0x8f, 0xb4, 0xbd, 0xb1, 0x00, 0x83, 0x00, 0x70,
6599ef7e25fSThierry Reding 		0x00, 0x96,
6609ef7e25fSThierry Reding 	}, {
6619ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa9, 0xab, 0xa3,
6629ef7e25fSThierry Reding 		0xaa, 0xbf, 0xa7, 0xc5, 0xd3, 0xcb, 0x93, 0xa5,
6639ef7e25fSThierry Reding 		0x8f, 0xb2, 0xbb, 0xb0, 0x00, 0x86, 0x00, 0x74,
6649ef7e25fSThierry Reding 		0x00, 0x9b,
6659ef7e25fSThierry Reding 	}, {
6669ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb1, 0xb5, 0xab,
6679ef7e25fSThierry Reding 		0xab, 0xc0, 0xa9, 0xc7, 0xd4, 0xcc, 0x94, 0xa4,
6689ef7e25fSThierry Reding 		0x8f, 0xb1, 0xbb, 0xaf, 0x00, 0x8a, 0x00, 0x77,
6699ef7e25fSThierry Reding 		0x00, 0x9e,
6709ef7e25fSThierry Reding 	}, {
6719ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb2, 0xa7,
6729ef7e25fSThierry Reding 		0xae, 0xc2, 0xab, 0xc5, 0xd3, 0xca, 0x93, 0xa4,
6739ef7e25fSThierry Reding 		0x8f, 0xb1, 0xba, 0xae, 0x00, 0x8d, 0x00, 0x7b,
6749ef7e25fSThierry Reding 		0x00, 0xa2,
6759ef7e25fSThierry Reding 	}, {
6769ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa9, 0xaf, 0xa3,
6779ef7e25fSThierry Reding 		0xb0, 0xc3, 0xae, 0xc4, 0xd1, 0xc8, 0x93, 0xa4,
6789ef7e25fSThierry Reding 		0x8f, 0xb1, 0xba, 0xaf, 0x00, 0x8f, 0x00, 0x7d,
6799ef7e25fSThierry Reding 		0x00, 0xa5,
6809ef7e25fSThierry Reding 	}, {
6819ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb4, 0xbd, 0xaf,
6829ef7e25fSThierry Reding 		0xae, 0xc1, 0xab, 0xc2, 0xd0, 0xc6, 0x94, 0xa4,
6839ef7e25fSThierry Reding 		0x8f, 0xb1, 0xba, 0xaf, 0x00, 0x92, 0x00, 0x80,
6849ef7e25fSThierry Reding 		0x00, 0xa8,
6859ef7e25fSThierry Reding 	}, {
6869ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb0, 0xb9, 0xac,
6879ef7e25fSThierry Reding 		0xad, 0xc1, 0xab, 0xc4, 0xd1, 0xc7, 0x95, 0xa4,
6889ef7e25fSThierry Reding 		0x90, 0xb0, 0xb9, 0xad, 0x00, 0x95, 0x00, 0x84,
6899ef7e25fSThierry Reding 		0x00, 0xac,
6909ef7e25fSThierry Reding 	}, {
6919ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb6, 0xa7,
6929ef7e25fSThierry Reding 		0xaf, 0xc2, 0xae, 0xc5, 0xd1, 0xc7, 0x93, 0xa3,
6939ef7e25fSThierry Reding 		0x8e, 0xb0, 0xb9, 0xad, 0x00, 0x98, 0x00, 0x86,
6949ef7e25fSThierry Reding 		0x00, 0xaf,
6959ef7e25fSThierry Reding 	}, {
6969ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb4, 0xbf, 0xaf,
6979ef7e25fSThierry Reding 		0xad, 0xc1, 0xab, 0xc3, 0xd0, 0xc6, 0x94, 0xa3,
6989ef7e25fSThierry Reding 		0x8f, 0xaf, 0xb8, 0xac, 0x00, 0x9a, 0x00, 0x89,
6999ef7e25fSThierry Reding 		0x00, 0xb2,
7009ef7e25fSThierry Reding 	}, {
7019ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb0, 0xbc, 0xac,
7029ef7e25fSThierry Reding 		0xaf, 0xc2, 0xad, 0xc2, 0xcf, 0xc4, 0x94, 0xa3,
7039ef7e25fSThierry Reding 		0x90, 0xaf, 0xb8, 0xad, 0x00, 0x9c, 0x00, 0x8b,
7049ef7e25fSThierry Reding 		0x00, 0xb5,
7059ef7e25fSThierry Reding 	}, {
7069ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb9, 0xa7,
7079ef7e25fSThierry Reding 		0xb1, 0xc4, 0xaf, 0xc3, 0xcf, 0xc5, 0x94, 0xa3,
7089ef7e25fSThierry Reding 		0x8f, 0xae, 0xb7, 0xac, 0x00, 0x9f, 0x00, 0x8e,
7099ef7e25fSThierry Reding 		0x00, 0xb8,
7109ef7e25fSThierry Reding 	}, {
7119ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xb9, 0xa7,
7129ef7e25fSThierry Reding 		0xaf, 0xc2, 0xad, 0xc1, 0xce, 0xc3, 0x95, 0xa3,
7139ef7e25fSThierry Reding 		0x90, 0xad, 0xb6, 0xab, 0x00, 0xa2, 0x00, 0x91,
7149ef7e25fSThierry Reding 		0x00, 0xbb,
7159ef7e25fSThierry Reding 	}, {
7169ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb1, 0xbe, 0xac,
7179ef7e25fSThierry Reding 		0xb1, 0xc4, 0xaf, 0xc1, 0xcd, 0xc1, 0x95, 0xa4,
7189ef7e25fSThierry Reding 		0x91, 0xad, 0xb6, 0xab, 0x00, 0xa4, 0x00, 0x93,
7199ef7e25fSThierry Reding 		0x00, 0xbd,
7209ef7e25fSThierry Reding 	}, {
7219ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xbb, 0xa8,
7229ef7e25fSThierry Reding 		0xb3, 0xc5, 0xb2, 0xc1, 0xcd, 0xc2, 0x95, 0xa3,
7239ef7e25fSThierry Reding 		0x90, 0xad, 0xb6, 0xab, 0x00, 0xa6, 0x00, 0x95,
7249ef7e25fSThierry Reding 		0x00, 0xc0,
7259ef7e25fSThierry Reding 	}, {
7269ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xbb, 0xa8,
7279ef7e25fSThierry Reding 		0xb0, 0xc3, 0xaf, 0xc2, 0xce, 0xc2, 0x94, 0xa2,
7289ef7e25fSThierry Reding 		0x90, 0xac, 0xb6, 0xab, 0x00, 0xa8, 0x00, 0x98,
7299ef7e25fSThierry Reding 		0x00, 0xc3,
7309ef7e25fSThierry Reding 	}, {
7319ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xa9, 0xb8, 0xa5,
7329ef7e25fSThierry Reding 		0xb3, 0xc5, 0xb2, 0xc1, 0xcc, 0xc0, 0x95, 0xa2,
7339ef7e25fSThierry Reding 		0x90, 0xad, 0xb6, 0xab, 0x00, 0xaa, 0x00, 0x9a,
7349ef7e25fSThierry Reding 		0x00, 0xc5,
7359ef7e25fSThierry Reding 	}, {
7369ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xb0, 0xc0, 0xac,
7379ef7e25fSThierry Reding 		0xb0, 0xc3, 0xaf, 0xc1, 0xcd, 0xc1, 0x95, 0xa2,
7389ef7e25fSThierry Reding 		0x90, 0xac, 0xb5, 0xa9, 0x00, 0xac, 0x00, 0x9c,
7399ef7e25fSThierry Reding 		0x00, 0xc8,
7409ef7e25fSThierry Reding 	}, {
7419ef7e25fSThierry Reding 		0xfa, 0x01, 0x43, 0x14, 0x45, 0xad, 0xbd, 0xa8,
7429ef7e25fSThierry Reding 		0xaf, 0xc2, 0xaf, 0xc1, 0xcc, 0xc0, 0x95, 0xa2,
7439ef7e25fSThierry Reding 		0x90, 0xac, 0xb5, 0xaa, 0x00, 0xb1, 0x00, 0xa1,
7449ef7e25fSThierry Reding 		0x00, 0xcc,
7459ef7e25fSThierry Reding 	},
7469ef7e25fSThierry Reding };
7479ef7e25fSThierry Reding 
7489ef7e25fSThierry Reding static const struct s6e8aa0_variant s6e8aa0_variants[] = {
7499ef7e25fSThierry Reding 	{
7509ef7e25fSThierry Reding 		.version = 32,
7519ef7e25fSThierry Reding 		.gamma_tables = s6e8aa0_gamma_tables_v32,
7529ef7e25fSThierry Reding 	}, {
7539ef7e25fSThierry Reding 		.version = 96,
7549ef7e25fSThierry Reding 		.gamma_tables = s6e8aa0_gamma_tables_v96,
7559ef7e25fSThierry Reding 	}, {
7569ef7e25fSThierry Reding 		.version = 142,
7579ef7e25fSThierry Reding 		.gamma_tables = s6e8aa0_gamma_tables_v142,
7589ef7e25fSThierry Reding 	}, {
7599ef7e25fSThierry Reding 		.version = 210,
7609ef7e25fSThierry Reding 		.gamma_tables = s6e8aa0_gamma_tables_v142,
7619ef7e25fSThierry Reding 	}
7629ef7e25fSThierry Reding };
7639ef7e25fSThierry Reding 
s6e8aa0_brightness_set(struct s6e8aa0 * ctx)7649ef7e25fSThierry Reding static void s6e8aa0_brightness_set(struct s6e8aa0 *ctx)
7659ef7e25fSThierry Reding {
7669ef7e25fSThierry Reding 	const u8 *gamma;
7679ef7e25fSThierry Reding 
7689ef7e25fSThierry Reding 	if (ctx->error)
7699ef7e25fSThierry Reding 		return;
7709ef7e25fSThierry Reding 
7719ef7e25fSThierry Reding 	gamma = ctx->variant->gamma_tables[ctx->brightness];
7729ef7e25fSThierry Reding 
7739ef7e25fSThierry Reding 	if (ctx->version >= 142)
7749ef7e25fSThierry Reding 		s6e8aa0_elvss_nvm_set(ctx);
7759ef7e25fSThierry Reding 
7769ef7e25fSThierry Reding 	s6e8aa0_dcs_write(ctx, gamma, GAMMA_TABLE_LEN);
7779ef7e25fSThierry Reding 
7789ef7e25fSThierry Reding 	/* update gamma table. */
7799ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq_static(ctx, 0xf7, 0x03);
7809ef7e25fSThierry Reding }
7819ef7e25fSThierry Reding 
s6e8aa0_panel_init(struct s6e8aa0 * ctx)7829ef7e25fSThierry Reding static void s6e8aa0_panel_init(struct s6e8aa0 *ctx)
7839ef7e25fSThierry Reding {
7849ef7e25fSThierry Reding 	s6e8aa0_apply_level_1_key(ctx);
7859ef7e25fSThierry Reding 	s6e8aa0_apply_level_2_key(ctx);
7869ef7e25fSThierry Reding 	msleep(20);
7879ef7e25fSThierry Reding 
7889ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq_static(ctx, MIPI_DCS_EXIT_SLEEP_MODE);
7899ef7e25fSThierry Reding 	msleep(40);
7909ef7e25fSThierry Reding 
7919ef7e25fSThierry Reding 	s6e8aa0_panel_cond_set(ctx);
7929ef7e25fSThierry Reding 	s6e8aa0_display_condition_set(ctx);
7939ef7e25fSThierry Reding 	s6e8aa0_brightness_set(ctx);
7949ef7e25fSThierry Reding 	s6e8aa0_etc_source_control(ctx);
7959ef7e25fSThierry Reding 	s6e8aa0_etc_pentile_control(ctx);
7969ef7e25fSThierry Reding 	s6e8aa0_elvss_nvm_set(ctx);
7979ef7e25fSThierry Reding 	s6e8aa0_etc_power_control(ctx);
7989ef7e25fSThierry Reding 	s6e8aa0_etc_elvss_control(ctx);
7999ef7e25fSThierry Reding 	msleep(ctx->init_delay);
8009ef7e25fSThierry Reding }
8019ef7e25fSThierry Reding 
s6e8aa0_set_maximum_return_packet_size(struct s6e8aa0 * ctx,u16 size)8029ef7e25fSThierry Reding static void s6e8aa0_set_maximum_return_packet_size(struct s6e8aa0 *ctx,
8039ef7e25fSThierry Reding 						   u16 size)
8049ef7e25fSThierry Reding {
8059ef7e25fSThierry Reding 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
8069ef7e25fSThierry Reding 	int ret;
8079ef7e25fSThierry Reding 
8089ef7e25fSThierry Reding 	if (ctx->error < 0)
8099ef7e25fSThierry Reding 		return;
8109ef7e25fSThierry Reding 
8119ef7e25fSThierry Reding 	ret = mipi_dsi_set_maximum_return_packet_size(dsi, size);
8129ef7e25fSThierry Reding 	if (ret < 0) {
8139ef7e25fSThierry Reding 		dev_err(ctx->dev,
8149ef7e25fSThierry Reding 			"error %d setting maximum return packet size to %d\n",
8159ef7e25fSThierry Reding 			ret, size);
8169ef7e25fSThierry Reding 		ctx->error = ret;
8179ef7e25fSThierry Reding 	}
8189ef7e25fSThierry Reding }
8199ef7e25fSThierry Reding 
s6e8aa0_read_mtp_id(struct s6e8aa0 * ctx)8209ef7e25fSThierry Reding static void s6e8aa0_read_mtp_id(struct s6e8aa0 *ctx)
8219ef7e25fSThierry Reding {
8229ef7e25fSThierry Reding 	u8 id[3];
8239ef7e25fSThierry Reding 	int ret, i;
8249ef7e25fSThierry Reding 
8259ef7e25fSThierry Reding 	ret = s6e8aa0_dcs_read(ctx, 0xd1, id, ARRAY_SIZE(id));
826cd0e0ca6SDan Carpenter 	if (ret < 0 || ret < ARRAY_SIZE(id) || id[0] == 0x00) {
8279ef7e25fSThierry Reding 		dev_err(ctx->dev, "read id failed\n");
8289ef7e25fSThierry Reding 		ctx->error = -EIO;
8299ef7e25fSThierry Reding 		return;
8309ef7e25fSThierry Reding 	}
8319ef7e25fSThierry Reding 
8329ef7e25fSThierry Reding 	dev_info(ctx->dev, "ID: 0x%2x, 0x%2x, 0x%2x\n", id[0], id[1], id[2]);
8339ef7e25fSThierry Reding 
8349ef7e25fSThierry Reding 	for (i = 0; i < ARRAY_SIZE(s6e8aa0_variants); ++i) {
8359ef7e25fSThierry Reding 		if (id[1] == s6e8aa0_variants[i].version)
8369ef7e25fSThierry Reding 			break;
8379ef7e25fSThierry Reding 	}
8389ef7e25fSThierry Reding 	if (i >= ARRAY_SIZE(s6e8aa0_variants)) {
8399ef7e25fSThierry Reding 		dev_err(ctx->dev, "unsupported display version %d\n", id[1]);
8409ef7e25fSThierry Reding 		ctx->error = -EINVAL;
8419ef7e25fSThierry Reding 		return;
8429ef7e25fSThierry Reding 	}
8439ef7e25fSThierry Reding 
8449ef7e25fSThierry Reding 	ctx->variant = &s6e8aa0_variants[i];
8459ef7e25fSThierry Reding 	ctx->version = id[1];
8469ef7e25fSThierry Reding 	ctx->id = id[2];
8479ef7e25fSThierry Reding }
8489ef7e25fSThierry Reding 
s6e8aa0_set_sequence(struct s6e8aa0 * ctx)8499ef7e25fSThierry Reding static void s6e8aa0_set_sequence(struct s6e8aa0 *ctx)
8509ef7e25fSThierry Reding {
8519ef7e25fSThierry Reding 	s6e8aa0_set_maximum_return_packet_size(ctx, 3);
8529ef7e25fSThierry Reding 	s6e8aa0_read_mtp_id(ctx);
8539ef7e25fSThierry Reding 	s6e8aa0_panel_init(ctx);
8549ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq_static(ctx, MIPI_DCS_SET_DISPLAY_ON);
8559ef7e25fSThierry Reding }
8569ef7e25fSThierry Reding 
s6e8aa0_power_on(struct s6e8aa0 * ctx)8579ef7e25fSThierry Reding static int s6e8aa0_power_on(struct s6e8aa0 *ctx)
8589ef7e25fSThierry Reding {
8599ef7e25fSThierry Reding 	int ret;
8609ef7e25fSThierry Reding 
8619ef7e25fSThierry Reding 	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
8629ef7e25fSThierry Reding 	if (ret < 0)
8639ef7e25fSThierry Reding 		return ret;
8649ef7e25fSThierry Reding 
8659ef7e25fSThierry Reding 	msleep(ctx->power_on_delay);
8669ef7e25fSThierry Reding 
8679ef7e25fSThierry Reding 	gpiod_set_value(ctx->reset_gpio, 0);
8689ef7e25fSThierry Reding 	usleep_range(10000, 11000);
8699ef7e25fSThierry Reding 	gpiod_set_value(ctx->reset_gpio, 1);
8709ef7e25fSThierry Reding 
8719ef7e25fSThierry Reding 	msleep(ctx->reset_delay);
8729ef7e25fSThierry Reding 
8739ef7e25fSThierry Reding 	return 0;
8749ef7e25fSThierry Reding }
8759ef7e25fSThierry Reding 
s6e8aa0_power_off(struct s6e8aa0 * ctx)8769ef7e25fSThierry Reding static int s6e8aa0_power_off(struct s6e8aa0 *ctx)
8779ef7e25fSThierry Reding {
8789ef7e25fSThierry Reding 	return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
8799ef7e25fSThierry Reding }
8809ef7e25fSThierry Reding 
s6e8aa0_disable(struct drm_panel * panel)8819ef7e25fSThierry Reding static int s6e8aa0_disable(struct drm_panel *panel)
8829ef7e25fSThierry Reding {
8839ef7e25fSThierry Reding 	return 0;
8849ef7e25fSThierry Reding }
8859ef7e25fSThierry Reding 
s6e8aa0_unprepare(struct drm_panel * panel)8869ef7e25fSThierry Reding static int s6e8aa0_unprepare(struct drm_panel *panel)
8879ef7e25fSThierry Reding {
8889ef7e25fSThierry Reding 	struct s6e8aa0 *ctx = panel_to_s6e8aa0(panel);
8899ef7e25fSThierry Reding 
8909ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq_static(ctx, MIPI_DCS_ENTER_SLEEP_MODE);
8919ef7e25fSThierry Reding 	s6e8aa0_dcs_write_seq_static(ctx, MIPI_DCS_SET_DISPLAY_OFF);
8929ef7e25fSThierry Reding 	msleep(40);
8939ef7e25fSThierry Reding 
8949ef7e25fSThierry Reding 	s6e8aa0_clear_error(ctx);
8959ef7e25fSThierry Reding 
8969ef7e25fSThierry Reding 	return s6e8aa0_power_off(ctx);
8979ef7e25fSThierry Reding }
8989ef7e25fSThierry Reding 
s6e8aa0_prepare(struct drm_panel * panel)8999ef7e25fSThierry Reding static int s6e8aa0_prepare(struct drm_panel *panel)
9009ef7e25fSThierry Reding {
9019ef7e25fSThierry Reding 	struct s6e8aa0 *ctx = panel_to_s6e8aa0(panel);
9029ef7e25fSThierry Reding 	int ret;
9039ef7e25fSThierry Reding 
9049ef7e25fSThierry Reding 	ret = s6e8aa0_power_on(ctx);
9059ef7e25fSThierry Reding 	if (ret < 0)
9069ef7e25fSThierry Reding 		return ret;
9079ef7e25fSThierry Reding 
9089ef7e25fSThierry Reding 	s6e8aa0_set_sequence(ctx);
9099ef7e25fSThierry Reding 	ret = ctx->error;
9109ef7e25fSThierry Reding 
9119ef7e25fSThierry Reding 	if (ret < 0)
9129ef7e25fSThierry Reding 		s6e8aa0_unprepare(panel);
9139ef7e25fSThierry Reding 
9149ef7e25fSThierry Reding 	return ret;
9159ef7e25fSThierry Reding }
9169ef7e25fSThierry Reding 
s6e8aa0_enable(struct drm_panel * panel)9179ef7e25fSThierry Reding static int s6e8aa0_enable(struct drm_panel *panel)
9189ef7e25fSThierry Reding {
9199ef7e25fSThierry Reding 	return 0;
9209ef7e25fSThierry Reding }
9219ef7e25fSThierry Reding 
s6e8aa0_get_modes(struct drm_panel * panel,struct drm_connector * connector)9220ce8ddd8SSam Ravnborg static int s6e8aa0_get_modes(struct drm_panel *panel,
9230ce8ddd8SSam Ravnborg 			     struct drm_connector *connector)
9249ef7e25fSThierry Reding {
9259ef7e25fSThierry Reding 	struct s6e8aa0 *ctx = panel_to_s6e8aa0(panel);
9269ef7e25fSThierry Reding 	struct drm_display_mode *mode;
9279ef7e25fSThierry Reding 
9289ef7e25fSThierry Reding 	mode = drm_mode_create(connector->dev);
9299ef7e25fSThierry Reding 	if (!mode) {
9305936b3bdSSam Ravnborg 		dev_err(panel->dev, "failed to create a new display mode\n");
9319ef7e25fSThierry Reding 		return 0;
9329ef7e25fSThierry Reding 	}
9339ef7e25fSThierry Reding 
9349ef7e25fSThierry Reding 	drm_display_mode_from_videomode(&ctx->vm, mode);
9359ef7e25fSThierry Reding 	mode->width_mm = ctx->width_mm;
9369ef7e25fSThierry Reding 	mode->height_mm = ctx->height_mm;
9379ef7e25fSThierry Reding 	connector->display_info.width_mm = mode->width_mm;
9389ef7e25fSThierry Reding 	connector->display_info.height_mm = mode->height_mm;
9399ef7e25fSThierry Reding 
9409ef7e25fSThierry Reding 	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
9419ef7e25fSThierry Reding 	drm_mode_probed_add(connector, mode);
9429ef7e25fSThierry Reding 
9439ef7e25fSThierry Reding 	return 1;
9449ef7e25fSThierry Reding }
9459ef7e25fSThierry Reding 
9469ef7e25fSThierry Reding static const struct drm_panel_funcs s6e8aa0_drm_funcs = {
9479ef7e25fSThierry Reding 	.disable = s6e8aa0_disable,
9489ef7e25fSThierry Reding 	.unprepare = s6e8aa0_unprepare,
9499ef7e25fSThierry Reding 	.prepare = s6e8aa0_prepare,
9509ef7e25fSThierry Reding 	.enable = s6e8aa0_enable,
9519ef7e25fSThierry Reding 	.get_modes = s6e8aa0_get_modes,
9529ef7e25fSThierry Reding };
9539ef7e25fSThierry Reding 
s6e8aa0_parse_dt(struct s6e8aa0 * ctx)9549ef7e25fSThierry Reding static int s6e8aa0_parse_dt(struct s6e8aa0 *ctx)
9559ef7e25fSThierry Reding {
9569ef7e25fSThierry Reding 	struct device *dev = ctx->dev;
9579ef7e25fSThierry Reding 	struct device_node *np = dev->of_node;
9589ef7e25fSThierry Reding 	int ret;
9599ef7e25fSThierry Reding 
9609ef7e25fSThierry Reding 	ret = of_get_videomode(np, &ctx->vm, 0);
9619ef7e25fSThierry Reding 	if (ret < 0)
9629ef7e25fSThierry Reding 		return ret;
9639ef7e25fSThierry Reding 
9649ef7e25fSThierry Reding 	of_property_read_u32(np, "power-on-delay", &ctx->power_on_delay);
9659ef7e25fSThierry Reding 	of_property_read_u32(np, "reset-delay", &ctx->reset_delay);
9669ef7e25fSThierry Reding 	of_property_read_u32(np, "init-delay", &ctx->init_delay);
9679ef7e25fSThierry Reding 	of_property_read_u32(np, "panel-width-mm", &ctx->width_mm);
9689ef7e25fSThierry Reding 	of_property_read_u32(np, "panel-height-mm", &ctx->height_mm);
9699ef7e25fSThierry Reding 
9709ef7e25fSThierry Reding 	ctx->flip_horizontal = of_property_read_bool(np, "flip-horizontal");
9719ef7e25fSThierry Reding 	ctx->flip_vertical = of_property_read_bool(np, "flip-vertical");
9729ef7e25fSThierry Reding 
9739ef7e25fSThierry Reding 	return 0;
9749ef7e25fSThierry Reding }
9759ef7e25fSThierry Reding 
s6e8aa0_probe(struct mipi_dsi_device * dsi)9769ef7e25fSThierry Reding static int s6e8aa0_probe(struct mipi_dsi_device *dsi)
9779ef7e25fSThierry Reding {
9789ef7e25fSThierry Reding 	struct device *dev = &dsi->dev;
9799ef7e25fSThierry Reding 	struct s6e8aa0 *ctx;
9809ef7e25fSThierry Reding 	int ret;
9819ef7e25fSThierry Reding 
9829ef7e25fSThierry Reding 	ctx = devm_kzalloc(dev, sizeof(struct s6e8aa0), GFP_KERNEL);
9839ef7e25fSThierry Reding 	if (!ctx)
9849ef7e25fSThierry Reding 		return -ENOMEM;
9859ef7e25fSThierry Reding 
9869ef7e25fSThierry Reding 	mipi_dsi_set_drvdata(dsi, ctx);
9879ef7e25fSThierry Reding 
9889ef7e25fSThierry Reding 	ctx->dev = dev;
9899ef7e25fSThierry Reding 
9909ef7e25fSThierry Reding 	dsi->lanes = 4;
9919ef7e25fSThierry Reding 	dsi->format = MIPI_DSI_FMT_RGB888;
9929ef7e25fSThierry Reding 	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST
9939ef7e25fSThierry Reding 		| MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_AUTO_VERT;
9949ef7e25fSThierry Reding 
9959ef7e25fSThierry Reding 	ret = s6e8aa0_parse_dt(ctx);
9969ef7e25fSThierry Reding 	if (ret < 0)
9979ef7e25fSThierry Reding 		return ret;
9989ef7e25fSThierry Reding 
9999ef7e25fSThierry Reding 	ctx->supplies[0].supply = "vdd3";
10009ef7e25fSThierry Reding 	ctx->supplies[1].supply = "vci";
10019ef7e25fSThierry Reding 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
10029ef7e25fSThierry Reding 				      ctx->supplies);
10039ef7e25fSThierry Reding 	if (ret < 0) {
10049ef7e25fSThierry Reding 		dev_err(dev, "failed to get regulators: %d\n", ret);
10059ef7e25fSThierry Reding 		return ret;
10069ef7e25fSThierry Reding 	}
10079ef7e25fSThierry Reding 
10089ef7e25fSThierry Reding 	ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
10099ef7e25fSThierry Reding 	if (IS_ERR(ctx->reset_gpio)) {
10109ef7e25fSThierry Reding 		dev_err(dev, "cannot get reset-gpios %ld\n",
10119ef7e25fSThierry Reding 			PTR_ERR(ctx->reset_gpio));
10129ef7e25fSThierry Reding 		return PTR_ERR(ctx->reset_gpio);
10139ef7e25fSThierry Reding 	}
10149ef7e25fSThierry Reding 
10159ef7e25fSThierry Reding 	ctx->brightness = GAMMA_LEVEL_NUM - 1;
10169ef7e25fSThierry Reding 
10179a2654c0SLaurent Pinchart 	drm_panel_init(&ctx->panel, dev, &s6e8aa0_drm_funcs,
10189a2654c0SLaurent Pinchart 		       DRM_MODE_CONNECTOR_DSI);
1019*a91d0e7dSJagan Teki 	ctx->panel.prepare_prev_first = true;
10209ef7e25fSThierry Reding 
1021c3ee8c65SBernard Zhao 	drm_panel_add(&ctx->panel);
10229ef7e25fSThierry Reding 
10239ef7e25fSThierry Reding 	ret = mipi_dsi_attach(dsi);
10249ef7e25fSThierry Reding 	if (ret < 0)
10259ef7e25fSThierry Reding 		drm_panel_remove(&ctx->panel);
10269ef7e25fSThierry Reding 
10279ef7e25fSThierry Reding 	return ret;
10289ef7e25fSThierry Reding }
10299ef7e25fSThierry Reding 
s6e8aa0_remove(struct mipi_dsi_device * dsi)103079abca2bSUwe Kleine-König static void s6e8aa0_remove(struct mipi_dsi_device *dsi)
10319ef7e25fSThierry Reding {
10329ef7e25fSThierry Reding 	struct s6e8aa0 *ctx = mipi_dsi_get_drvdata(dsi);
10339ef7e25fSThierry Reding 
10349ef7e25fSThierry Reding 	mipi_dsi_detach(dsi);
10359ef7e25fSThierry Reding 	drm_panel_remove(&ctx->panel);
10369ef7e25fSThierry Reding }
10379ef7e25fSThierry Reding 
10389ef7e25fSThierry Reding static const struct of_device_id s6e8aa0_of_match[] = {
10399ef7e25fSThierry Reding 	{ .compatible = "samsung,s6e8aa0" },
10409ef7e25fSThierry Reding 	{ }
10419ef7e25fSThierry Reding };
10429ef7e25fSThierry Reding MODULE_DEVICE_TABLE(of, s6e8aa0_of_match);
10439ef7e25fSThierry Reding 
10449ef7e25fSThierry Reding static struct mipi_dsi_driver s6e8aa0_driver = {
10459ef7e25fSThierry Reding 	.probe = s6e8aa0_probe,
10469ef7e25fSThierry Reding 	.remove = s6e8aa0_remove,
10479ef7e25fSThierry Reding 	.driver = {
10489ef7e25fSThierry Reding 		.name = "panel-samsung-s6e8aa0",
10499ef7e25fSThierry Reding 		.of_match_table = s6e8aa0_of_match,
10509ef7e25fSThierry Reding 	},
10519ef7e25fSThierry Reding };
10529ef7e25fSThierry Reding module_mipi_dsi_driver(s6e8aa0_driver);
10539ef7e25fSThierry Reding 
10549ef7e25fSThierry Reding MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
10559ef7e25fSThierry Reding MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
10569ef7e25fSThierry Reding MODULE_AUTHOR("Joongmock Shin <jmock.shin@samsung.com>");
10579ef7e25fSThierry Reding MODULE_AUTHOR("Eunchul Kim <chulspro.kim@samsung.com>");
10589ef7e25fSThierry Reding MODULE_AUTHOR("Tomasz Figa <t.figa@samsung.com>");
10599ef7e25fSThierry Reding MODULE_AUTHOR("Andrzej Hajda <a.hajda@samsung.com>");
10609ef7e25fSThierry Reding MODULE_DESCRIPTION("MIPI-DSI based s6e8aa0 AMOLED LCD Panel Driver");
10619ef7e25fSThierry Reding MODULE_LICENSE("GPL v2");
1062