xref: /linux/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c (revision 58e16d792a6a8c6b750f637a4649967fcac853dc)
1*1ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2f7018c21STomi Valkeinen /*
3f7018c21STomi Valkeinen  * linux/drivers/video/mmp/panel/tpo_tj032md01bw.c
4f7018c21STomi Valkeinen  * active panel using spi interface to do init
5f7018c21STomi Valkeinen  *
6f7018c21STomi Valkeinen  * Copyright (C) 2012 Marvell Technology Group Ltd.
7f7018c21STomi Valkeinen  * Authors:  Guoqing Li <ligq@marvell.com>
8f7018c21STomi Valkeinen  *          Lisa Du <cldu@marvell.com>
9f7018c21STomi Valkeinen  *          Zhou Zhu <zzhu3@marvell.com>
10f7018c21STomi Valkeinen  */
11f7018c21STomi Valkeinen 
12f7018c21STomi Valkeinen #include <linux/module.h>
13f7018c21STomi Valkeinen #include <linux/moduleparam.h>
14f7018c21STomi Valkeinen #include <linux/kernel.h>
15f7018c21STomi Valkeinen #include <linux/errno.h>
16f7018c21STomi Valkeinen #include <linux/string.h>
17f7018c21STomi Valkeinen #include <linux/delay.h>
18f7018c21STomi Valkeinen #include <linux/platform_device.h>
19f7018c21STomi Valkeinen #include <linux/err.h>
20f7018c21STomi Valkeinen #include <linux/spi/spi.h>
21f7018c21STomi Valkeinen #include <video/mmp_disp.h>
22f7018c21STomi Valkeinen 
23f7018c21STomi Valkeinen static u16 init[] = {
24f7018c21STomi Valkeinen 	0x0801,
25f7018c21STomi Valkeinen 	0x0800,
26f7018c21STomi Valkeinen 	0x0200,
27f7018c21STomi Valkeinen 	0x0304,
28f7018c21STomi Valkeinen 	0x040e,
29f7018c21STomi Valkeinen 	0x0903,
30f7018c21STomi Valkeinen 	0x0b18,
31f7018c21STomi Valkeinen 	0x0c53,
32f7018c21STomi Valkeinen 	0x0d01,
33f7018c21STomi Valkeinen 	0x0ee0,
34f7018c21STomi Valkeinen 	0x0f01,
35f7018c21STomi Valkeinen 	0x1058,
36f7018c21STomi Valkeinen 	0x201e,
37f7018c21STomi Valkeinen 	0x210a,
38f7018c21STomi Valkeinen 	0x220a,
39f7018c21STomi Valkeinen 	0x231e,
40f7018c21STomi Valkeinen 	0x2400,
41f7018c21STomi Valkeinen 	0x2532,
42f7018c21STomi Valkeinen 	0x2600,
43f7018c21STomi Valkeinen 	0x27ac,
44f7018c21STomi Valkeinen 	0x2904,
45f7018c21STomi Valkeinen 	0x2aa2,
46f7018c21STomi Valkeinen 	0x2b45,
47f7018c21STomi Valkeinen 	0x2c45,
48f7018c21STomi Valkeinen 	0x2d15,
49f7018c21STomi Valkeinen 	0x2e5a,
50f7018c21STomi Valkeinen 	0x2fff,
51f7018c21STomi Valkeinen 	0x306b,
52f7018c21STomi Valkeinen 	0x310d,
53f7018c21STomi Valkeinen 	0x3248,
54f7018c21STomi Valkeinen 	0x3382,
55f7018c21STomi Valkeinen 	0x34bd,
56f7018c21STomi Valkeinen 	0x35e7,
57f7018c21STomi Valkeinen 	0x3618,
58f7018c21STomi Valkeinen 	0x3794,
59f7018c21STomi Valkeinen 	0x3801,
60f7018c21STomi Valkeinen 	0x395d,
61f7018c21STomi Valkeinen 	0x3aae,
62f7018c21STomi Valkeinen 	0x3bff,
63f7018c21STomi Valkeinen 	0x07c9,
64f7018c21STomi Valkeinen };
65f7018c21STomi Valkeinen 
66f7018c21STomi Valkeinen static u16 poweroff[] = {
67f7018c21STomi Valkeinen 	0x07d9,
68f7018c21STomi Valkeinen };
69f7018c21STomi Valkeinen 
70f7018c21STomi Valkeinen struct tpohvga_plat_data {
71f7018c21STomi Valkeinen 	void (*plat_onoff)(int status);
72f7018c21STomi Valkeinen 	struct spi_device *spi;
73f7018c21STomi Valkeinen };
74f7018c21STomi Valkeinen 
tpohvga_onoff(struct mmp_panel * panel,int status)75f7018c21STomi Valkeinen static void tpohvga_onoff(struct mmp_panel *panel, int status)
76f7018c21STomi Valkeinen {
77f7018c21STomi Valkeinen 	struct tpohvga_plat_data *plat = panel->plat_data;
78f7018c21STomi Valkeinen 	int ret;
79f7018c21STomi Valkeinen 
80f7018c21STomi Valkeinen 	if (status) {
81f7018c21STomi Valkeinen 		plat->plat_onoff(1);
82f7018c21STomi Valkeinen 
83f7018c21STomi Valkeinen 		ret = spi_write(plat->spi, init, sizeof(init));
84f7018c21STomi Valkeinen 		if (ret < 0)
85f7018c21STomi Valkeinen 			dev_warn(panel->dev, "init cmd failed(%d)\n", ret);
86f7018c21STomi Valkeinen 	} else {
87f7018c21STomi Valkeinen 		ret = spi_write(plat->spi, poweroff, sizeof(poweroff));
88f7018c21STomi Valkeinen 		if (ret < 0)
89f7018c21STomi Valkeinen 			dev_warn(panel->dev, "poweroff cmd failed(%d)\n", ret);
90f7018c21STomi Valkeinen 
91f7018c21STomi Valkeinen 		plat->plat_onoff(0);
92f7018c21STomi Valkeinen 	}
93f7018c21STomi Valkeinen }
94f7018c21STomi Valkeinen 
95f7018c21STomi Valkeinen static struct mmp_mode mmp_modes_tpohvga[] = {
96f7018c21STomi Valkeinen 	[0] = {
97f7018c21STomi Valkeinen 		.pixclock_freq = 10394400,
98f7018c21STomi Valkeinen 		.refresh = 60,
99f7018c21STomi Valkeinen 		.xres = 320,
100f7018c21STomi Valkeinen 		.yres = 480,
101f7018c21STomi Valkeinen 		.hsync_len = 10,
102f7018c21STomi Valkeinen 		.left_margin = 15,
103f7018c21STomi Valkeinen 		.right_margin = 10,
104f7018c21STomi Valkeinen 		.vsync_len = 2,
105f7018c21STomi Valkeinen 		.upper_margin = 4,
106f7018c21STomi Valkeinen 		.lower_margin = 2,
107f7018c21STomi Valkeinen 		.invert_pixclock = 1,
108f7018c21STomi Valkeinen 		.pix_fmt_out = PIXFMT_RGB565,
109f7018c21STomi Valkeinen 	},
110f7018c21STomi Valkeinen };
111f7018c21STomi Valkeinen 
tpohvga_get_modelist(struct mmp_panel * panel,struct mmp_mode ** modelist)112f7018c21STomi Valkeinen static int tpohvga_get_modelist(struct mmp_panel *panel,
113f7018c21STomi Valkeinen 		struct mmp_mode **modelist)
114f7018c21STomi Valkeinen {
115f7018c21STomi Valkeinen 	*modelist = mmp_modes_tpohvga;
116f7018c21STomi Valkeinen 	return 1;
117f7018c21STomi Valkeinen }
118f7018c21STomi Valkeinen 
119f7018c21STomi Valkeinen static struct mmp_panel panel_tpohvga = {
120f7018c21STomi Valkeinen 	.name = "tpohvga",
121f7018c21STomi Valkeinen 	.panel_type = PANELTYPE_ACTIVE,
122f7018c21STomi Valkeinen 	.get_modelist = tpohvga_get_modelist,
123f7018c21STomi Valkeinen 	.set_onoff = tpohvga_onoff,
124f7018c21STomi Valkeinen };
125f7018c21STomi Valkeinen 
tpohvga_probe(struct spi_device * spi)126f7018c21STomi Valkeinen static int tpohvga_probe(struct spi_device *spi)
127f7018c21STomi Valkeinen {
128f7018c21STomi Valkeinen 	struct mmp_mach_panel_info *mi;
129f7018c21STomi Valkeinen 	int ret;
130f7018c21STomi Valkeinen 	struct tpohvga_plat_data *plat_data;
131f7018c21STomi Valkeinen 
132f7018c21STomi Valkeinen 	/* get configs from platform data */
133f7018c21STomi Valkeinen 	mi = spi->dev.platform_data;
134f7018c21STomi Valkeinen 	if (mi == NULL) {
135f7018c21STomi Valkeinen 		dev_err(&spi->dev, "%s: no platform data defined\n", __func__);
136f7018c21STomi Valkeinen 		return -EINVAL;
137f7018c21STomi Valkeinen 	}
138f7018c21STomi Valkeinen 
139f7018c21STomi Valkeinen 	/* setup spi related info */
140f7018c21STomi Valkeinen 	spi->bits_per_word = 16;
141f7018c21STomi Valkeinen 	ret = spi_setup(spi);
142f7018c21STomi Valkeinen 	if (ret < 0) {
143f7018c21STomi Valkeinen 		dev_err(&spi->dev, "spi setup failed %d", ret);
144f7018c21STomi Valkeinen 		return ret;
145f7018c21STomi Valkeinen 	}
146f7018c21STomi Valkeinen 
147f7018c21STomi Valkeinen 	plat_data = kzalloc(sizeof(*plat_data), GFP_KERNEL);
148f7018c21STomi Valkeinen 	if (plat_data == NULL)
149f7018c21STomi Valkeinen 		return -ENOMEM;
150f7018c21STomi Valkeinen 
151f7018c21STomi Valkeinen 	plat_data->spi = spi;
152f7018c21STomi Valkeinen 	plat_data->plat_onoff = mi->plat_set_onoff;
153f7018c21STomi Valkeinen 	panel_tpohvga.plat_data = plat_data;
154f7018c21STomi Valkeinen 	panel_tpohvga.plat_path_name = mi->plat_path_name;
155f7018c21STomi Valkeinen 	panel_tpohvga.dev = &spi->dev;
156f7018c21STomi Valkeinen 
157f7018c21STomi Valkeinen 	mmp_register_panel(&panel_tpohvga);
158f7018c21STomi Valkeinen 
159f7018c21STomi Valkeinen 	return 0;
160f7018c21STomi Valkeinen }
161f7018c21STomi Valkeinen 
162f7018c21STomi Valkeinen static struct spi_driver panel_tpohvga_driver = {
163f7018c21STomi Valkeinen 	.driver		= {
164f7018c21STomi Valkeinen 		.name	= "tpo-hvga",
165f7018c21STomi Valkeinen 	},
166f7018c21STomi Valkeinen 	.probe		= tpohvga_probe,
167f7018c21STomi Valkeinen };
168f7018c21STomi Valkeinen module_spi_driver(panel_tpohvga_driver);
169f7018c21STomi Valkeinen 
170f7018c21STomi Valkeinen MODULE_AUTHOR("Lisa Du<cldu@marvell.com>");
171f7018c21STomi Valkeinen MODULE_DESCRIPTION("Panel driver for tpohvga");
172f7018c21STomi Valkeinen MODULE_LICENSE("GPL");
173