1 /* $NetBSD: tc5165buf.c,v 1.15 2007/10/17 19:54:29 garbled Exp $ */
4 * Copyright (c) 1999-2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND 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 THE FOUNDATION OR CONTRIBUTORS
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.
33 * Device driver for TOSHIBA TC5165BFTS, PHILIPS 74ALVC16241/245
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: tc5165buf.c,v 1.15 2007/10/17 19:54:29 garbled Exp $");
40 #include "opt_use_poll.h"
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/callout.h>
45 #include <sys/device.h>
47 #include <machine/bus.h>
48 #include <machine/intr.h>
50 #include <dev/hpc/hpckbdvar.h>
52 #include <hpcmips/tx/tx39var.h>
53 #include <hpcmips/tx/txcsbusvar.h>
54 #include <hpcmips/dev/tc5165bufvar.h>
56 #define TC5165_ROW_MAX 16
57 #define TC5165_COLUMN_MAX 8
60 #define DPRINTF(arg) printf arg
65 struct tc5165buf_chip
{
66 bus_space_tag_t scc_cst
;
67 bus_space_handle_t scc_csh
;
68 u_int16_t scc_buf
[TC5165_COLUMN_MAX
];
71 struct callout scc_soft_ch
;
72 struct hpckbd_ic_if scc_if
;
73 struct hpckbd_if
*scc_hpckbd
;
76 struct tc5165buf_softc
{
78 struct tc5165buf_chip
*sc_chip
;
79 tx_chipset_tag_t sc_tc
;
83 int tc5165buf_match(struct device
*, struct cfdata
*, void *);
84 void tc5165buf_attach(struct device
*, struct device
*, void *);
85 int tc5165buf_intr(void *);
86 int tc5165buf_poll(void *);
87 void tc5165buf_soft(void *);
88 void tc5165buf_ifsetup(struct tc5165buf_chip
*);
90 int tc5165buf_input_establish(void *, struct hpckbd_if
*);
92 struct tc5165buf_chip tc5165buf_chip
;
94 CFATTACH_DECL(tc5165buf
, sizeof(struct tc5165buf_softc
),
95 tc5165buf_match
, tc5165buf_attach
, NULL
, NULL
);
98 tc5165buf_match(struct device
*parent
, struct cfdata
*cf
, void *aux
)
105 tc5165buf_attach(struct device
*parent
, struct device
*self
, void *aux
)
107 struct cs_attach_args
*ca
= aux
;
108 struct tc5165buf_softc
*sc
= (void*)self
;
109 struct hpckbd_attach_args haa
;
112 sc
->sc_tc
= ca
->ca_tc
;
113 sc
->sc_chip
= &tc5165buf_chip
;
115 callout_init(&sc
->sc_chip
->scc_soft_ch
, 0);
117 sc
->sc_chip
->scc_cst
= ca
->ca_csio
.cstag
;
119 if (bus_space_map(sc
->sc_chip
->scc_cst
, ca
->ca_csio
.csbase
,
120 ca
->ca_csio
.cssize
, 0, &sc
->sc_chip
->scc_csh
)) {
121 printf("can't map i/o space\n");
125 sc
->sc_chip
->scc_enabled
= 0;
127 if (ca
->ca_irq1
!= -1) {
128 sc
->sc_ih
= tx_intr_establish(sc
->sc_tc
, ca
->ca_irq1
,
131 printf("interrupt mode");
133 sc
->sc_ih
= tx39_poll_establish(sc
->sc_tc
, 1, IPL_TTY
,
135 printf("polling mode");
139 printf(" can't establish interrupt\n");
145 /* setup upper interface */
146 tc5165buf_ifsetup(sc
->sc_chip
);
148 haa
.haa_ic
= &sc
->sc_chip
->scc_if
;
150 config_found(self
, &haa
, hpckbd_print
);
154 tc5165buf_ifsetup(struct tc5165buf_chip
*scc
)
157 scc
->scc_if
.hii_ctx
= scc
;
158 scc
->scc_if
.hii_establish
= tc5165buf_input_establish
;
159 scc
->scc_if
.hii_poll
= tc5165buf_poll
;
163 tc5165buf_cnattach(paddr_t addr
)
165 struct tc5165buf_chip
*scc
= &tc5165buf_chip
;
167 scc
->scc_csh
= MIPS_PHYS_TO_KSEG1(addr
);
169 tc5165buf_ifsetup(scc
);
171 hpckbd_cnattach(&scc
->scc_if
);
177 tc5165buf_input_establish(void *ic
, struct hpckbd_if
*kbdif
)
179 struct tc5165buf_chip
*scc
= ic
;
181 /* save hpckbd interface */
182 scc
->scc_hpckbd
= kbdif
;
184 scc
->scc_enabled
= 1;
190 tc5165buf_intr(void *arg
)
192 struct tc5165buf_softc
*sc
= arg
;
193 struct tc5165buf_chip
*scc
= sc
->sc_chip
;
195 if (!scc
->scc_enabled
|| scc
->scc_queued
)
199 callout_reset(&scc
->scc_soft_ch
, 1, tc5165buf_soft
, scc
);
205 tc5165buf_poll(void *arg
)
207 struct tc5165buf_chip
*scc
= arg
;
209 if (!scc
->scc_enabled
)
218 tc5165buf_soft(void *arg
)
220 struct tc5165buf_chip
*scc
= arg
;
221 bus_space_tag_t t
= scc
->scc_cst
;
222 bus_space_handle_t h
= scc
->scc_csh
;
223 u_int16_t mask
, rpat
, edge
;
227 hpckbd_input_hook(scc
->scc_hpckbd
);
229 /* clear scanlines */
230 (void)bus_space_read_2(t
, h
, 0);
233 for (i
= 0; i
< TC5165_COLUMN_MAX
; i
++) {
234 rpat
= bus_space_read_2(t
, h
, 2 << i
);
236 (void)bus_space_read_2(t
, h
, 0);
238 if ((edge
= (rpat
^ scc
->scc_buf
[i
]))) {
239 scc
->scc_buf
[i
] = rpat
;
240 for (j
= 0, mask
= 1; j
< TC5165_ROW_MAX
;
243 type
= mask
& rpat
? 1 : 0;
244 val
= j
* TC5165_COLUMN_MAX
+ i
;
245 DPRINTF(("%d %d\n", j
, i
));
246 hpckbd_input(scc
->scc_hpckbd
,