brintos

brintos / linux-shallow public Read only

0
0
Text · 22.6 KiB · 14932cb Raw
898 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2020 BayLibre, SAS4 * Author: Neil Armstrong <narmstrong@baylibre.com>5 */6 7#include <linux/delay.h>8#include <linux/gpio/consumer.h>9#include <linux/module.h>10#include <linux/of.h>11#include <linux/regulator/consumer.h>12 13#include <video/mipi_display.h>14 15#include <drm/drm_crtc.h>16#include <drm/drm_device.h>17#include <drm/drm_mipi_dsi.h>18#include <drm/drm_modes.h>19#include <drm/drm_panel.h>20 21struct khadas_ts050_panel {22	struct drm_panel base;23	struct mipi_dsi_device *link;24 25	struct regulator *supply;26	struct gpio_desc *reset_gpio;27	struct gpio_desc *enable_gpio;28	struct khadas_ts050_panel_data *panel_data;29};30 31struct khadas_ts050_panel_cmd {32	u8 cmd;33	u8 data[55];34	u8 size;35};36 37struct khadas_ts050_panel_data {38	struct khadas_ts050_panel_cmd *init_code;39	int len;40};41 42static const struct khadas_ts050_panel_cmd ts050v2_init_code[] = {43	{0xB9, {0xFF, 0x83, 0x99}, 0x03},44	{0xBA, {0x63, 0x23, 0x68, 0xCF}, 0x04},45	{0xD2, {0x55}, 0x01},46	{0xB1, {0x02, 0x04, 0x70, 0x90, 0x01, 0x32, 0x33,47			0x11, 0x11, 0x4D, 0x57, 0x56, 0x73, 0x02, 0x02}, 0x0f},48	{0xB2, {0x00, 0x80, 0x80, 0xAE, 0x0A, 0x0E, 0x75, 0x11, 0x00, 0x00, 0x00}, 0x0b},49	{0xB4, {0x00, 0xFF, 0x04, 0xA4, 0x02, 0xA0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02,50			0x00, 0x24,	0x02, 0x04, 0x0A, 0x21, 0x03, 0x00, 0x00, 0x08, 0xA6, 0x88,51			0x04, 0xA4, 0x02, 0xA0,	0x00, 0x00,	0x10, 0x00, 0x00, 0x02, 0x00, 0x24,52			0x02, 0x04, 0x0A, 0x00, 0x00, 0x08,	0xA6, 0x00, 0x08, 0x11}, 0x2e},53	{0xD3, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,54			0x18, 0x32, 0x10, 0x09, 0x00, 0x09, 0x32,55			0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,56			0x00, 0x00, 0x11, 0x00, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x0A,57			0x40}, 0x21},58	{0xD5, {0x18, 0x18, 0x18, 0x18, 0x21, 0x20, 0x18, 0x18, 0x19, 0x19, 0x19,59			0x19, 0x18, 0x18, 0x18, 0x18, 0x03, 0x02, 0x01, 0x00, 0x2F, 0x2F,60			0x30, 0x30, 0x31, 0x31, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, 0x20},61	{0xD6, {0x18, 0x18, 0x18, 0x18, 0x20, 0x21, 0x19, 0x19, 0x18, 0x18, 0x19,62			0x19, 0x18, 0x18, 0x18, 0x18, 0x00, 0x01, 0x02, 0x03, 0x2F, 0x2F,63			0x30, 0x30, 0x31, 0x31, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, 0x20},64	{0xD8, {0x0A, 0xBE, 0xFA, 0xA0, 0x0A, 0xBE, 0xFA, 0xA0}, 0x08},65	{0xBD, {0x01}, 0x01},66	{0xD8, {0x0F, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xE0}, 0x08},67	{0xBD, {0x02}, 0x01},68	{0xD8, {0x0F, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xE0}, 0x08},69	{0xBD, {0x00}, 0x01},70	{0xE0, {0x01, 0x35, 0x41, 0x3B, 0x79, 0x81, 0x8C, 0x85, 0x8E,71			0x95, 0x9B, 0xA0, 0xA4, 0xAB, 0xB1, 0xB3, 0xB7, 0xC5, 0xBD, 0xC5,72			0xB6, 0xC2, 0xC2, 0x62, 0x5D, 0x66, 0x73, 0x01, 0x35, 0x41, 0x3B,73			0x79, 0x81, 0x8C, 0x85, 0x8E, 0x95, 0x9B, 0xA0, 0xA4, 0xAB, 0xB1,74			0xB3, 0xB7, 0xB5, 0xBD, 0xC5, 0xB6, 0xC2, 0xC2, 0x62, 0x5D, 0x66,75			0x73}, 0x36},76	{0xB6, {0x97, 0x97}, 0x02},77	{0xCC, {0xC8}, 0x02},78	{0xBF, {0x40, 0x41, 0x50, 0x19}, 0x04},79	{0xC6, {0xFF, 0xF9}, 0x02},80	{0xC0, {0x25, 0x5A}, 0x02},81};82 83/* Only the CMD1 User Command set is documented */84static const struct khadas_ts050_panel_cmd ts050_init_code[] = {85	/* Select Unknown CMD Page (Undocumented) */86	{0xff, {0xee}, 0x01},87	/* Reload CMD1: Don't reload default value to register */88	{0xfb, {0x01}, 0x01},89	{0x1f, {0x45}, 0x01},90	{0x24, {0x4f}, 0x01},91	{0x38, {0xc8}, 0x01},92	{0x39, {0x27}, 0x01},93	{0x1e, {0x77}, 0x01},94	{0x1d, {0x0f}, 0x01},95	{0x7e, {0x71}, 0x01},96	{0x7c, {0x03}, 0x01},97	{0xff, {0x00}, 0x01},98	{0xfb, {0x01}, 0x01},99	{0x35, {0x01}, 0x01},100	/* Select CMD2 Page0 (Undocumented) */101	{0xff, {0x01}, 0x01},102	/* Reload CMD1: Don't reload default value to register */103	{0xfb, {0x01}, 0x01},104	{0x00, {0x01}, 0x01},105	{0x01, {0x55}, 0x01},106	{0x02, {0x40}, 0x01},107	{0x05, {0x40}, 0x01},108	{0x06, {0x4a}, 0x01},109	{0x07, {0x24}, 0x01},110	{0x08, {0x0c}, 0x01},111	{0x0b, {0x7d}, 0x01},112	{0x0c, {0x7d}, 0x01},113	{0x0e, {0xb0}, 0x01},114	{0x0f, {0xae}, 0x01},115	{0x11, {0x10}, 0x01},116	{0x12, {0x10}, 0x01},117	{0x13, {0x03}, 0x01},118	{0x14, {0x4a}, 0x01},119	{0x15, {0x12}, 0x01},120	{0x16, {0x12}, 0x01},121	{0x18, {0x00}, 0x01},122	{0x19, {0x77}, 0x01},123	{0x1a, {0x55}, 0x01},124	{0x1b, {0x13}, 0x01},125	{0x1c, {0x00}, 0x01},126	{0x1d, {0x00}, 0x01},127	{0x1e, {0x13}, 0x01},128	{0x1f, {0x00}, 0x01},129	{0x23, {0x00}, 0x01},130	{0x24, {0x00}, 0x01},131	{0x25, {0x00}, 0x01},132	{0x26, {0x00}, 0x01},133	{0x27, {0x00}, 0x01},134	{0x28, {0x00}, 0x01},135	{0x35, {0x00}, 0x01},136	{0x66, {0x00}, 0x01},137	{0x58, {0x82}, 0x01},138	{0x59, {0x02}, 0x01},139	{0x5a, {0x02}, 0x01},140	{0x5b, {0x02}, 0x01},141	{0x5c, {0x82}, 0x01},142	{0x5d, {0x82}, 0x01},143	{0x5e, {0x02}, 0x01},144	{0x5f, {0x02}, 0x01},145	{0x72, {0x31}, 0x01},146	/* Select CMD2 Page4 (Undocumented) */147	{0xff, {0x05}, 0x01},148	/* Reload CMD1: Don't reload default value to register */149	{0xfb, {0x01}, 0x01},150	{0x00, {0x01}, 0x01},151	{0x01, {0x0b}, 0x01},152	{0x02, {0x0c}, 0x01},153	{0x03, {0x09}, 0x01},154	{0x04, {0x0a}, 0x01},155	{0x05, {0x00}, 0x01},156	{0x06, {0x0f}, 0x01},157	{0x07, {0x10}, 0x01},158	{0x08, {0x00}, 0x01},159	{0x09, {0x00}, 0x01},160	{0x0a, {0x00}, 0x01},161	{0x0b, {0x00}, 0x01},162	{0x0c, {0x00}, 0x01},163	{0x0d, {0x13}, 0x01},164	{0x0e, {0x15}, 0x01},165	{0x0f, {0x17}, 0x01},166	{0x10, {0x01}, 0x01},167	{0x11, {0x0b}, 0x01},168	{0x12, {0x0c}, 0x01},169	{0x13, {0x09}, 0x01},170	{0x14, {0x0a}, 0x01},171	{0x15, {0x00}, 0x01},172	{0x16, {0x0f}, 0x01},173	{0x17, {0x10}, 0x01},174	{0x18, {0x00}, 0x01},175	{0x19, {0x00}, 0x01},176	{0x1a, {0x00}, 0x01},177	{0x1b, {0x00}, 0x01},178	{0x1c, {0x00}, 0x01},179	{0x1d, {0x13}, 0x01},180	{0x1e, {0x15}, 0x01},181	{0x1f, {0x17}, 0x01},182	{0x20, {0x00}, 0x01},183	{0x21, {0x03}, 0x01},184	{0x22, {0x01}, 0x01},185	{0x23, {0x40}, 0x01},186	{0x24, {0x40}, 0x01},187	{0x25, {0xed}, 0x01},188	{0x29, {0x58}, 0x01},189	{0x2a, {0x12}, 0x01},190	{0x2b, {0x01}, 0x01},191	{0x4b, {0x06}, 0x01},192	{0x4c, {0x11}, 0x01},193	{0x4d, {0x20}, 0x01},194	{0x4e, {0x02}, 0x01},195	{0x4f, {0x02}, 0x01},196	{0x50, {0x20}, 0x01},197	{0x51, {0x61}, 0x01},198	{0x52, {0x01}, 0x01},199	{0x53, {0x63}, 0x01},200	{0x54, {0x77}, 0x01},201	{0x55, {0xed}, 0x01},202	{0x5b, {0x00}, 0x01},203	{0x5c, {0x00}, 0x01},204	{0x5d, {0x00}, 0x01},205	{0x5e, {0x00}, 0x01},206	{0x5f, {0x15}, 0x01},207	{0x60, {0x75}, 0x01},208	{0x61, {0x00}, 0x01},209	{0x62, {0x00}, 0x01},210	{0x63, {0x00}, 0x01},211	{0x64, {0x00}, 0x01},212	{0x65, {0x00}, 0x01},213	{0x66, {0x00}, 0x01},214	{0x67, {0x00}, 0x01},215	{0x68, {0x04}, 0x01},216	{0x69, {0x00}, 0x01},217	{0x6a, {0x00}, 0x01},218	{0x6c, {0x40}, 0x01},219	{0x75, {0x01}, 0x01},220	{0x76, {0x01}, 0x01},221	{0x7a, {0x80}, 0x01},222	{0x7b, {0xa3}, 0x01},223	{0x7c, {0xd8}, 0x01},224	{0x7d, {0x60}, 0x01},225	{0x7f, {0x15}, 0x01},226	{0x80, {0x81}, 0x01},227	{0x83, {0x05}, 0x01},228	{0x93, {0x08}, 0x01},229	{0x94, {0x10}, 0x01},230	{0x8a, {0x00}, 0x01},231	{0x9b, {0x0f}, 0x01},232	{0xea, {0xff}, 0x01},233	{0xec, {0x00}, 0x01},234	/* Select CMD2 Page0 (Undocumented) */235	{0xff, {0x01}, 0x01},236	/* Reload CMD1: Don't reload default value to register */237	{0xfb, {0x01}, 0x01},238	{0x75, {0x00}, 0x01},239	{0x76, {0xdf}, 0x01},240	{0x77, {0x00}, 0x01},241	{0x78, {0xe4}, 0x01},242	{0x79, {0x00}, 0x01},243	{0x7a, {0xed}, 0x01},244	{0x7b, {0x00}, 0x01},245	{0x7c, {0xf6}, 0x01},246	{0x7d, {0x00}, 0x01},247	{0x7e, {0xff}, 0x01},248	{0x7f, {0x01}, 0x01},249	{0x80, {0x07}, 0x01},250	{0x81, {0x01}, 0x01},251	{0x82, {0x10}, 0x01},252	{0x83, {0x01}, 0x01},253	{0x84, {0x18}, 0x01},254	{0x85, {0x01}, 0x01},255	{0x86, {0x20}, 0x01},256	{0x87, {0x01}, 0x01},257	{0x88, {0x3d}, 0x01},258	{0x89, {0x01}, 0x01},259	{0x8a, {0x56}, 0x01},260	{0x8b, {0x01}, 0x01},261	{0x8c, {0x84}, 0x01},262	{0x8d, {0x01}, 0x01},263	{0x8e, {0xab}, 0x01},264	{0x8f, {0x01}, 0x01},265	{0x90, {0xec}, 0x01},266	{0x91, {0x02}, 0x01},267	{0x92, {0x22}, 0x01},268	{0x93, {0x02}, 0x01},269	{0x94, {0x23}, 0x01},270	{0x95, {0x02}, 0x01},271	{0x96, {0x55}, 0x01},272	{0x97, {0x02}, 0x01},273	{0x98, {0x8b}, 0x01},274	{0x99, {0x02}, 0x01},275	{0x9a, {0xaf}, 0x01},276	{0x9b, {0x02}, 0x01},277	{0x9c, {0xdf}, 0x01},278	{0x9d, {0x03}, 0x01},279	{0x9e, {0x01}, 0x01},280	{0x9f, {0x03}, 0x01},281	{0xa0, {0x2c}, 0x01},282	{0xa2, {0x03}, 0x01},283	{0xa3, {0x39}, 0x01},284	{0xa4, {0x03}, 0x01},285	{0xa5, {0x47}, 0x01},286	{0xa6, {0x03}, 0x01},287	{0xa7, {0x56}, 0x01},288	{0xa9, {0x03}, 0x01},289	{0xaa, {0x66}, 0x01},290	{0xab, {0x03}, 0x01},291	{0xac, {0x76}, 0x01},292	{0xad, {0x03}, 0x01},293	{0xae, {0x85}, 0x01},294	{0xaf, {0x03}, 0x01},295	{0xb0, {0x90}, 0x01},296	{0xb1, {0x03}, 0x01},297	{0xb2, {0xcb}, 0x01},298	{0xb3, {0x00}, 0x01},299	{0xb4, {0xdf}, 0x01},300	{0xb5, {0x00}, 0x01},301	{0xb6, {0xe4}, 0x01},302	{0xb7, {0x00}, 0x01},303	{0xb8, {0xed}, 0x01},304	{0xb9, {0x00}, 0x01},305	{0xba, {0xf6}, 0x01},306	{0xbb, {0x00}, 0x01},307	{0xbc, {0xff}, 0x01},308	{0xbd, {0x01}, 0x01},309	{0xbe, {0x07}, 0x01},310	{0xbf, {0x01}, 0x01},311	{0xc0, {0x10}, 0x01},312	{0xc1, {0x01}, 0x01},313	{0xc2, {0x18}, 0x01},314	{0xc3, {0x01}, 0x01},315	{0xc4, {0x20}, 0x01},316	{0xc5, {0x01}, 0x01},317	{0xc6, {0x3d}, 0x01},318	{0xc7, {0x01}, 0x01},319	{0xc8, {0x56}, 0x01},320	{0xc9, {0x01}, 0x01},321	{0xca, {0x84}, 0x01},322	{0xcb, {0x01}, 0x01},323	{0xcc, {0xab}, 0x01},324	{0xcd, {0x01}, 0x01},325	{0xce, {0xec}, 0x01},326	{0xcf, {0x02}, 0x01},327	{0xd0, {0x22}, 0x01},328	{0xd1, {0x02}, 0x01},329	{0xd2, {0x23}, 0x01},330	{0xd3, {0x02}, 0x01},331	{0xd4, {0x55}, 0x01},332	{0xd5, {0x02}, 0x01},333	{0xd6, {0x8b}, 0x01},334	{0xd7, {0x02}, 0x01},335	{0xd8, {0xaf}, 0x01},336	{0xd9, {0x02}, 0x01},337	{0xda, {0xdf}, 0x01},338	{0xdb, {0x03}, 0x01},339	{0xdc, {0x01}, 0x01},340	{0xdd, {0x03}, 0x01},341	{0xde, {0x2c}, 0x01},342	{0xdf, {0x03}, 0x01},343	{0xe0, {0x39}, 0x01},344	{0xe1, {0x03}, 0x01},345	{0xe2, {0x47}, 0x01},346	{0xe3, {0x03}, 0x01},347	{0xe4, {0x56}, 0x01},348	{0xe5, {0x03}, 0x01},349	{0xe6, {0x66}, 0x01},350	{0xe7, {0x03}, 0x01},351	{0xe8, {0x76}, 0x01},352	{0xe9, {0x03}, 0x01},353	{0xea, {0x85}, 0x01},354	{0xeb, {0x03}, 0x01},355	{0xec, {0x90}, 0x01},356	{0xed, {0x03}, 0x01},357	{0xee, {0xcb}, 0x01},358	{0xef, {0x00}, 0x01},359	{0xf0, {0xbb}, 0x01},360	{0xf1, {0x00}, 0x01},361	{0xf2, {0xc0}, 0x01},362	{0xf3, {0x00}, 0x01},363	{0xf4, {0xcc}, 0x01},364	{0xf5, {0x00}, 0x01},365	{0xf6, {0xd6}, 0x01},366	{0xf7, {0x00}, 0x01},367	{0xf8, {0xe1}, 0x01},368	{0xf9, {0x00}, 0x01},369	{0xfa, {0xea}, 0x01},370	/* Select CMD2 Page2 (Undocumented) */371	{0xff, {0x02}, 0x01},372	/* Reload CMD1: Don't reload default value to register */373	{0xfb, {0x01}, 0x01},374	{0x00, {0x00}, 0x01},375	{0x01, {0xf4}, 0x01},376	{0x02, {0x00}, 0x01},377	{0x03, {0xef}, 0x01},378	{0x04, {0x01}, 0x01},379	{0x05, {0x07}, 0x01},380	{0x06, {0x01}, 0x01},381	{0x07, {0x28}, 0x01},382	{0x08, {0x01}, 0x01},383	{0x09, {0x44}, 0x01},384	{0x0a, {0x01}, 0x01},385	{0x0b, {0x76}, 0x01},386	{0x0c, {0x01}, 0x01},387	{0x0d, {0xa0}, 0x01},388	{0x0e, {0x01}, 0x01},389	{0x0f, {0xe7}, 0x01},390	{0x10, {0x02}, 0x01},391	{0x11, {0x1f}, 0x01},392	{0x12, {0x02}, 0x01},393	{0x13, {0x22}, 0x01},394	{0x14, {0x02}, 0x01},395	{0x15, {0x54}, 0x01},396	{0x16, {0x02}, 0x01},397	{0x17, {0x8b}, 0x01},398	{0x18, {0x02}, 0x01},399	{0x19, {0xaf}, 0x01},400	{0x1a, {0x02}, 0x01},401	{0x1b, {0xe0}, 0x01},402	{0x1c, {0x03}, 0x01},403	{0x1d, {0x01}, 0x01},404	{0x1e, {0x03}, 0x01},405	{0x1f, {0x2d}, 0x01},406	{0x20, {0x03}, 0x01},407	{0x21, {0x39}, 0x01},408	{0x22, {0x03}, 0x01},409	{0x23, {0x47}, 0x01},410	{0x24, {0x03}, 0x01},411	{0x25, {0x57}, 0x01},412	{0x26, {0x03}, 0x01},413	{0x27, {0x65}, 0x01},414	{0x28, {0x03}, 0x01},415	{0x29, {0x77}, 0x01},416	{0x2a, {0x03}, 0x01},417	{0x2b, {0x85}, 0x01},418	{0x2d, {0x03}, 0x01},419	{0x2f, {0x8f}, 0x01},420	{0x30, {0x03}, 0x01},421	{0x31, {0xcb}, 0x01},422	{0x32, {0x00}, 0x01},423	{0x33, {0xbb}, 0x01},424	{0x34, {0x00}, 0x01},425	{0x35, {0xc0}, 0x01},426	{0x36, {0x00}, 0x01},427	{0x37, {0xcc}, 0x01},428	{0x38, {0x00}, 0x01},429	{0x39, {0xd6}, 0x01},430	{0x3a, {0x00}, 0x01},431	{0x3b, {0xe1}, 0x01},432	{0x3d, {0x00}, 0x01},433	{0x3f, {0xea}, 0x01},434	{0x40, {0x00}, 0x01},435	{0x41, {0xf4}, 0x01},436	{0x42, {0x00}, 0x01},437	{0x43, {0xfe}, 0x01},438	{0x44, {0x01}, 0x01},439	{0x45, {0x07}, 0x01},440	{0x46, {0x01}, 0x01},441	{0x47, {0x28}, 0x01},442	{0x48, {0x01}, 0x01},443	{0x49, {0x44}, 0x01},444	{0x4a, {0x01}, 0x01},445	{0x4b, {0x76}, 0x01},446	{0x4c, {0x01}, 0x01},447	{0x4d, {0xa0}, 0x01},448	{0x4e, {0x01}, 0x01},449	{0x4f, {0xe7}, 0x01},450	{0x50, {0x02}, 0x01},451	{0x51, {0x1f}, 0x01},452	{0x52, {0x02}, 0x01},453	{0x53, {0x22}, 0x01},454	{0x54, {0x02}, 0x01},455	{0x55, {0x54}, 0x01},456	{0x56, {0x02}, 0x01},457	{0x58, {0x8b}, 0x01},458	{0x59, {0x02}, 0x01},459	{0x5a, {0xaf}, 0x01},460	{0x5b, {0x02}, 0x01},461	{0x5c, {0xe0}, 0x01},462	{0x5d, {0x03}, 0x01},463	{0x5e, {0x01}, 0x01},464	{0x5f, {0x03}, 0x01},465	{0x60, {0x2d}, 0x01},466	{0x61, {0x03}, 0x01},467	{0x62, {0x39}, 0x01},468	{0x63, {0x03}, 0x01},469	{0x64, {0x47}, 0x01},470	{0x65, {0x03}, 0x01},471	{0x66, {0x57}, 0x01},472	{0x67, {0x03}, 0x01},473	{0x68, {0x65}, 0x01},474	{0x69, {0x03}, 0x01},475	{0x6a, {0x77}, 0x01},476	{0x6b, {0x03}, 0x01},477	{0x6c, {0x85}, 0x01},478	{0x6d, {0x03}, 0x01},479	{0x6e, {0x8f}, 0x01},480	{0x6f, {0x03}, 0x01},481	{0x70, {0xcb}, 0x01},482	{0x71, {0x00}, 0x01},483	{0x72, {0x00}, 0x01},484	{0x73, {0x00}, 0x01},485	{0x74, {0x21}, 0x01},486	{0x75, {0x00}, 0x01},487	{0x76, {0x4c}, 0x01},488	{0x77, {0x00}, 0x01},489	{0x78, {0x6b}, 0x01},490	{0x79, {0x00}, 0x01},491	{0x7a, {0x85}, 0x01},492	{0x7b, {0x00}, 0x01},493	{0x7c, {0x9a}, 0x01},494	{0x7d, {0x00}, 0x01},495	{0x7e, {0xad}, 0x01},496	{0x7f, {0x00}, 0x01},497	{0x80, {0xbe}, 0x01},498	{0x81, {0x00}, 0x01},499	{0x82, {0xcd}, 0x01},500	{0x83, {0x01}, 0x01},501	{0x84, {0x01}, 0x01},502	{0x85, {0x01}, 0x01},503	{0x86, {0x29}, 0x01},504	{0x87, {0x01}, 0x01},505	{0x88, {0x68}, 0x01},506	{0x89, {0x01}, 0x01},507	{0x8a, {0x98}, 0x01},508	{0x8b, {0x01}, 0x01},509	{0x8c, {0xe5}, 0x01},510	{0x8d, {0x02}, 0x01},511	{0x8e, {0x1e}, 0x01},512	{0x8f, {0x02}, 0x01},513	{0x90, {0x30}, 0x01},514	{0x91, {0x02}, 0x01},515	{0x92, {0x52}, 0x01},516	{0x93, {0x02}, 0x01},517	{0x94, {0x88}, 0x01},518	{0x95, {0x02}, 0x01},519	{0x96, {0xaa}, 0x01},520	{0x97, {0x02}, 0x01},521	{0x98, {0xd7}, 0x01},522	{0x99, {0x02}, 0x01},523	{0x9a, {0xf7}, 0x01},524	{0x9b, {0x03}, 0x01},525	{0x9c, {0x21}, 0x01},526	{0x9d, {0x03}, 0x01},527	{0x9e, {0x2e}, 0x01},528	{0x9f, {0x03}, 0x01},529	{0xa0, {0x3d}, 0x01},530	{0xa2, {0x03}, 0x01},531	{0xa3, {0x4c}, 0x01},532	{0xa4, {0x03}, 0x01},533	{0xa5, {0x5e}, 0x01},534	{0xa6, {0x03}, 0x01},535	{0xa7, {0x71}, 0x01},536	{0xa9, {0x03}, 0x01},537	{0xaa, {0x86}, 0x01},538	{0xab, {0x03}, 0x01},539	{0xac, {0x94}, 0x01},540	{0xad, {0x03}, 0x01},541	{0xae, {0xfa}, 0x01},542	{0xaf, {0x00}, 0x01},543	{0xb0, {0x00}, 0x01},544	{0xb1, {0x00}, 0x01},545	{0xb2, {0x21}, 0x01},546	{0xb3, {0x00}, 0x01},547	{0xb4, {0x4c}, 0x01},548	{0xb5, {0x00}, 0x01},549	{0xb6, {0x6b}, 0x01},550	{0xb7, {0x00}, 0x01},551	{0xb8, {0x85}, 0x01},552	{0xb9, {0x00}, 0x01},553	{0xba, {0x9a}, 0x01},554	{0xbb, {0x00}, 0x01},555	{0xbc, {0xad}, 0x01},556	{0xbd, {0x00}, 0x01},557	{0xbe, {0xbe}, 0x01},558	{0xbf, {0x00}, 0x01},559	{0xc0, {0xcd}, 0x01},560	{0xc1, {0x01}, 0x01},561	{0xc2, {0x01}, 0x01},562	{0xc3, {0x01}, 0x01},563	{0xc4, {0x29}, 0x01},564	{0xc5, {0x01}, 0x01},565	{0xc6, {0x68}, 0x01},566	{0xc7, {0x01}, 0x01},567	{0xc8, {0x98}, 0x01},568	{0xc9, {0x01}, 0x01},569	{0xca, {0xe5}, 0x01},570	{0xcb, {0x02}, 0x01},571	{0xcc, {0x1e}, 0x01},572	{0xcd, {0x02}, 0x01},573	{0xce, {0x20}, 0x01},574	{0xcf, {0x02}, 0x01},575	{0xd0, {0x52}, 0x01},576	{0xd1, {0x02}, 0x01},577	{0xd2, {0x88}, 0x01},578	{0xd3, {0x02}, 0x01},579	{0xd4, {0xaa}, 0x01},580	{0xd5, {0x02}, 0x01},581	{0xd6, {0xd7}, 0x01},582	{0xd7, {0x02}, 0x01},583	{0xd8, {0xf7}, 0x01},584	{0xd9, {0x03}, 0x01},585	{0xda, {0x21}, 0x01},586	{0xdb, {0x03}, 0x01},587	{0xdc, {0x2e}, 0x01},588	{0xdd, {0x03}, 0x01},589	{0xde, {0x3d}, 0x01},590	{0xdf, {0x03}, 0x01},591	{0xe0, {0x4c}, 0x01},592	{0xe1, {0x03}, 0x01},593	{0xe2, {0x5e}, 0x01},594	{0xe3, {0x03}, 0x01},595	{0xe4, {0x71}, 0x01},596	{0xe5, {0x03}, 0x01},597	{0xe6, {0x86}, 0x01},598	{0xe7, {0x03}, 0x01},599	{0xe8, {0x94}, 0x01},600	{0xe9, {0x03}, 0x01},601	{0xea, {0xfa}, 0x01},602	/* Select CMD2 Page0 (Undocumented) */603	{0xff, {0x01}, 0x01},604	/* Reload CMD1: Don't reload default value to register */605	{0xfb, {0x01}, 0x01},606	/* Select CMD2 Page1 (Undocumented) */607	{0xff, {0x02}, 0x01},608	/* Reload CMD1: Don't reload default value to register */609	{0xfb, {0x01}, 0x01},610	/* Select CMD2 Page3 (Undocumented) */611	{0xff, {0x04}, 0x01},612	/* Reload CMD1: Don't reload default value to register */613	{0xfb, {0x01}, 0x01},614	/* Select CMD1 */615	{0xff, {0x00}, 0x01},616	{0xd3, {0x22}, 0x01}, /* RGBMIPICTRL: VSYNC back porch = 34 */617	{0xd4, {0x04}, 0x01}, /* RGBMIPICTRL: VSYNC front porch = 4 */618};619 620struct khadas_ts050_panel_data ts050_panel_data = {621	.init_code = (struct khadas_ts050_panel_cmd *)ts050_init_code,622	.len = ARRAY_SIZE(ts050_init_code)623};624 625struct khadas_ts050_panel_data ts050v2_panel_data = {626	.init_code = (struct khadas_ts050_panel_cmd *)ts050v2_init_code,627	.len = ARRAY_SIZE(ts050v2_init_code)628};629 630static inline631struct khadas_ts050_panel *to_khadas_ts050_panel(struct drm_panel *panel)632{633	return container_of(panel, struct khadas_ts050_panel, base);634}635 636static int khadas_ts050_panel_prepare(struct drm_panel *panel)637{638	struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);639	unsigned int i;640	int err;641 642	gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 0);643 644	err = regulator_enable(khadas_ts050->supply);645	if (err < 0)646		return err;647 648	gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 1);649 650	msleep(60);651 652	gpiod_set_value_cansleep(khadas_ts050->reset_gpio, 1);653 654	usleep_range(10000, 11000);655 656	gpiod_set_value_cansleep(khadas_ts050->reset_gpio, 0);657 658	/* Select CMD2 page 4 (Undocumented) */659	mipi_dsi_dcs_write(khadas_ts050->link, 0xff, (u8[]){ 0x05 }, 1);660 661	/* Reload CMD1: Don't reload default value to register */662	mipi_dsi_dcs_write(khadas_ts050->link, 0xfb, (u8[]){ 0x01 }, 1);663 664	mipi_dsi_dcs_write(khadas_ts050->link, 0xc5, (u8[]){ 0x01 }, 1);665 666	msleep(100);667 668	for (i = 0; i < khadas_ts050->panel_data->len; i++) {669		err = mipi_dsi_dcs_write(khadas_ts050->link,670						khadas_ts050->panel_data->init_code[i].cmd,671						&khadas_ts050->panel_data->init_code[i].data,672						khadas_ts050->panel_data->init_code[i].size);673		if (err < 0) {674			dev_err(panel->dev, "failed write cmds: %d\n", err);675			goto poweroff;676		}677	}678 679	err = mipi_dsi_dcs_exit_sleep_mode(khadas_ts050->link);680	if (err < 0) {681		dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);682		goto poweroff;683	}684 685	msleep(120);686 687	/* Select CMD1 */688	mipi_dsi_dcs_write(khadas_ts050->link, 0xff, (u8[]){ 0x00 }, 1);689 690	err = mipi_dsi_dcs_set_tear_on(khadas_ts050->link,691				       MIPI_DSI_DCS_TEAR_MODE_VBLANK);692	if (err < 0) {693		dev_err(panel->dev, "failed to set tear on: %d\n", err);694		goto poweroff;695	}696 697	err = mipi_dsi_dcs_set_display_on(khadas_ts050->link);698	if (err < 0) {699		dev_err(panel->dev, "failed to set display on: %d\n", err);700		goto poweroff;701	}702 703	usleep_range(10000, 11000);704 705	return 0;706 707poweroff:708	gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 0);709	gpiod_set_value_cansleep(khadas_ts050->reset_gpio, 1);710 711	regulator_disable(khadas_ts050->supply);712 713	return err;714}715 716static int khadas_ts050_panel_unprepare(struct drm_panel *panel)717{718	struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);719	int err;720 721	err = mipi_dsi_dcs_enter_sleep_mode(khadas_ts050->link);722	if (err < 0)723		dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);724 725	msleep(150);726 727	gpiod_set_value_cansleep(khadas_ts050->enable_gpio, 0);728	gpiod_set_value_cansleep(khadas_ts050->reset_gpio, 1);729 730	err = regulator_disable(khadas_ts050->supply);731	if (err < 0)732		return err;733 734	return 0;735}736 737static int khadas_ts050_panel_disable(struct drm_panel *panel)738{739	struct khadas_ts050_panel *khadas_ts050 = to_khadas_ts050_panel(panel);740	int err;741 742	err = mipi_dsi_dcs_set_display_off(khadas_ts050->link);743	if (err < 0)744		dev_err(panel->dev, "failed to set display off: %d\n", err);745 746	usleep_range(10000, 11000);747 748	return 0;749}750 751static const struct drm_display_mode default_mode = {752	.clock = 160000,753	.hdisplay = 1080,754	.hsync_start = 1080 + 117,755	.hsync_end = 1080 + 117 + 5,756	.htotal = 1080 + 117 + 5 + 160,757	.vdisplay = 1920,758	.vsync_start = 1920 + 4,759	.vsync_end = 1920 + 4 + 3,760	.vtotal = 1920 + 4 + 3 + 31,761	.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,762};763 764static int khadas_ts050_panel_get_modes(struct drm_panel *panel,765					struct drm_connector *connector)766{767	struct drm_display_mode *mode;768 769	mode = drm_mode_duplicate(connector->dev, &default_mode);770	if (!mode) {771		dev_err(panel->dev, "failed to add mode %ux%u@%u\n",772			default_mode.hdisplay, default_mode.vdisplay,773			drm_mode_vrefresh(&default_mode));774		return -ENOMEM;775	}776 777	drm_mode_set_name(mode);778 779	drm_mode_probed_add(connector, mode);780 781	connector->display_info.width_mm = 64;782	connector->display_info.height_mm = 118;783	connector->display_info.bpc = 8;784 785	return 1;786}787 788static const struct drm_panel_funcs khadas_ts050_panel_funcs = {789	.prepare = khadas_ts050_panel_prepare,790	.unprepare = khadas_ts050_panel_unprepare,791	.disable = khadas_ts050_panel_disable,792	.get_modes = khadas_ts050_panel_get_modes,793};794 795static const struct of_device_id khadas_ts050_of_match[] = {796	{ .compatible = "khadas,ts050",    .data = &ts050_panel_data, },797	{ .compatible = "khadas,ts050v2",  .data = &ts050v2_panel_data, },798	{ /* sentinel */ }799};800MODULE_DEVICE_TABLE(of, khadas_ts050_of_match);801 802static int khadas_ts050_panel_add(struct khadas_ts050_panel *khadas_ts050)803{804	struct device *dev = &khadas_ts050->link->dev;805	int err;806 807	khadas_ts050->supply = devm_regulator_get(dev, "power");808	if (IS_ERR(khadas_ts050->supply))809		return dev_err_probe(dev, PTR_ERR(khadas_ts050->supply),810				     "failed to get power supply");811 812	khadas_ts050->reset_gpio = devm_gpiod_get(dev, "reset",813						  GPIOD_OUT_LOW);814	if (IS_ERR(khadas_ts050->reset_gpio))815		return dev_err_probe(dev, PTR_ERR(khadas_ts050->reset_gpio),816				     "failed to get reset gpio");817 818	khadas_ts050->enable_gpio = devm_gpiod_get(dev, "enable",819						   GPIOD_OUT_HIGH);820	if (IS_ERR(khadas_ts050->enable_gpio))821		return dev_err_probe(dev, PTR_ERR(khadas_ts050->enable_gpio),822				     "failed to get enable gpio");823 824	drm_panel_init(&khadas_ts050->base, &khadas_ts050->link->dev,825		       &khadas_ts050_panel_funcs, DRM_MODE_CONNECTOR_DSI);826 827	err = drm_panel_of_backlight(&khadas_ts050->base);828	if (err)829		return err;830 831	drm_panel_add(&khadas_ts050->base);832 833	return 0;834}835 836static int khadas_ts050_panel_probe(struct mipi_dsi_device *dsi)837{838	struct khadas_ts050_panel *khadas_ts050;839	int err;840 841	const void *data = of_device_get_match_data(&dsi->dev);842 843	if (!data) {844		dev_err(&dsi->dev, "No matching data\n");845		return -ENODEV;846	}847 848	dsi->lanes = 4;849	dsi->format = MIPI_DSI_FMT_RGB888;850	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |851			  MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET;852 853	khadas_ts050 = devm_kzalloc(&dsi->dev, sizeof(*khadas_ts050),854				    GFP_KERNEL);855	if (!khadas_ts050)856		return -ENOMEM;857 858	khadas_ts050->panel_data = (struct khadas_ts050_panel_data *)data;859	mipi_dsi_set_drvdata(dsi, khadas_ts050);860	khadas_ts050->link = dsi;861 862	err = khadas_ts050_panel_add(khadas_ts050);863	if (err < 0)864		return err;865 866	err = mipi_dsi_attach(dsi);867	if (err)868		drm_panel_remove(&khadas_ts050->base);869 870	return err;871}872 873static void khadas_ts050_panel_remove(struct mipi_dsi_device *dsi)874{875	struct khadas_ts050_panel *khadas_ts050 = mipi_dsi_get_drvdata(dsi);876	int err;877 878	err = mipi_dsi_detach(dsi);879	if (err < 0)880		dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);881 882	drm_panel_remove(&khadas_ts050->base);883}884 885static struct mipi_dsi_driver khadas_ts050_panel_driver = {886	.driver = {887		.name = "panel-khadas-ts050",888		.of_match_table = khadas_ts050_of_match,889	},890	.probe = khadas_ts050_panel_probe,891	.remove = khadas_ts050_panel_remove,892};893module_mipi_dsi_driver(khadas_ts050_panel_driver);894 895MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");896MODULE_DESCRIPTION("Khadas TS050 panel driver");897MODULE_LICENSE("GPL v2");898