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 IQ31244. 40 */ 41 42#include <sys/cdefs.h>
| 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 IQ31244. 40 */ 41 42#include <sys/cdefs.h>
|
43__FBSDID("$FreeBSD: head/sys/arm/xscale/i80321/iq31244_7seg.c 140308 2005-01-15 18:55:22Z cognet $");
| 43__FBSDID("$FreeBSD: head/sys/arm/xscale/i80321/iq31244_7seg.c 140350 2005-01-16 13:18:52Z cognet $");
|
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>
| 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>
|
50 51#include <machine/bus.h> 52 53#include <arm/xscale/i80321/iq80321reg.h> 54#include <arm/xscale/i80321/iq80321var.h> 55 56#define WRITE(x, v) *((__volatile uint8_t *) (x)) = (v) 57 58static int snakestate; 59 60/* 61 * The 7-segment display looks like so: 62 * 63 * A 64 * +-----+ 65 * | | 66 * F | | B 67 * | G | 68 * +-----+ 69 * | | 70 * E | | C 71 * | D | 72 * +-----+ o DP 73 * 74 * Setting a bit clears the corresponding segment on the 75 * display. 76 */ 77#define SEG_A (1 << 0) 78#define SEG_B (1 << 1) 79#define SEG_C (1 << 2) 80#define SEG_D (1 << 3) 81#define SEG_E (1 << 4) 82#define SEG_F (1 << 5) 83#define SEG_G (1 << 6) 84#define SEG_DP (1 << 7) 85 86static const uint8_t digitmap[] = { 87/* +#####+ 88 * # # 89 * # # 90 * # # 91 * +-----+ 92 * # # 93 * # # 94 * # # 95 * +#####+ 96 */ 97 SEG_G, 98 99/* +-----+ 100 * | # 101 * | # 102 * | # 103 * +-----+ 104 * | # 105 * | # 106 * | # 107 * +-----+ 108 */ 109 SEG_A|SEG_D|SEG_E|SEG_F|SEG_G, 110 111/* +#####+ 112 * | # 113 * | # 114 * | # 115 * +#####+ 116 * # | 117 * # | 118 * # | 119 * +#####+ 120 */ 121 SEG_C|SEG_F, 122 123/* +#####+ 124 * | # 125 * | # 126 * | # 127 * +#####+ 128 * | # 129 * | # 130 * | # 131 * +#####+ 132 */ 133 SEG_E|SEG_F, 134 135/* +-----+ 136 * # # 137 * # # 138 * # # 139 * +#####+ 140 * | # 141 * | # 142 * | # 143 * +-----+ 144 */ 145 SEG_A|SEG_D|SEG_E, 146 147/* +#####+ 148 * # | 149 * # | 150 * # | 151 * +#####+ 152 * | # 153 * | # 154 * | # 155 * +#####+ 156 */ 157 SEG_B|SEG_E, 158 159/* +#####+ 160 * # | 161 * # | 162 * # | 163 * +#####+ 164 * # # 165 * # # 166 * # # 167 * +#####+ 168 */ 169 SEG_B, 170 171/* +#####+ 172 * | # 173 * | # 174 * | # 175 * +-----+ 176 * | # 177 * | # 178 * | # 179 * +-----+ 180 */ 181 SEG_D|SEG_E|SEG_F, 182 183/* +#####+ 184 * # # 185 * # # 186 * # # 187 * +#####+ 188 * # # 189 * # # 190 * # # 191 * +#####+ 192 */ 193 0, 194 195/* +#####+ 196 * # # 197 * # # 198 * # # 199 * +#####+ 200 * | # 201 * | # 202 * | # 203 * +-----+ 204 */ 205 SEG_D|SEG_E, 206}; 207 208static uint8_t 209iq80321_7seg_xlate(char c) 210{ 211 uint8_t rv; 212 213 if (c >= '0' && c <= '9') 214 rv = digitmap[c - '0']; 215 else if (c == '.') 216 rv = (uint8_t) ~SEG_DP; 217 else 218 rv = 0xff; 219 220 return (rv); 221} 222 223void 224iq80321_7seg(char a, char b) 225{ 226 uint8_t msb, lsb; 227 228 msb = iq80321_7seg_xlate(a); 229 lsb = iq80321_7seg_xlate(b); 230 231 snakestate = 0; 232 233 WRITE(IQ80321_7SEG_MSB, msb); 234 WRITE(IQ80321_7SEG_LSB, lsb); 235} 236 237static const uint8_t snakemap[][2] = { 238 239/* +#####+ +#####+ 240 * | | | | 241 * | | | | 242 * | | | | 243 * +-----+ +-----+ 244 * | | | | 245 * | | | | 246 * | | | | 247 * +-----+ +-----+ 248 */ 249 { ~SEG_A, ~SEG_A }, 250 251/* +-----+ +-----+ 252 * # | | # 253 * # | | # 254 * # | | # 255 * +-----+ +-----+ 256 * | | | | 257 * | | | | 258 * | | | | 259 * +-----+ +-----+ 260 */ 261 { ~SEG_F, ~SEG_B }, 262 263/* +-----+ +-----+ 264 * | | | | 265 * | | | | 266 * | | | | 267 * +#####+ +#####+ 268 * | | | | 269 * | | | | 270 * | | | | 271 * +-----+ +-----+ 272 */ 273 { ~SEG_G, ~SEG_G }, 274 275/* +-----+ +-----+ 276 * | | | | 277 * | | | | 278 * | | | | 279 * +-----+ +-----+ 280 * | # # | 281 * | # # | 282 * | # # | 283 * +-----+ +-----+ 284 */ 285 { ~SEG_C, ~SEG_E }, 286 287/* +-----+ +-----+ 288 * | | | | 289 * | | | | 290 * | | | | 291 * +-----+ +-----+ 292 * | | | | 293 * | | | | 294 * | | | | 295 * +#####+ +#####+ 296 */ 297 { ~SEG_D, ~SEG_D }, 298 299/* +-----+ +-----+ 300 * | | | | 301 * | | | | 302 * | | | | 303 * +-----+ +-----+ 304 * # | | # 305 * # | | # 306 * # | | # 307 * +-----+ +-----+ 308 */ 309 { ~SEG_E, ~SEG_C }, 310 311/* +-----+ +-----+ 312 * | | | | 313 * | | | | 314 * | | | | 315 * +#####+ +#####+ 316 * | | | | 317 * | | | | 318 * | | | | 319 * +-----+ +-----+ 320 */ 321 { ~SEG_G, ~SEG_G }, 322 323/* +-----+ +-----+ 324 * | # # | 325 * | # # | 326 * | # # | 327 * +-----+ +-----+ 328 * | | | | 329 * | | | | 330 * | | | | 331 * +-----+ +-----+ 332 */ 333 { ~SEG_B, ~SEG_F }, 334}; 335
| 51 52#include <machine/bus.h> 53 54#include <arm/xscale/i80321/iq80321reg.h> 55#include <arm/xscale/i80321/iq80321var.h> 56 57#define WRITE(x, v) *((__volatile uint8_t *) (x)) = (v) 58 59static int snakestate; 60 61/* 62 * The 7-segment display looks like so: 63 * 64 * A 65 * +-----+ 66 * | | 67 * F | | B 68 * | G | 69 * +-----+ 70 * | | 71 * E | | C 72 * | D | 73 * +-----+ o DP 74 * 75 * Setting a bit clears the corresponding segment on the 76 * display. 77 */ 78#define SEG_A (1 << 0) 79#define SEG_B (1 << 1) 80#define SEG_C (1 << 2) 81#define SEG_D (1 << 3) 82#define SEG_E (1 << 4) 83#define SEG_F (1 << 5) 84#define SEG_G (1 << 6) 85#define SEG_DP (1 << 7) 86 87static const uint8_t digitmap[] = { 88/* +#####+ 89 * # # 90 * # # 91 * # # 92 * +-----+ 93 * # # 94 * # # 95 * # # 96 * +#####+ 97 */ 98 SEG_G, 99 100/* +-----+ 101 * | # 102 * | # 103 * | # 104 * +-----+ 105 * | # 106 * | # 107 * | # 108 * +-----+ 109 */ 110 SEG_A|SEG_D|SEG_E|SEG_F|SEG_G, 111 112/* +#####+ 113 * | # 114 * | # 115 * | # 116 * +#####+ 117 * # | 118 * # | 119 * # | 120 * +#####+ 121 */ 122 SEG_C|SEG_F, 123 124/* +#####+ 125 * | # 126 * | # 127 * | # 128 * +#####+ 129 * | # 130 * | # 131 * | # 132 * +#####+ 133 */ 134 SEG_E|SEG_F, 135 136/* +-----+ 137 * # # 138 * # # 139 * # # 140 * +#####+ 141 * | # 142 * | # 143 * | # 144 * +-----+ 145 */ 146 SEG_A|SEG_D|SEG_E, 147 148/* +#####+ 149 * # | 150 * # | 151 * # | 152 * +#####+ 153 * | # 154 * | # 155 * | # 156 * +#####+ 157 */ 158 SEG_B|SEG_E, 159 160/* +#####+ 161 * # | 162 * # | 163 * # | 164 * +#####+ 165 * # # 166 * # # 167 * # # 168 * +#####+ 169 */ 170 SEG_B, 171 172/* +#####+ 173 * | # 174 * | # 175 * | # 176 * +-----+ 177 * | # 178 * | # 179 * | # 180 * +-----+ 181 */ 182 SEG_D|SEG_E|SEG_F, 183 184/* +#####+ 185 * # # 186 * # # 187 * # # 188 * +#####+ 189 * # # 190 * # # 191 * # # 192 * +#####+ 193 */ 194 0, 195 196/* +#####+ 197 * # # 198 * # # 199 * # # 200 * +#####+ 201 * | # 202 * | # 203 * | # 204 * +-----+ 205 */ 206 SEG_D|SEG_E, 207}; 208 209static uint8_t 210iq80321_7seg_xlate(char c) 211{ 212 uint8_t rv; 213 214 if (c >= '0' && c <= '9') 215 rv = digitmap[c - '0']; 216 else if (c == '.') 217 rv = (uint8_t) ~SEG_DP; 218 else 219 rv = 0xff; 220 221 return (rv); 222} 223 224void 225iq80321_7seg(char a, char b) 226{ 227 uint8_t msb, lsb; 228 229 msb = iq80321_7seg_xlate(a); 230 lsb = iq80321_7seg_xlate(b); 231 232 snakestate = 0; 233 234 WRITE(IQ80321_7SEG_MSB, msb); 235 WRITE(IQ80321_7SEG_LSB, lsb); 236} 237 238static const uint8_t snakemap[][2] = { 239 240/* +#####+ +#####+ 241 * | | | | 242 * | | | | 243 * | | | | 244 * +-----+ +-----+ 245 * | | | | 246 * | | | | 247 * | | | | 248 * +-----+ +-----+ 249 */ 250 { ~SEG_A, ~SEG_A }, 251 252/* +-----+ +-----+ 253 * # | | # 254 * # | | # 255 * # | | # 256 * +-----+ +-----+ 257 * | | | | 258 * | | | | 259 * | | | | 260 * +-----+ +-----+ 261 */ 262 { ~SEG_F, ~SEG_B }, 263 264/* +-----+ +-----+ 265 * | | | | 266 * | | | | 267 * | | | | 268 * +#####+ +#####+ 269 * | | | | 270 * | | | | 271 * | | | | 272 * +-----+ +-----+ 273 */ 274 { ~SEG_G, ~SEG_G }, 275 276/* +-----+ +-----+ 277 * | | | | 278 * | | | | 279 * | | | | 280 * +-----+ +-----+ 281 * | # # | 282 * | # # | 283 * | # # | 284 * +-----+ +-----+ 285 */ 286 { ~SEG_C, ~SEG_E }, 287 288/* +-----+ +-----+ 289 * | | | | 290 * | | | | 291 * | | | | 292 * +-----+ +-----+ 293 * | | | | 294 * | | | | 295 * | | | | 296 * +#####+ +#####+ 297 */ 298 { ~SEG_D, ~SEG_D }, 299 300/* +-----+ +-----+ 301 * | | | | 302 * | | | | 303 * | | | | 304 * +-----+ +-----+ 305 * # | | # 306 * # | | # 307 * # | | # 308 * +-----+ +-----+ 309 */ 310 { ~SEG_E, ~SEG_C }, 311 312/* +-----+ +-----+ 313 * | | | | 314 * | | | | 315 * | | | | 316 * +#####+ +#####+ 317 * | | | | 318 * | | | | 319 * | | | | 320 * +-----+ +-----+ 321 */ 322 { ~SEG_G, ~SEG_G }, 323 324/* +-----+ +-----+ 325 * | # # | 326 * | # # | 327 * | # # | 328 * +-----+ +-----+ 329 * | | | | 330 * | | | | 331 * | | | | 332 * +-----+ +-----+ 333 */ 334 { ~SEG_B, ~SEG_F }, 335}; 336
|
| 337SYSCTL_NODE(_hw, OID_AUTO, sevenseg, CTLFLAG_RD, 0, "7 seg"); 338static int freq = 100; 339SYSCTL_INT(_hw_sevenseg, OID_AUTO, freq, CTLFLAG_RW, &freq, 0, 340 "7 Seg update frequency");
|
336static void 337iq31244_7seg_snake(void) 338{ 339 static int snakefreq; 340 int cur = snakestate; 341 342 snakefreq++;
| 341static void 342iq31244_7seg_snake(void) 343{ 344 static int snakefreq; 345 int cur = snakestate; 346 347 snakefreq++;
|
343 if ((snakefreq & (0xff)))
| 348 if ((snakefreq % freq))
|
344 return; 345 WRITE(IQ80321_7SEG_MSB, snakemap[cur][0]); 346 WRITE(IQ80321_7SEG_LSB, snakemap[cur][1]); 347 348 snakestate = (cur + 1) & 7; 349} 350 351struct iq31244_7seg_softc { 352 device_t dev; 353}; 354 355static int 356iq31244_7seg_probe(device_t dev) 357{ 358 359 device_set_desc(dev, "IQ31244 7seg"); 360 return (0); 361} 362 363extern void (*i80321_hardclock_hook)(void); 364static int 365iq31244_7seg_attach(device_t dev) 366{ 367 368 i80321_hardclock_hook = iq31244_7seg_snake; 369 return (0); 370} 371 372static device_method_t iq31244_7seg_methods[] = { 373 DEVMETHOD(device_probe, iq31244_7seg_probe), 374 DEVMETHOD(device_attach, iq31244_7seg_attach), 375 {0, 0}, 376}; 377 378static driver_t iq31244_7seg_driver = { 379 "iqseg", 380 iq31244_7seg_methods, 381 sizeof(struct iq31244_7seg_softc), 382}; 383static devclass_t iq31244_7seg_devclass; 384 385DRIVER_MODULE(iqseg, iq, iq31244_7seg_driver, iq31244_7seg_devclass, 0, 0);
| 349 return; 350 WRITE(IQ80321_7SEG_MSB, snakemap[cur][0]); 351 WRITE(IQ80321_7SEG_LSB, snakemap[cur][1]); 352 353 snakestate = (cur + 1) & 7; 354} 355 356struct iq31244_7seg_softc { 357 device_t dev; 358}; 359 360static int 361iq31244_7seg_probe(device_t dev) 362{ 363 364 device_set_desc(dev, "IQ31244 7seg"); 365 return (0); 366} 367 368extern void (*i80321_hardclock_hook)(void); 369static int 370iq31244_7seg_attach(device_t dev) 371{ 372 373 i80321_hardclock_hook = iq31244_7seg_snake; 374 return (0); 375} 376 377static device_method_t iq31244_7seg_methods[] = { 378 DEVMETHOD(device_probe, iq31244_7seg_probe), 379 DEVMETHOD(device_attach, iq31244_7seg_attach), 380 {0, 0}, 381}; 382 383static driver_t iq31244_7seg_driver = { 384 "iqseg", 385 iq31244_7seg_methods, 386 sizeof(struct iq31244_7seg_softc), 387}; 388static devclass_t iq31244_7seg_devclass; 389 390DRIVER_MODULE(iqseg, iq, iq31244_7seg_driver, iq31244_7seg_devclass, 0, 0);
|