1/*
2 * linux/drivers/video/mmp/panel/tpo_tj032md01bw.c
3 * active panel using spi interface to do init
4 *
5 * Copyright (C) 2012 Marvell Technology Group Ltd.
6 * Authors:  Guoqing Li <ligq@marvell.com>
7 *          Lisa Du <cldu@marvell.com>
8 *          Zhou Zhu <zzhu3@marvell.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program.  If not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/kernel.h>
28#include <linux/errno.h>
29#include <linux/string.h>
30#include <linux/delay.h>
31#include <linux/platform_device.h>
32#include <linux/err.h>
33#include <linux/spi/spi.h>
34#include <video/mmp_disp.h>
35
36static u16 init[] = {
37	0x0801,
38	0x0800,
39	0x0200,
40	0x0304,
41	0x040e,
42	0x0903,
43	0x0b18,
44	0x0c53,
45	0x0d01,
46	0x0ee0,
47	0x0f01,
48	0x1058,
49	0x201e,
50	0x210a,
51	0x220a,
52	0x231e,
53	0x2400,
54	0x2532,
55	0x2600,
56	0x27ac,
57	0x2904,
58	0x2aa2,
59	0x2b45,
60	0x2c45,
61	0x2d15,
62	0x2e5a,
63	0x2fff,
64	0x306b,
65	0x310d,
66	0x3248,
67	0x3382,
68	0x34bd,
69	0x35e7,
70	0x3618,
71	0x3794,
72	0x3801,
73	0x395d,
74	0x3aae,
75	0x3bff,
76	0x07c9,
77};
78
79static u16 poweroff[] = {
80	0x07d9,
81};
82
83struct tpohvga_plat_data {
84	void (*plat_onoff)(int status);
85	struct spi_device *spi;
86};
87
88static void tpohvga_onoff(struct mmp_panel *panel, int status)
89{
90	struct tpohvga_plat_data *plat = panel->plat_data;
91	int ret;
92
93	if (status) {
94		plat->plat_onoff(1);
95
96		ret = spi_write(plat->spi, init, sizeof(init));
97		if (ret < 0)
98			dev_warn(panel->dev, "init cmd failed(%d)\n", ret);
99	} else {
100		ret = spi_write(plat->spi, poweroff, sizeof(poweroff));
101		if (ret < 0)
102			dev_warn(panel->dev, "poweroff cmd failed(%d)\n", ret);
103
104		plat->plat_onoff(0);
105	}
106}
107
108static struct mmp_mode mmp_modes_tpohvga[] = {
109	[0] = {
110		.pixclock_freq = 10394400,
111		.refresh = 60,
112		.xres = 320,
113		.yres = 480,
114		.hsync_len = 10,
115		.left_margin = 15,
116		.right_margin = 10,
117		.vsync_len = 2,
118		.upper_margin = 4,
119		.lower_margin = 2,
120		.invert_pixclock = 1,
121		.pix_fmt_out = PIXFMT_RGB565,
122	},
123};
124
125static int tpohvga_get_modelist(struct mmp_panel *panel,
126		struct mmp_mode **modelist)
127{
128	*modelist = mmp_modes_tpohvga;
129	return 1;
130}
131
132static struct mmp_panel panel_tpohvga = {
133	.name = "tpohvga",
134	.panel_type = PANELTYPE_ACTIVE,
135	.get_modelist = tpohvga_get_modelist,
136	.set_onoff = tpohvga_onoff,
137};
138
139static int tpohvga_probe(struct spi_device *spi)
140{
141	struct mmp_mach_panel_info *mi;
142	int ret;
143	struct tpohvga_plat_data *plat_data;
144
145	/* get configs from platform data */
146	mi = spi->dev.platform_data;
147	if (mi == NULL) {
148		dev_err(&spi->dev, "%s: no platform data defined\n", __func__);
149		return -EINVAL;
150	}
151
152	/* setup spi related info */
153	spi->bits_per_word = 16;
154	ret = spi_setup(spi);
155	if (ret < 0) {
156		dev_err(&spi->dev, "spi setup failed %d", ret);
157		return ret;
158	}
159
160	plat_data = kzalloc(sizeof(*plat_data), GFP_KERNEL);
161	if (plat_data == NULL)
162		return -ENOMEM;
163
164	plat_data->spi = spi;
165	plat_data->plat_onoff = mi->plat_set_onoff;
166	panel_tpohvga.plat_data = plat_data;
167	panel_tpohvga.plat_path_name = mi->plat_path_name;
168	panel_tpohvga.dev = &spi->dev;
169
170	mmp_register_panel(&panel_tpohvga);
171
172	return 0;
173}
174
175static struct spi_driver panel_tpohvga_driver = {
176	.driver		= {
177		.name	= "tpo-hvga",
178		.owner	= THIS_MODULE,
179	},
180	.probe		= tpohvga_probe,
181};
182module_spi_driver(panel_tpohvga_driver);
183
184MODULE_AUTHOR("Lisa Du<cldu@marvell.com>");
185MODULE_DESCRIPTION("Panel driver for tpohvga");
186MODULE_LICENSE("GPL");
187