Annotation of funnyos/arch/sam7s64/dev/gpio7seg.c, Revision 1.1
1.1 ! nbrk 1: /*
! 2: * $Id$
! 3: */
! 4: #include <sys/types.h>
! 5: #include <sys/device.h>
! 6: #include <sys/gpio.h>
! 7: #include <sys/devctl.h>
! 8:
! 9: #include <arch/sam7s64/dev/gpio7segvar.h>
! 10: #include <libkern/printf.h>
! 11: /*
! 12: * Driver for 7-segment LED indicator.
! 13: *
! 14: * Well known way to describe segments is:
! 15: * _a_
! 16: * f| |b
! 17: * |_g_|
! 18: * e| |c
! 19: * |_d_|
! 20: *
! 21: * XXX: There is no way to associate pin to a segment but to hardcode that.
! 22: * TODO: Maybe this all gpio stuff should go into MI part.
! 23: */
! 24:
! 25: /* hardcode segments to lines (PA{23, 26-31} in my case) */
! 26: #define GPIO7SEG_PINA 26
! 27: #define GPIO7SEG_PINB 28
! 28: #define GPIO7SEG_PINC 31
! 29: #define GPIO7SEG_PIND 29
! 30: #define GPIO7SEG_PINE 30
! 31: #define GPIO7SEG_PINF 27
! 32: #define GPIO7SEG_PING 23
! 33:
! 34:
! 35: int gpio7seg_attach(struct device *, uint32_t, uint8_t);
! 36: int gpio7seg_devctl(struct device *self, uint32_t ctlcmd, void *ctldata);
! 37: uint8_t gpio7seg_digit(uint8_t digit);
! 38: void gpio7seg_update(struct gpio7seg_dd *ddp);
! 39:
! 40:
! 41: struct driver gpio7seg_dr = {
! 42: sizeof(struct gpio7seg_dd),
! 43: gpio7seg_attach,
! 44: NULL,
! 45: NULL
! 46: };
! 47:
! 48:
! 49: int
! 50: gpio7seg_attach(struct device *self, uint32_t loc, uint8_t flags)
! 51: {
! 52: struct gpio7seg_dd *ddp = self->dv_devdata;
! 53: uint8_t i;
! 54:
! 55: /* grab parent's gpio_controller */
! 56: ddp->gs_gcp = self->dv_parent->dv_aux;
! 57:
! 58: /*
! 59: * Configure pins.
! 60: */
! 61: /* assign hardcoded pin numbers */
! 62: ddp->gs_pins[0].gp_pinno = GPIO7SEG_PINA;
! 63: ddp->gs_pins[1].gp_pinno = GPIO7SEG_PINB;
! 64: ddp->gs_pins[2].gp_pinno = GPIO7SEG_PINC;
! 65: ddp->gs_pins[3].gp_pinno = GPIO7SEG_PIND;
! 66: ddp->gs_pins[4].gp_pinno = GPIO7SEG_PINE;
! 67: ddp->gs_pins[5].gp_pinno = GPIO7SEG_PINF;
! 68: ddp->gs_pins[6].gp_pinno = GPIO7SEG_PING;
! 69:
! 70: /* set all lines to output, value 1 means 'off' */
! 71: for(i = 0; i < 7; i++) {
! 72: ddp->gs_pins[i].gp_pio = 1;
! 73: ddp->gs_pins[i].gp_flags = GPIO_PIN_OUTPUT;
! 74: ddp->gs_pins[i].gp_value = 1; /* OFF by default */
! 75:
! 76: /* talk to gpio controller */
! 77: ddp->gs_gcp->gc_pinset(ddp->gs_gcp->gc_selfdd, ddp->gs_pins[i]);
! 78: }
! 79:
! 80: printf("p64 onboard 7-segment LED\n");
! 81:
! 82:
! 83: devctl_register(self, gpio7seg_devctl);
! 84:
! 85: return(0);
! 86: }
! 87:
! 88:
! 89: int
! 90: gpio7seg_devctl(struct device *self, uint32_t ctlcmd, void *ctldata)
! 91: {
! 92: struct gpio7seg_dd *ddp;
! 93: uint8_t digit;
! 94:
! 95: ddp = self->dv_devdata;
! 96:
! 97: switch(ctlcmd) {
! 98: case(DCGPIO7SEG_OFF):
! 99: /*
! 100: * Switch all segments off.
! 101: */
! 102: ddp->gs_mask &= ~(1 << 7);
! 103: gpio7seg_update(ddp);
! 104:
! 105: break;
! 106:
! 107: case(DCGPIO7SEG_ON):
! 108: /*
! 109: * Switch all segments on.
! 110: */
! 111: ddp->gs_mask |= 1 << 7;
! 112: gpio7seg_update(ddp);
! 113:
! 114: break;
! 115:
! 116: case(DCGPIO7SEG_SETMASK):
! 117: /*
! 118: * Manually set indicator mask and update ourselves.
! 119: */
! 120: ddp->gs_mask = *(uint8_t *)ctldata;
! 121: gpio7seg_update(ddp);
! 122:
! 123: break;
! 124:
! 125: case(DCGPIO7SEG_SETDIGIT):
! 126: /*
! 127: * Draw given digit. Valid digits are 0..15 (where 10 will be 'A').
! 128: */
! 129: digit = *(uint8_t *)ctldata;
! 130:
! 131: if (digit > 15)
! 132: /* overflow */
! 133: return(-1);
! 134:
! 135: /* modify mask to determine which segments represent given digit */
! 136: ddp->gs_mask = gpio7seg_digit(digit);
! 137:
! 138: /* update */
! 139: gpio7seg_update(ddp);
! 140:
! 141: default:
! 142: break;
! 143: }
! 144:
! 145: return(0);
! 146: }
! 147:
! 148:
! 149: uint8_t
! 150: gpio7seg_digit(uint8_t digit)
! 151: {
! 152: /*
! 153: * Return bitmask representing given digit.
! 154: * Nothing special: this is well-know way.
! 155: */
! 156: switch (digit) {
! 157: case 0:
! 158: return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_C | GPIO7SEG_D | GPIO7SEG_E | GPIO7SEG_F);
! 159: case 1:
! 160: return(GPIO7SEG_B | GPIO7SEG_C);
! 161: case 2:
! 162: return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_G | GPIO7SEG_E | GPIO7SEG_D);
! 163: case 3:
! 164: return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_G | GPIO7SEG_C | GPIO7SEG_D);
! 165: case 4:
! 166: return(GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_B | GPIO7SEG_C);
! 167: case 5:
! 168: return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_C | GPIO7SEG_D);
! 169: case 6:
! 170: return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_C | GPIO7SEG_D | GPIO7SEG_E);
! 171: case 7:
! 172: return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_C);
! 173: case 8:
! 174: return(GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_C | GPIO7SEG_D | GPIO7SEG_E | GPIO7SEG_F | GPIO7SEG_G);
! 175: case 9:
! 176: return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_B | GPIO7SEG_C);
! 177: case 10:
! 178: /* 'A' */
! 179: return(GPIO7SEG_E | GPIO7SEG_F | GPIO7SEG_A | GPIO7SEG_B | GPIO7SEG_C | GPIO7SEG_G);
! 180: case 11:
! 181: /* 'b' */
! 182: return(GPIO7SEG_F | GPIO7SEG_E | GPIO7SEG_D | GPIO7SEG_C | GPIO7SEG_G);
! 183: case 12:
! 184: /* 'C' */
! 185: return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_E | GPIO7SEG_D);
! 186: case 13:
! 187: /* 'd' */
! 188: return(GPIO7SEG_B | GPIO7SEG_C | GPIO7SEG_D | GPIO7SEG_E | GPIO7SEG_G);
! 189: case 14:
! 190: /* 'E' */
! 191: return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_E | GPIO7SEG_D);
! 192: case 15:
! 193: /* 'F' */
! 194: return(GPIO7SEG_A | GPIO7SEG_F | GPIO7SEG_G | GPIO7SEG_E);
! 195: }
! 196:
! 197: /* XXX else return 'OFF' mask */
! 198: return(GPIO7SEG_OFF);
! 199: }
! 200:
! 201:
! 202: void
! 203: gpio7seg_update(struct gpio7seg_dd *ddp)
! 204: {
! 205: /*
! 206: * Update gpio controller based on our mask.
! 207: */
! 208: uint8_t i;
! 209:
! 210: /* see if GPIO7SEG_OFF is given */
! 211: if (ddp->gs_mask & GPIO7SEG_OFF) {
! 212: /* TODO */
! 213: return;
! 214: }
! 215:
! 216: for(i = 0; i < 7; i++) {
! 217: if (ddp->gs_mask & (1 << i)) {
! 218: /* corresponding bit is set */
! 219: ddp->gs_pins[i].gp_value = 0;
! 220: } else ddp->gs_pins[i].gp_value = 1;
! 221:
! 222: /* kick pio controller */
! 223: ddp->gs_gcp->gc_pinset(ddp->gs_gcp->gc_selfdd, ddp->gs_pins[i]);
! 224: }
! 225:
! 226: }
! 227:
CVSweb