[BACK]Return to jmcu.c CVS log [TXT][DIR] Up to [local] / sys / arch / jornada / dev

Diff for /sys/arch/jornada/dev/jmcu.c between version 1.2 and 1.3

version 1.2, 2008/03/05 20:31:27 version 1.3, 2008/05/11 10:26:11
Line 23 
Line 23 
 #include <arm/sa11x0/sa11x0_gpiovar.h>  #include <arm/sa11x0/sa11x0_gpiovar.h>
   
 #include <jornada/dev/jmcu_kbdmap.h>  #include <jornada/dev/jmcu_kbdmap.h>
   #include "wskbd.h"
   
 #define JMCU_KBD_GPIOINTR       0  #define JMCU_KBD_GPIOINTR       0
 #define JMCU_TS_GPIOINTR        15  #define JMCU_TS_GPIOINTR        15
Line 32 
Line 33 
 struct jmcu_softc {  struct jmcu_softc {
         struct device   sc_dev;          struct device   sc_dev;
   
           /* parent SPI stuff */
         struct spi_bus  *sc_bus;          struct spi_bus  *sc_bus;
         void    *sc_spisc;          void    *sc_spisc;
   
         uint8_t sc_kbdeventsbuf[JMCU_KBD_NEVENTS];          /* keyboard stuff */
         uint8_t sc_kbdeventsnum;          struct device   *sc_wskbddev;
           int     sc_polling;     /* if in 'poll' mode now */
           u_int   sc_kbdqtypes[JMCU_KBD_NEVENTS];
           uint8_t sc_kbdqkeys[JMCU_KBD_NEVENTS];
           uint8_t sc_kbdnevents;
   
           /* battery charge */
           uint16_t        sc_batmain;
           uint16_t        sc_batback;
 };  };
   
 struct jmcu_softc *jmcu_sc;  struct jmcu_softc *jmcu_sc;
   
 struct wskbd_mapdata jmcukbd_keymapdata = {  struct wskbd_mapdata jmcukbd_keymapdata = {
         jmcukbd_keydesctab,          jmcukbd_keydesctab,
         KB_US,          KB_US,
Line 53 
Line 64 
 int     jmcu_kbdintr(void *arg);  int     jmcu_kbdintr(void *arg);
 int     jmcu_touchintr(void *arg);  int     jmcu_touchintr(void *arg);
 void    jmcukbd_cngetc(void *v, u_int *type, int *data);  void    jmcukbd_cngetc(void *v, u_int *type, int *data);
 void    jmcukbd_enqueue(struct jmcu_softc *sc, uint8_t keycode);  void    jmcukbd_cnpollc(void *v, int on);
 void    jmcukbd_dequeue(struct jmcu_softc *sc, uint8_t *keycodep);  void    jmcukbd_poll(void *v);
 void    jmcukbd_getcodes(struct jmcu_softc *sc, int block);  void    jmcukbd_enqueue(struct jmcu_softc *sc, u_int type, uint8_t key);
 void    jmcubatt_status(struct jmcu_softc *sc);  void    jmcukbd_dequeue(struct jmcu_softc *sc, u_int *type, int *data);
   void    jmcubatt_getstatus(struct jmcu_softc *sc);
   void    jmcukbd_readcodes(struct jmcu_softc *sc, char *buf);
   /* accessops */
   int jmcukbd_enable(void *, int);
   void jmcukbd_set_leds(void *, int);
   int jmcukbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
   
   
 /*  /*
  * Autoconf glue.   * Autoconf glue.
  */   */
Line 76 
Line 94 
  */   */
 struct wskbd_consops jmcukbd_consops = {  struct wskbd_consops jmcukbd_consops = {
         jmcukbd_cngetc,          jmcukbd_cngetc,
         NULL, /* pollc */          jmcukbd_cnpollc,
         NULL /* bell */          NULL /* bell */
 };  };
   
   struct wskbd_accessops jmcukbd_accessops = {
           jmcukbd_enable,
           jmcukbd_set_leds,
           jmcukbd_ioctl,
   };
   
   
 int  int
 jmcu_match(struct device *parent, void *cf, void *aux)  jmcu_match(struct device *parent, void *cf, void *aux)
 {  {
Line 92 
Line 116 
 {  {
         struct jmcu_softc *sc = (struct jmcu_softc *)self;          struct jmcu_softc *sc = (struct jmcu_softc *)self;
         struct spibus_attach_args *sba = aux;          struct spibus_attach_args *sba = aux;
   #if NWSKBD > 0
         struct wskbddev_attach_args     wda;          struct wskbddev_attach_args     wda;
   #endif
           /* leap to parent */
         sc->sc_bus = sba->sba_bus;          sc->sc_bus = sba->sba_bus;
         sc->sc_spisc = sba->sba_spisc;          sc->sc_spisc = sba->sba_spisc;
   
         printf(": Jornada MCU\n");  
   
         jmcu_sc = sc;          jmcu_sc = sc;
   
         /* XXX */          jmcubatt_getstatus(sc);
         jmcubatt_status(sc);  
   
           printf(": Jornada MCU (battery charge: main=%d backup=%d)\n", sc->sc_batmain, sc->sc_batback);
   
   #if 0
           sa11x0_gpio_intr_establish(JMCU_KBD_GPIOINTR, IST_EDGE_FALLING, IPL_TTY, jmcu_kbdintr, sc, "jmcukbd_intr");
   #endif /* 0 */
   
   #if NWSKBD > 0
           /* empty event queue */
           sc->sc_kbdnevents = 0;
   
         wskbd_cnattach(&jmcukbd_consops, sc, &jmcukbd_keymapdata);          wskbd_cnattach(&jmcukbd_consops, sc, &jmcukbd_keymapdata);
   
         wda.console = 1;          wda.console = 1;
         wda.keymap = &jmcukbd_keymapdata;          wda.keymap = &jmcukbd_keymapdata;
         wda.accessops = NULL; //jmcukbd_accessops;          wda.accessops = &jmcukbd_accessops;
         wda.accesscookie = sc;          wda.accesscookie = sc;
   
         config_found(self, &wda, wskbddevprint);          sc->sc_wskbddev = config_found(self, &wda, wskbddevprint);
   #endif
         return;          return;
 }  }
   
   #if 0
 int  int
 jmcu_kbdintr(void *arg)  jmcu_kbdintr(void *arg)
 {  {
         struct jmcu_softc *sc = arg;          jmcukbd_poll(arg);
         printf("%s: jmcu_kbdintr\n", sc->sc_dev.dv_xname);  
   
         return(0);          return(0);
 }  }
   #endif
   
   #if 0
 int  int
 jmcu_touchintr(void *arg)  jmcu_touchintr(void *arg)
 {  {
Line 133 
Line 168 
   
         return(0);          return(0);
 }  }
   #endif
   
 void  void
 jmcukbd_cngetc(void *v, u_int *type, int *data)  jmcukbd_cngetc(void *v, u_int *type, int *data)
 {  {
         struct jmcu_softc *sc = v;          struct jmcu_softc *sc = v;
         uint8_t ourdata;  
   
         printf("jmcukbd_cngetc:\n");          /* XXX we should block until new keycode has been obtained */
   
         if (sc->sc_kbdeventsnum == 0)          sc->sc_polling = 1;
                 jmcukbd_getcodes(sc, 1);        /* note that we've passed blocking flag */          while (sc->sc_kbdnevents == 0) {
                   /* enqueue events */
                   jmcukbd_poll(v);
           }
           sc->sc_polling = 0;
   
         jmcukbd_dequeue(sc, &ourdata);          jmcukbd_dequeue(sc, type, data);
   }
   
         *data = ourdata & 0x7f;  void
         *type = ourdata & 0x80 ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;  jmcukbd_cnpollc(void *v, int on)
   {
   
 }  }
   
 void  void
 jmcukbd_getcodes(struct jmcu_softc *sc, int block)  jmcukbd_poll(void *v)
 {  {
           struct jmcu_softc *sc = v;
           u_int   type;
           int     key, s;
           char buf[JMCU_KBD_NEVENTS + 1], *p;
   
           s = spltty();
   
           jmcukbd_readcodes(sc, buf);
   
           for (p = buf; *p; p++) {
                   type = *p & 0x80 ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
                   key = *p & 0x7f;
   
                   /* XXX */
                   if (sc->sc_polling == 0)
                           wskbd_input(sc->sc_wskbddev, type, key);
                   else {
                           /* enqueue event */
                           jmcukbd_enqueue(sc, type, key);
                   }
           }
   
           splx(s);
   }
   
   void
   jmcukbd_readcodes(struct jmcu_softc *sc, char *buf)
   {
         int     nkeys;          int     nkeys;
         uint8_t keycode;  
   
         /* wake up the MCU */          /* wake up the MCU */
         sa11x0_gpio_clear_bit(25);          sa11x0_gpio_clear_bit(25);
   
         spi_acquire(sc->sc_spisc);          spi_acquire(sc->sc_spisc);
   
         do {          /* ask mcu about how many keypress events are there; should get TXDUMMY here */
                 /* ask mcu about how many keypress events are there; should get TXDUMMY here */          if (spi_shift_1(sc->sc_spisc, JMCU_CMD_GETKEYCODES) != JMCU_CMD_TXDUMMY) {
                 if (spi_shift_1(sc->sc_spisc, JMCU_CMD_GETKEYCODES) != JMCU_CMD_TXDUMMY)  
                 printf("%s: WARNING, no txdummy received\n", sc->sc_dev.dv_xname);                  printf("%s: WARNING, no txdummy received\n", sc->sc_dev.dv_xname);
   
                 nkeys = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);                  goto out;
         } while(nkeys == 0 && block);          }
   
           nkeys = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
   
         while (nkeys) {          while (nkeys) {
                 keycode = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);                  *buf = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
                 jmcukbd_enqueue(sc, keycode);  
   
                 nkeys--;                  nkeys--;
                   buf++;
         }          }
   
   out:
           /* terminate buffer */
           *buf = 0;
   
         spi_release(sc->sc_spisc);          spi_release(sc->sc_spisc);
   
         /* park off the MCU */          /* park off the MCU */
         sa11x0_gpio_set_bit(25);          sa11x0_gpio_set_bit(25);
 }  }
   
   
 void  void
 jmcukbd_enqueue(struct jmcu_softc *sc, uint8_t keycode)  jmcukbd_enqueue(struct jmcu_softc *sc, u_int type, uint8_t key)
 {  {
         if (sc->sc_kbdeventsnum >= JMCU_KBD_NEVENTS) {  
                 printf("%s: WARNING, event queue is full; keycode 0x%x will be discarded\n", sc->sc_dev.dv_xname, keycode);          if (sc->sc_kbdnevents > JMCU_KBD_NEVENTS) {
                   printf("%s: WARNING, event queue is full; keycode 0x%x will be discarded\n", sc->sc_dev.dv_xname, key);
                 return;                  return;
         }          }
   
         sc->sc_kbdeventsbuf[sc->sc_kbdeventsnum] = keycode;          sc->sc_kbdqtypes[sc->sc_kbdnevents] = type;
         sc->sc_kbdeventsnum++;          sc->sc_kbdqkeys[sc->sc_kbdnevents] = key;
           sc->sc_kbdnevents++;
 }  }
   
 void  void
 jmcukbd_dequeue(struct jmcu_softc *sc, uint8_t *keycodep)  jmcukbd_dequeue(struct jmcu_softc *sc, u_int *type, int *data)
 {  {
   #if 0
         if (sc->sc_kbdeventsnum < 1) {          if (sc->sc_kbdeventsnum < 1) {
                 printf("%s: WARNING, event queue is empty\n", sc->sc_dev.dv_xname);                  printf("%s: WARNING, event queue is empty\n", sc->sc_dev.dv_xname);
                 return;                  return;
         }          }
   #endif
         sc->sc_kbdeventsnum--;          sc->sc_kbdnevents--;
         *keycodep = sc->sc_kbdeventsbuf[sc->sc_kbdeventsnum];          *type = sc->sc_kbdqtypes[sc->sc_kbdnevents];
           *data = sc->sc_kbdqkeys[sc->sc_kbdnevents];
 }  }
   
   
 void  void
 jmcubatt_status(struct jmcu_softc *sc)  jmcubatt_getstatus(struct jmcu_softc *sc)
 {  {
         uint16_t        mainbatt;  
         uint16_t        backbatt;  
         uint8_t fraction;          uint8_t fraction;
   
         /* wake up the MCU */          /* wake up the MCU */
Line 218 
Line 297 
   
         spi_acquire(sc->sc_spisc);          spi_acquire(sc->sc_spisc);
         spi_shift_1(sc->sc_spisc, JMCU_CMD_GETBATTERYDATA);          spi_shift_1(sc->sc_spisc, JMCU_CMD_GETBATTERYDATA);
         mainbatt = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);          sc->sc_batmain = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
         backbatt = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);          sc->sc_batback = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
         fraction = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);          fraction = spi_shift_1(sc->sc_spisc, JMCU_CMD_TXDUMMY);
         spi_release(sc->sc_spisc);          spi_release(sc->sc_spisc);
   
Line 227 
Line 306 
         sa11x0_gpio_set_bit(25);          sa11x0_gpio_set_bit(25);
   
         /* fraction[0:1] is mainbatt[8:9]; fraction[2:3] is backbatt[8:9] */          /* fraction[0:1] is mainbatt[8:9]; fraction[2:3] is backbatt[8:9] */
         mainbatt |= (uint16_t)((fraction & 0x03) << 8);          sc->sc_batmain |= (uint16_t)((fraction & 0x03) << 8);
         backbatt |= (uint16_t)((fraction & 0xc0) << 6);          sc->sc_batback |= (uint16_t)((fraction & 0x0c) << 6);
   }
   
         printf("%s: battery status: main %d, backup %d\n", sc->sc_dev.dv_xname, mainbatt, backbatt);  int
   jmcukbd_enable(void *v, int on)
   {
           return 0;
 }  }
   
   void
   jmcukbd_set_leds(void *v, int on)
   {
   }
   
   int
   jmcukbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
   {
   #ifdef WSDISPLAY_COMPAT_RAWKBD
           struct jmcukbd_softc *sc = v;
   #endif
   
           switch (cmd) {
   
           case WSKBDIO_GTYPE:
                   *(int *)data = WSKBD_TYPE_ZAURUS /* XXX WSKBD_TYPE_JORNADA */;
                   return 0;
           case WSKBDIO_SETLEDS:
                   return 0;
           case WSKBDIO_GETLEDS:
                   *(int *)data = 0;
                   return 0;
   #ifdef WSDISPLAY_COMPAT_RAWKBD
           case WSKBDIO_SETMODE:
                   sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
                   timeout_del(&sc->sc_rawrepeat_ch);
                   return (0);
   #endif
   
           }
           /* kbdioctl(...); */
   
           return -1;
   }
   
   

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

CVSweb