1172297Scognet/* $NetBSD: iq31244_7seg.c,v 1.2 2003/07/15 00:25:01 lukem Exp $ */ 2172297Scognet 3172297Scognet/*- 4172297Scognet * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc. 5172297Scognet * All rights reserved. 6172297Scognet * 7172297Scognet * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8172297Scognet * 9172297Scognet * Redistribution and use in source and binary forms, with or without 10172297Scognet * modification, are permitted provided that the following conditions 11172297Scognet * are met: 12172297Scognet * 1. Redistributions of source code must retain the above copyright 13172297Scognet * notice, this list of conditions and the following disclaimer. 14172297Scognet * 2. Redistributions in binary form must reproduce the above copyright 15172297Scognet * notice, this list of conditions and the following disclaimer in the 16172297Scognet * documentation and/or other materials provided with the distribution. 17172297Scognet * 3. All advertising materials mentioning features or use of this software 18172297Scognet * must display the following acknowledgement: 19172297Scognet * This product includes software developed for the NetBSD Project by 20172297Scognet * Wasabi Systems, Inc. 21172297Scognet * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22172297Scognet * or promote products derived from this software without specific prior 23172297Scognet * written permission. 24172297Scognet * 25172297Scognet * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26172297Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27172297Scognet * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28172297Scognet * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29172297Scognet * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30172297Scognet * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31172297Scognet * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32172297Scognet * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33172297Scognet * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34172297Scognet * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35172297Scognet * POSSIBILITY OF SUCH DAMAGE. 36172297Scognet */ 37172297Scognet 38172297Scognet/* 39172297Scognet * Support for the 7-segment display on the Intel IQ81342. 40172297Scognet */ 41172297Scognet 42172297Scognet#include <sys/cdefs.h> 43172297Scognet__FBSDID("$FreeBSD: releng/11.0/sys/arm/xscale/i8134x/iq81342_7seg.c 236987 2012-06-13 04:38:09Z imp $"); 44172297Scognet 45172297Scognet#include <sys/param.h> 46172297Scognet#include <sys/systm.h> 47172297Scognet#include <sys/kernel.h> 48172297Scognet#include <sys/module.h> 49172297Scognet#include <sys/bus.h> 50172297Scognet#include <sys/sysctl.h> 51172297Scognet 52172297Scognet#include <machine/bus.h> 53172297Scognet 54172297Scognet#include <arm/xscale/i8134x/i81342reg.h> 55172297Scognet#include <arm/xscale/i8134x/iq81342reg.h> 56172297Scognet#include <arm/xscale/i8134x/iq81342var.h> 57172297Scognet 58172297Scognet#define WRITE(x, v) *((__volatile uint8_t *) (x)) = (v) 59172297Scognet 60172297Scognetstatic int snakestate; 61172297Scognet 62172297Scognet/* 63172297Scognet * The 7-segment display looks like so: 64172297Scognet * 65172297Scognet * A 66172297Scognet * +-----+ 67172297Scognet * | | 68172297Scognet * F | | B 69172297Scognet * | G | 70172297Scognet * +-----+ 71172297Scognet * | | 72172297Scognet * E | | C 73172297Scognet * | D | 74172297Scognet * +-----+ o DP 75172297Scognet * 76172297Scognet * Setting a bit clears the corresponding segment on the 77172297Scognet * display. 78172297Scognet */ 79172297Scognet#define SEG_A (1 << 1) 80172297Scognet#define SEG_B (1 << 2) 81172297Scognet#define SEG_C (1 << 3) 82172297Scognet#define SEG_D (1 << 4) 83172297Scognet#define SEG_E (1 << 5) 84172297Scognet#define SEG_F (1 << 6) 85172297Scognet#define SEG_G (1 << 7) 86172297Scognet#define SEG_DP (1 << 0) 87172297Scognet 88172297Scognetstatic const uint8_t digitmap[] = { 89172297Scognet/* +#####+ 90172297Scognet * # # 91172297Scognet * # # 92172297Scognet * # # 93172297Scognet * +-----+ 94172297Scognet * # # 95172297Scognet * # # 96172297Scognet * # # 97172297Scognet * +#####+ 98172297Scognet */ 99172297Scognet (unsigned char)~SEG_G, 100172297Scognet 101172297Scognet/* +-----+ 102172297Scognet * | # 103172297Scognet * | # 104172297Scognet * | # 105172297Scognet * +-----+ 106172297Scognet * | # 107172297Scognet * | # 108172297Scognet * | # 109172297Scognet * +-----+ 110172297Scognet */ 111172297Scognet SEG_B|SEG_C, 112172297Scognet 113172297Scognet/* +#####+ 114172297Scognet * | # 115172297Scognet * | # 116172297Scognet * | # 117172297Scognet * +#####+ 118172297Scognet * # | 119172297Scognet * # | 120172297Scognet * # | 121172297Scognet * +#####+ 122172297Scognet */ 123172297Scognet ~(SEG_C|SEG_F), 124172297Scognet 125172297Scognet/* +#####+ 126172297Scognet * | # 127172297Scognet * | # 128172297Scognet * | # 129172297Scognet * +#####+ 130172297Scognet * | # 131172297Scognet * | # 132172297Scognet * | # 133172297Scognet * +#####+ 134172297Scognet */ 135172297Scognet ~(SEG_E|SEG_F), 136172297Scognet 137172297Scognet/* +-----+ 138172297Scognet * # # 139172297Scognet * # # 140172297Scognet * # # 141172297Scognet * +#####+ 142172297Scognet * | # 143172297Scognet * | # 144172297Scognet * | # 145172297Scognet * +-----+ 146172297Scognet */ 147172297Scognet ~(SEG_A|SEG_D|SEG_E), 148172297Scognet 149172297Scognet/* +#####+ 150172297Scognet * # | 151172297Scognet * # | 152172297Scognet * # | 153172297Scognet * +#####+ 154172297Scognet * | # 155172297Scognet * | # 156172297Scognet * | # 157172297Scognet * +#####+ 158172297Scognet */ 159172297Scognet ~(SEG_B|SEG_E), 160172297Scognet 161172297Scognet/* +#####+ 162172297Scognet * # | 163172297Scognet * # | 164172297Scognet * # | 165172297Scognet * +#####+ 166172297Scognet * # # 167172297Scognet * # # 168172297Scognet * # # 169172297Scognet * +#####+ 170172297Scognet */ 171172297Scognet ~(SEG_B), 172172297Scognet 173172297Scognet/* +#####+ 174172297Scognet * | # 175172297Scognet * | # 176172297Scognet * | # 177172297Scognet * +-----+ 178172297Scognet * | # 179172297Scognet * | # 180172297Scognet * | # 181172297Scognet * +-----+ 182172297Scognet */ 183172297Scognet ~(SEG_D|SEG_E|SEG_F), 184172297Scognet 185172297Scognet/* +#####+ 186172297Scognet * # # 187172297Scognet * # # 188172297Scognet * # # 189172297Scognet * +#####+ 190172297Scognet * # # 191172297Scognet * # # 192172297Scognet * # # 193172297Scognet * +#####+ 194172297Scognet */ 195172297Scognet ~0, 196172297Scognet 197172297Scognet/* +#####+ 198172297Scognet * # # 199172297Scognet * # # 200172297Scognet * # # 201172297Scognet * +#####+ 202172297Scognet * | # 203172297Scognet * | # 204172297Scognet * | # 205172297Scognet * +-----+ 206172297Scognet */ 207172297Scognet ~(SEG_D|SEG_E), 208172297Scognet}; 209172297Scognet 210236987Simpstatic uint8_t 211172297Scognetiq81342_7seg_xlate(char c) 212172297Scognet{ 213172297Scognet uint8_t rv; 214172297Scognet 215172297Scognet if (c >= '0' && c <= '9') 216172297Scognet rv = digitmap[c - '0']; 217172297Scognet else if (c == '.') 218172297Scognet rv = (uint8_t) ~SEG_DP; 219172297Scognet else 220172297Scognet rv = 0xff; 221172297Scognet 222172297Scognet return (rv); 223172297Scognet} 224172297Scognet 225172297Scognetvoid 226172297Scognetiq81342_7seg(char a, char b) 227172297Scognet{ 228172297Scognet uint8_t msb, lsb; 229172297Scognet 230172297Scognet msb = iq81342_7seg_xlate(a); 231172297Scognet lsb = iq81342_7seg_xlate(b); 232172297Scognet 233172297Scognet snakestate = 0; 234172297Scognet 235172297Scognet WRITE(IQ8134X_7SEG_MSB, msb); 236172297Scognet WRITE(IQ8134X_7SEG_LSB, lsb); 237172297Scognet} 238172297Scognet 239172297Scognetstatic const uint8_t snakemap[][2] = { 240172297Scognet 241172297Scognet/* +#####+ +#####+ 242172297Scognet * | | | | 243172297Scognet * | | | | 244172297Scognet * | | | | 245172297Scognet * +-----+ +-----+ 246172297Scognet * | | | | 247172297Scognet * | | | | 248172297Scognet * | | | | 249172297Scognet * +-----+ +-----+ 250172297Scognet */ 251172297Scognet { SEG_A, SEG_A }, 252172297Scognet 253172297Scognet/* +-----+ +-----+ 254172297Scognet * # | | # 255172297Scognet * # | | # 256172297Scognet * # | | # 257172297Scognet * +-----+ +-----+ 258172297Scognet * | | | | 259172297Scognet * | | | | 260172297Scognet * | | | | 261172297Scognet * +-----+ +-----+ 262172297Scognet */ 263172297Scognet { SEG_F, SEG_B }, 264172297Scognet 265172297Scognet/* +-----+ +-----+ 266172297Scognet * | | | | 267172297Scognet * | | | | 268172297Scognet * | | | | 269172297Scognet * +#####+ +#####+ 270172297Scognet * | | | | 271172297Scognet * | | | | 272172297Scognet * | | | | 273172297Scognet * +-----+ +-----+ 274172297Scognet */ 275172297Scognet { SEG_G, SEG_G }, 276172297Scognet 277172297Scognet/* +-----+ +-----+ 278172297Scognet * | | | | 279172297Scognet * | | | | 280172297Scognet * | | | | 281172297Scognet * +-----+ +-----+ 282172297Scognet * | # # | 283172297Scognet * | # # | 284172297Scognet * | # # | 285172297Scognet * +-----+ +-----+ 286172297Scognet */ 287172297Scognet { SEG_C, SEG_E }, 288172297Scognet 289172297Scognet/* +-----+ +-----+ 290172297Scognet * | | | | 291172297Scognet * | | | | 292172297Scognet * | | | | 293172297Scognet * +-----+ +-----+ 294172297Scognet * | | | | 295172297Scognet * | | | | 296172297Scognet * | | | | 297172297Scognet * +#####+ +#####+ 298172297Scognet */ 299172297Scognet { SEG_D, SEG_D }, 300172297Scognet 301172297Scognet/* +-----+ +-----+ 302172297Scognet * | | | | 303172297Scognet * | | | | 304172297Scognet * | | | | 305172297Scognet * +-----+ +-----+ 306172297Scognet * # | | # 307172297Scognet * # | | # 308172297Scognet * # | | # 309172297Scognet * +-----+ +-----+ 310172297Scognet */ 311172297Scognet { SEG_E, SEG_C }, 312172297Scognet 313172297Scognet/* +-----+ +-----+ 314172297Scognet * | | | | 315172297Scognet * | | | | 316172297Scognet * | | | | 317172297Scognet * +#####+ +#####+ 318172297Scognet * | | | | 319172297Scognet * | | | | 320172297Scognet * | | | | 321172297Scognet * +-----+ +-----+ 322172297Scognet */ 323172297Scognet { SEG_G, SEG_G }, 324172297Scognet 325172297Scognet/* +-----+ +-----+ 326172297Scognet * | # # | 327172297Scognet * | # # | 328172297Scognet * | # # | 329172297Scognet * +-----+ +-----+ 330172297Scognet * | | | | 331172297Scognet * | | | | 332172297Scognet * | | | | 333172297Scognet * +-----+ +-----+ 334172297Scognet */ 335172297Scognet { SEG_B, SEG_F }, 336172297Scognet}; 337172297Scognet 338227309Sedstatic SYSCTL_NODE(_hw, OID_AUTO, sevenseg, CTLFLAG_RD, 0, "7 seg"); 339172297Scognetstatic int freq = 20; 340236987SimpSYSCTL_INT(_hw_sevenseg, OID_AUTO, freq, CTLFLAG_RW, &freq, 0, 341172297Scognet "7 Seg update frequency"); 342172297Scognetstatic void 343172297Scognetiq81342_7seg_snake(void) 344172297Scognet{ 345172297Scognet static int snakefreq; 346172297Scognet int cur = snakestate; 347172297Scognet 348172297Scognet snakefreq++; 349172297Scognet if ((snakefreq % freq)) 350172297Scognet return; 351172297Scognet WRITE(IQ8134X_7SEG_MSB, snakemap[cur][0]); 352172297Scognet WRITE(IQ8134X_7SEG_LSB, snakemap[cur][1]); 353172297Scognet 354172297Scognet snakestate = (cur + 1) & 7; 355172297Scognet} 356172297Scognet 357172297Scognetstruct iq81342_7seg_softc { 358172297Scognet device_t dev; 359172297Scognet}; 360172297Scognet 361172297Scognetstatic int 362172297Scognetiq81342_7seg_probe(device_t dev) 363172297Scognet{ 364172297Scognet 365172297Scognet device_set_desc(dev, "IQ81342 7seg"); 366172297Scognet return (0); 367172297Scognet} 368172297Scognet 369172297Scognetextern void (*i80321_hardclock_hook)(void); 370172297Scognetstatic int 371172297Scognetiq81342_7seg_attach(device_t dev) 372172297Scognet{ 373172297Scognet 374172297Scognet i80321_hardclock_hook = iq81342_7seg_snake; 375172297Scognet return (0); 376172297Scognet} 377172297Scognet 378172297Scognetstatic device_method_t iq81342_7seg_methods[] = { 379172297Scognet DEVMETHOD(device_probe, iq81342_7seg_probe), 380172297Scognet DEVMETHOD(device_attach, iq81342_7seg_attach), 381172297Scognet {0, 0}, 382172297Scognet}; 383172297Scognet 384172297Scognetstatic driver_t iq81342_7seg_driver = { 385172297Scognet "iqseg", 386172297Scognet iq81342_7seg_methods, 387172297Scognet sizeof(struct iq81342_7seg_softc), 388172297Scognet}; 389172297Scognetstatic devclass_t iq81342_7seg_devclass; 390172297Scognet 391172297ScognetDRIVER_MODULE(iqseg, iq, iq81342_7seg_driver, iq81342_7seg_devclass, 0, 0); 392