gxlcd.c revision 1.6
1/*	$NetBSD: gxlcd.c,v 1.6 2023/12/20 13:55:17 thorpej Exp $	*/
2
3/*
4 * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
5 * Written by Hiroyuki Bessho for Genetec Corporation.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of Genetec Corporation may not be used to endorse or
16 *    promote products derived from this software without specific prior
17 *    written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * LCD driver for Gumstix consoleLCD-vx and compatible.
34 * (based on the Intel Lubbock driver).
35 *
36 * Controlling LCD is almost completely done through PXA2X0's
37 * integrated LCD controller.  Codes for it is arm/xscale/pxa2x0_lcd.c.
38 *
39 * Codes in this file provide platform specific things including:
40 *   LCD on/off switch and backlight
41 *   LCD panel geometry
42 */
43
44#include <sys/cdefs.h>
45__KERNEL_RCSID(0, "$NetBSD: gxlcd.c,v 1.6 2023/12/20 13:55:17 thorpej Exp $");
46
47#include <sys/param.h>
48#include <sys/systm.h>
49#include <sys/conf.h>
50#include <sys/uio.h>
51
52#include <dev/cons.h>
53#include <dev/wscons/wsconsio.h>
54#include <dev/wscons/wsdisplayvar.h>
55#include <dev/wscons/wscons_callbacks.h>
56
57#include <sys/bus.h>
58
59#include <arm/xscale/pxa2x0var.h>
60#include <arm/xscale/pxa2x0reg.h>
61#include <arm/xscale/pxa2x0_lcd.h>
62#include <arm/xscale/pxa2x0_gpio.h>
63
64
65#ifndef CURRENT_DISPLAY
66#define CURRENT_DISPLAY samsung_lte430wq_f0c
67#endif
68
69
70static int gxlcd_match(device_t, cfdata_t, void *);
71static void gxlcd_attach(device_t, device_t, void *);
72
73void gxlcd_cnattach(void);
74
75static int gxlcd_ioctl(void *, void *, u_long, void *, int, struct lwp *);
76static int gxlcd_show_screen(void *, void *, int,
77			     void (*)(void *, int, int), void *);
78
79
80/*
81 * wsdisplay glue
82 */
83static struct pxa2x0_wsscreen_descr gxlcd_std_screen = {
84	.c = {
85		.name = "std",
86		.textops = &pxa2x0_lcd_emulops,
87		.fontwidth = 8,
88		.fontheight = 16,
89		.capabilities = WSSCREEN_WSCOLORS,
90	},
91	.depth = 16,			/* bits per pixel */
92};
93
94static const struct wsscreen_descr *gxlcd_scr_descr[] = {
95	&gxlcd_std_screen.c
96};
97
98static const struct wsscreen_list gxlcd_screen_list = {
99	.nscreens = __arraycount(gxlcd_scr_descr),
100	.screens = gxlcd_scr_descr,
101};
102
103struct wsdisplay_accessops gxlcd_accessops = {
104	gxlcd_ioctl,
105	pxa2x0_lcd_mmap,
106	pxa2x0_lcd_alloc_screen,
107	pxa2x0_lcd_free_screen,
108	gxlcd_show_screen,
109	NULL,
110	NULL,
111	NULL,
112};
113
114const struct lcd_panel_geometry samsung_lte430wq_f0c =
115{
116	480,			/* Width */
117	272,			/* Height */
118	0,			/* No extra lines */
119
120	LCDPANEL_ACTIVE | LCDPANEL_PCP,
121	1,			/* clock divider */
122	0,			/* AC bias pin freq */
123
124	41,			/* horizontal sync pulse width */
125	4,			/* BLW */
126	8,			/* ELW */
127
128	10,			/* vertical sync pulse width */
129	2,			/* BFW */
130	4,			/* EFW */
131};
132
133static int gxlcd_console;
134
135
136CFATTACH_DECL_NEW(gxlcd, sizeof(struct pxa2x0_lcd_softc),
137    gxlcd_match, gxlcd_attach, NULL, NULL);
138
139
140static int
141gxlcd_match(device_t parent, cfdata_t match, void *aux)
142{
143	struct pxaip_attach_args *pxa = aux;
144
145	if (strcmp(pxa->pxa_name, match->cf_name) != 0)
146		return 0;
147
148	pxa->pxa_size = PXA2X0_LCDC_SIZE;
149	return 1;
150}
151
152static void
153gxlcd_attach(device_t parent, device_t self, void *aux)
154{
155	struct pxa2x0_lcd_softc *sc = device_private(self);
156	struct wsemuldisplaydev_attach_args aa;
157
158	sc->dev = self;
159	pxa2x0_lcd_attach_sub(sc, aux, &CURRENT_DISPLAY);
160
161	aa.console = gxlcd_console;
162	aa.scrdata = &gxlcd_screen_list;
163	aa.accessops = &gxlcd_accessops;
164	aa.accesscookie = sc;
165
166	pxa2x0_lcd_setup_wsscreen(&gxlcd_std_screen, &CURRENT_DISPLAY, NULL);
167
168	(void) config_found(self, &aa, wsemuldisplaydevprint, CFARGS_NONE);
169}
170
171void
172gxlcd_cnattach(void)
173{
174
175	pxa2x0_lcd_cnattach(&gxlcd_std_screen, &CURRENT_DISPLAY);
176
177	gxlcd_console = 1;
178}
179
180
181/*
182 * wsdisplay accessops overrides
183 */
184static int
185gxlcd_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
186{
187	int res = EINVAL;
188
189	switch (cmd) {
190	case WSDISPLAYIO_SVIDEO:
191		if (*(int *)data == WSDISPLAYIO_VIDEO_ON)
192			pxa2x0_gpio_set_function(17, GPIO_IN);
193		else
194			pxa2x0_gpio_set_function(17, GPIO_OUT | GPIO_CLR);
195		break;
196	}
197
198	if (res == EINVAL)
199		res = pxa2x0_lcd_ioctl(v, vs, cmd, data, flag, l);
200	return res;
201}
202
203static int
204gxlcd_show_screen(void *v, void *cookie, int waitok,
205		  void (*cb_func)(void *, int, int), void *cb_arg)
206{
207	int error;
208
209	error = pxa2x0_lcd_show_screen(v, cookie, waitok, cb_func, cb_arg);
210	if (error)
211		return (error);
212
213	/* Turn on LCD */
214	pxa2x0_gpio_set_function(17, GPIO_IN);
215
216	return 0;
217}
218