1 /* $NetBSD: iq31244_7seg.c,v 1.2 2003/07/15 00:25:01 lukem Exp $ */
2
3 /*-
4 * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
5 * All rights reserved.
6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 /*
39 * Support for the 7-segment display on the Intel IQ81342.
40 */
41
42 #include <sys/cdefs.h>
43 __FBSDID("$FreeBSD$");
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/kernel.h>
48 #include <sys/module.h>
49 #include <sys/bus.h>
50 #include <sys/sysctl.h>
51
52 #include <machine/bus.h>
53
54 #include <arm/xscale/i8134x/i81342reg.h>
55 #include <arm/xscale/i8134x/iq81342reg.h>
56 #include <arm/xscale/i8134x/iq81342var.h>
57
58 #define WRITE(x, v) *((__volatile uint8_t *) (x)) = (v)
59
60 static int snakestate;
61
62 /*
63 * The 7-segment display looks like so:
64 *
65 * A
66 * +-----+
67 * | |
68 * F | | B
69 * | G |
70 * +-----+
71 * | |
72 * E | | C
73 * | D |
74 * +-----+ o DP
75 *
76 * Setting a bit clears the corresponding segment on the
77 * display.
78 */
79 #define SEG_A (1 << 1)
80 #define SEG_B (1 << 2)
81 #define SEG_C (1 << 3)
82 #define SEG_D (1 << 4)
83 #define SEG_E (1 << 5)
84 #define SEG_F (1 << 6)
85 #define SEG_G (1 << 7)
86 #define SEG_DP (1 << 0)
87
88 static const uint8_t digitmap[] = {
89 /* +#####+
90 * # #
91 * # #
92 * # #
93 * +-----+
94 * # #
95 * # #
96 * # #
97 * +#####+
98 */
99 (unsigned char)~SEG_G,
100
101 /* +-----+
102 * | #
103 * | #
104 * | #
105 * +-----+
106 * | #
107 * | #
108 * | #
109 * +-----+
110 */
111 SEG_B|SEG_C,
112
113 /* +#####+
114 * | #
115 * | #
116 * | #
117 * +#####+
118 * # |
119 * # |
120 * # |
121 * +#####+
122 */
123 ~(SEG_C|SEG_F),
124
125 /* +#####+
126 * | #
127 * | #
128 * | #
129 * +#####+
130 * | #
131 * | #
132 * | #
133 * +#####+
134 */
135 ~(SEG_E|SEG_F),
136
137 /* +-----+
138 * # #
139 * # #
140 * # #
141 * +#####+
142 * | #
143 * | #
144 * | #
145 * +-----+
146 */
147 ~(SEG_A|SEG_D|SEG_E),
148
149 /* +#####+
150 * # |
151 * # |
152 * # |
153 * +#####+
154 * | #
155 * | #
156 * | #
157 * +#####+
158 */
159 ~(SEG_B|SEG_E),
160
161 /* +#####+
162 * # |
163 * # |
164 * # |
165 * +#####+
166 * # #
167 * # #
168 * # #
169 * +#####+
170 */
171 ~(SEG_B),
172
173 /* +#####+
174 * | #
175 * | #
176 * | #
177 * +-----+
178 * | #
179 * | #
180 * | #
181 * +-----+
182 */
183 ~(SEG_D|SEG_E|SEG_F),
184
185 /* +#####+
186 * # #
187 * # #
188 * # #
189 * +#####+
190 * # #
191 * # #
192 * # #
193 * +#####+
194 */
195 ~0,
196
197 /* +#####+
198 * # #
199 * # #
200 * # #
201 * +#####+
202 * | #
203 * | #
204 * | #
205 * +-----+
206 */
207 ~(SEG_D|SEG_E),
208 };
209
210 static uint8_t
211 iq81342_7seg_xlate(char c)
212 {
213 uint8_t rv;
214
215 if (c >= '' && c <= '9')
216 rv = digitmap[c - ''];
217 else if (c == '.')
218 rv = (uint8_t) ~SEG_DP;
219 else
220 rv = 0xff;
221
222 return (rv);
223 }
224
225 void
226 iq81342_7seg(char a, char b)
227 {
228 uint8_t msb, lsb;
229
230 msb = iq81342_7seg_xlate(a);
231 lsb = iq81342_7seg_xlate(b);
232
233 snakestate = 0;
234
235 WRITE(IQ8134X_7SEG_MSB, msb);
236 WRITE(IQ8134X_7SEG_LSB, lsb);
237 }
238
239 static const uint8_t snakemap[][2] = {
240
241 /* +#####+ +#####+
242 * | | | |
243 * | | | |
244 * | | | |
245 * +-----+ +-----+
246 * | | | |
247 * | | | |
248 * | | | |
249 * +-----+ +-----+
250 */
251 { SEG_A, SEG_A },
252
253 /* +-----+ +-----+
254 * # | | #
255 * # | | #
256 * # | | #
257 * +-----+ +-----+
258 * | | | |
259 * | | | |
260 * | | | |
261 * +-----+ +-----+
262 */
263 { SEG_F, SEG_B },
264
265 /* +-----+ +-----+
266 * | | | |
267 * | | | |
268 * | | | |
269 * +#####+ +#####+
270 * | | | |
271 * | | | |
272 * | | | |
273 * +-----+ +-----+
274 */
275 { SEG_G, SEG_G },
276
277 /* +-----+ +-----+
278 * | | | |
279 * | | | |
280 * | | | |
281 * +-----+ +-----+
282 * | # # |
283 * | # # |
284 * | # # |
285 * +-----+ +-----+
286 */
287 { SEG_C, SEG_E },
288
289 /* +-----+ +-----+
290 * | | | |
291 * | | | |
292 * | | | |
293 * +-----+ +-----+
294 * | | | |
295 * | | | |
296 * | | | |
297 * +#####+ +#####+
298 */
299 { SEG_D, SEG_D },
300
301 /* +-----+ +-----+
302 * | | | |
303 * | | | |
304 * | | | |
305 * +-----+ +-----+
306 * # | | #
307 * # | | #
308 * # | | #
309 * +-----+ +-----+
310 */
311 { SEG_E, SEG_C },
312
313 /* +-----+ +-----+
314 * | | | |
315 * | | | |
316 * | | | |
317 * +#####+ +#####+
318 * | | | |
319 * | | | |
320 * | | | |
321 * +-----+ +-----+
322 */
323 { SEG_G, SEG_G },
324
325 /* +-----+ +-----+
326 * | # # |
327 * | # # |
328 * | # # |
329 * +-----+ +-----+
330 * | | | |
331 * | | | |
332 * | | | |
333 * +-----+ +-----+
334 */
335 { SEG_B, SEG_F },
336 };
337
338 SYSCTL_NODE(_hw, OID_AUTO, sevenseg, CTLFLAG_RD, 0, "7 seg");
339 static int freq = 20;
340 SYSCTL_INT(_hw_sevenseg, OID_AUTO, freq, CTLFLAG_RW, &freq, 0,
341 "7 Seg update frequency");
342 static void
343 iq81342_7seg_snake(void)
344 {
345 static int snakefreq;
346 int cur = snakestate;
347
348 snakefreq++;
349 if ((snakefreq % freq))
350 return;
351 WRITE(IQ8134X_7SEG_MSB, snakemap[cur][0]);
352 WRITE(IQ8134X_7SEG_LSB, snakemap[cur][1]);
353
354 snakestate = (cur + 1) & 7;
355 }
356
357 struct iq81342_7seg_softc {
358 device_t dev;
359 };
360
361 static int
362 iq81342_7seg_probe(device_t dev)
363 {
364
365 device_set_desc(dev, "IQ81342 7seg");
366 return (0);
367 }
368
369 extern void (*i80321_hardclock_hook)(void);
370 static int
371 iq81342_7seg_attach(device_t dev)
372 {
373
374 i80321_hardclock_hook = iq81342_7seg_snake;
375 return (0);
376 }
377
378 static device_method_t iq81342_7seg_methods[] = {
379 DEVMETHOD(device_probe, iq81342_7seg_probe),
380 DEVMETHOD(device_attach, iq81342_7seg_attach),
381 {0, 0},
382 };
383
384 static driver_t iq81342_7seg_driver = {
385 "iqseg",
386 iq81342_7seg_methods,
387 sizeof(struct iq81342_7seg_softc),
388 };
389 static devclass_t iq81342_7seg_devclass;
390
391 DRIVER_MODULE(iqseg, iq, iq81342_7seg_driver, iq81342_7seg_devclass, 0, 0);
Cache object: 3e204a07f044ea2f57159797133baeee
|