Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  linux/drivers/hil/hilkbd.c
0004  *
0005  *  Copyright (C) 1998 Philip Blundell <philb@gnu.org>
0006  *  Copyright (C) 1999 Matthew Wilcox <willy@infradead.org>
0007  *  Copyright (C) 1999-2007 Helge Deller <deller@gmx.de>
0008  *
0009  *  Very basic HP Human Interface Loop (HIL) driver.
0010  *  This driver handles the keyboard on HP300 (m68k) and on some
0011  *  HP700 (parisc) series machines.
0012  */
0013 
0014 #include <linux/pci_ids.h>
0015 #include <linux/ioport.h>
0016 #include <linux/module.h>
0017 #include <linux/errno.h>
0018 #include <linux/input.h>
0019 #include <linux/init.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/hil.h>
0022 #include <linux/io.h>
0023 #include <linux/sched.h>
0024 #include <linux/spinlock.h>
0025 #include <asm/irq.h>
0026 #ifdef CONFIG_HP300
0027 #include <asm/hwtest.h>
0028 #endif
0029 
0030 
0031 MODULE_AUTHOR("Philip Blundell, Matthew Wilcox, Helge Deller");
0032 MODULE_DESCRIPTION("HIL keyboard driver (basic functionality)");
0033 MODULE_LICENSE("GPL v2");
0034 
0035 
0036 #if defined(CONFIG_PARISC)
0037 
0038  #include <asm/io.h>
0039  #include <asm/hardware.h>
0040  #include <asm/parisc-device.h>
0041  static unsigned long hil_base; /* HPA for the HIL device */
0042  static unsigned int hil_irq;
0043  #define HILBASE        hil_base /* HPPA (parisc) port address */
0044  #define HIL_DATA       0x800
0045  #define HIL_CMD        0x801
0046  #define HIL_IRQ        hil_irq
0047  #define hil_readb(p)       gsc_readb(p)
0048  #define hil_writeb(v,p)    gsc_writeb((v),(p))
0049 
0050 #elif defined(CONFIG_HP300)
0051 
0052  #define HILBASE        0xf0428000UL /* HP300 (m68k) port address */
0053  #define HIL_DATA       0x1
0054  #define HIL_CMD        0x3
0055  #define HIL_IRQ        2
0056  #define hil_readb(p)       readb((const volatile void __iomem *)(p))
0057  #define hil_writeb(v, p)   writeb((v), (volatile void __iomem *)(p))
0058 
0059 #else
0060 #error "HIL is not supported on this platform"
0061 #endif
0062 
0063 
0064 
0065 /* HIL helper functions */
0066 
0067 #define hil_busy()              (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY)
0068 #define hil_data_available()    (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY)
0069 #define hil_status()            (hil_readb(HILBASE + HIL_CMD))
0070 #define hil_command(x)          do { hil_writeb((x), HILBASE + HIL_CMD); } while (0)
0071 #define hil_read_data()         (hil_readb(HILBASE + HIL_DATA))
0072 #define hil_write_data(x)       do { hil_writeb((x), HILBASE + HIL_DATA); } while (0)
0073 
0074 /* HIL constants */
0075 
0076 #define HIL_BUSY        0x02
0077 #define HIL_DATA_RDY        0x01
0078 
0079 #define HIL_SETARD      0xA0        /* set auto-repeat delay */
0080 #define HIL_SETARR      0xA2        /* set auto-repeat rate */
0081 #define HIL_SETTONE     0xA3        /* set tone generator */
0082 #define HIL_CNMT        0xB2        /* clear nmi */
0083 #define HIL_INTON       0x5C        /* Turn on interrupts. */
0084 #define HIL_INTOFF      0x5D        /* Turn off interrupts. */
0085 
0086 #define HIL_READKBDSADR     0xF9
0087 #define HIL_WRITEKBDSADR    0xE9
0088 
0089 static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly =
0090     { HIL_KEYCODES_SET1 };
0091 
0092 /* HIL structure */
0093 static struct {
0094     struct input_dev *dev;
0095 
0096     unsigned int curdev;
0097 
0098     unsigned char s;
0099     unsigned char c;
0100     int valid;
0101 
0102     unsigned char data[16];
0103     unsigned int ptr;
0104     spinlock_t lock;
0105 
0106     void *dev_id;   /* native bus device */
0107 } hil_dev;
0108 
0109 
0110 static void poll_finished(void)
0111 {
0112     int down;
0113     int key;
0114     unsigned char scode;
0115 
0116     switch (hil_dev.data[0]) {
0117     case 0x40:
0118         down = (hil_dev.data[1] & 1) == 0;
0119         scode = hil_dev.data[1] >> 1;
0120         key = hphilkeyb_keycode[scode];
0121         input_report_key(hil_dev.dev, key, down);
0122         break;
0123     }
0124     hil_dev.curdev = 0;
0125 }
0126 
0127 
0128 static inline void handle_status(unsigned char s, unsigned char c)
0129 {
0130     if (c & 0x8) {
0131         /* End of block */
0132         if (c & 0x10)
0133             poll_finished();
0134     } else {
0135         if (c & 0x10) {
0136             if (hil_dev.curdev)
0137                 poll_finished();  /* just in case */
0138             hil_dev.curdev = c & 7;
0139             hil_dev.ptr = 0;
0140         }
0141     }
0142 }
0143 
0144 
0145 static inline void handle_data(unsigned char s, unsigned char c)
0146 {
0147     if (hil_dev.curdev) {
0148         hil_dev.data[hil_dev.ptr++] = c;
0149         hil_dev.ptr &= 15;
0150     }
0151 }
0152 
0153 
0154 /* handle HIL interrupts */
0155 static irqreturn_t hil_interrupt(int irq, void *handle)
0156 {
0157     unsigned char s, c;
0158 
0159     s = hil_status();
0160     c = hil_read_data();
0161 
0162     switch (s >> 4) {
0163     case 0x5:
0164         handle_status(s, c);
0165         break;
0166     case 0x6:
0167         handle_data(s, c);
0168         break;
0169     case 0x4:
0170         hil_dev.s = s;
0171         hil_dev.c = c;
0172         mb();
0173         hil_dev.valid = 1;
0174         break;
0175     }
0176     return IRQ_HANDLED;
0177 }
0178 
0179 
0180 /* send a command to the HIL */
0181 static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
0182 {
0183     unsigned long flags;
0184 
0185     spin_lock_irqsave(&hil_dev.lock, flags);
0186     while (hil_busy())
0187         /* wait */;
0188     hil_command(cmd);
0189     while (len--) {
0190         while (hil_busy())
0191             /* wait */;
0192         hil_write_data(*(data++));
0193     }
0194     spin_unlock_irqrestore(&hil_dev.lock, flags);
0195 }
0196 
0197 
0198 /* initialize HIL */
0199 static int hil_keyb_init(void)
0200 {
0201     unsigned char c;
0202     unsigned int i, kbid;
0203     wait_queue_head_t hil_wait;
0204     int err;
0205 
0206     if (hil_dev.dev)
0207         return -ENODEV; /* already initialized */
0208 
0209     init_waitqueue_head(&hil_wait);
0210     spin_lock_init(&hil_dev.lock);
0211 
0212     hil_dev.dev = input_allocate_device();
0213     if (!hil_dev.dev)
0214         return -ENOMEM;
0215 
0216     err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
0217     if (err) {
0218         printk(KERN_ERR "HIL: Can't get IRQ\n");
0219         goto err1;
0220     }
0221 
0222     /* Turn on interrupts */
0223     hil_do(HIL_INTON, NULL, 0);
0224 
0225     /* Look for keyboards */
0226     hil_dev.valid = 0;  /* clear any pending data */
0227     hil_do(HIL_READKBDSADR, NULL, 0);
0228 
0229     wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3 * HZ);
0230     if (!hil_dev.valid)
0231         printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n");
0232 
0233     c = hil_dev.c;
0234     hil_dev.valid = 0;
0235     if (c == 0) {
0236         kbid = -1;
0237         printk(KERN_WARNING "HIL: no keyboard present\n");
0238     } else {
0239         kbid = ffz(~c);
0240         printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid);
0241     }
0242 
0243     /* set it to raw mode */
0244     c = 0;
0245     hil_do(HIL_WRITEKBDSADR, &c, 1);
0246 
0247     for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
0248         if (hphilkeyb_keycode[i] != KEY_RESERVED)
0249             __set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
0250 
0251     hil_dev.dev->evbit[0]   = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
0252     hil_dev.dev->ledbit[0]  = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
0253         BIT_MASK(LED_SCROLLL);
0254     hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
0255     hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]);
0256     hil_dev.dev->keycode    = hphilkeyb_keycode;
0257     hil_dev.dev->name   = "HIL keyboard";
0258     hil_dev.dev->phys   = "hpkbd/input0";
0259 
0260     hil_dev.dev->id.bustype = BUS_HIL;
0261     hil_dev.dev->id.vendor  = PCI_VENDOR_ID_HP;
0262     hil_dev.dev->id.product = 0x0001;
0263     hil_dev.dev->id.version = 0x0010;
0264 
0265     err = input_register_device(hil_dev.dev);
0266     if (err) {
0267         printk(KERN_ERR "HIL: Can't register device\n");
0268         goto err2;
0269     }
0270 
0271     printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
0272            hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
0273 
0274     return 0;
0275 
0276 err2:
0277     hil_do(HIL_INTOFF, NULL, 0);
0278     free_irq(HIL_IRQ, hil_dev.dev_id);
0279 err1:
0280     input_free_device(hil_dev.dev);
0281     hil_dev.dev = NULL;
0282     return err;
0283 }
0284 
0285 static void hil_keyb_exit(void)
0286 {
0287     if (HIL_IRQ)
0288         free_irq(HIL_IRQ, hil_dev.dev_id);
0289 
0290     /* Turn off interrupts */
0291     hil_do(HIL_INTOFF, NULL, 0);
0292 
0293     input_unregister_device(hil_dev.dev);
0294     hil_dev.dev = NULL;
0295 }
0296 
0297 #if defined(CONFIG_PARISC)
0298 static int __init hil_probe_chip(struct parisc_device *dev)
0299 {
0300     /* Only allow one HIL keyboard */
0301     if (hil_dev.dev)
0302         return -ENODEV;
0303 
0304     if (!dev->irq) {
0305         printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%p\n",
0306             (void *)dev->hpa.start);
0307         return -ENODEV;
0308     }
0309 
0310     hil_base = dev->hpa.start;
0311     hil_irq  = dev->irq;
0312     hil_dev.dev_id = dev;
0313 
0314     printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq);
0315 
0316     return hil_keyb_init();
0317 }
0318 
0319 static void __exit hil_remove_chip(struct parisc_device *dev)
0320 {
0321     hil_keyb_exit();
0322 }
0323 
0324 static const struct parisc_device_id hil_tbl[] __initconst = {
0325     { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
0326     { 0, }
0327 };
0328 
0329 #if 0
0330 /* Disabled to avoid conflicts with the HP SDC HIL drivers */
0331 MODULE_DEVICE_TABLE(parisc, hil_tbl);
0332 #endif
0333 
0334 static struct parisc_driver hil_driver __refdata = {
0335     .name       = "hil",
0336     .id_table   = hil_tbl,
0337     .probe      = hil_probe_chip,
0338     .remove     = __exit_p(hil_remove_chip),
0339 };
0340 
0341 static int __init hil_init(void)
0342 {
0343     return register_parisc_driver(&hil_driver);
0344 }
0345 
0346 static void __exit hil_exit(void)
0347 {
0348     unregister_parisc_driver(&hil_driver);
0349 }
0350 
0351 #else /* !CONFIG_PARISC */
0352 
0353 static int __init hil_init(void)
0354 {
0355     int error;
0356 
0357     /* Only allow one HIL keyboard */
0358     if (hil_dev.dev)
0359         return -EBUSY;
0360 
0361     if (!MACH_IS_HP300)
0362         return -ENODEV;
0363 
0364     if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
0365         printk(KERN_ERR "HIL: hardware register was not found\n");
0366         return -ENODEV;
0367     }
0368 
0369     if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
0370         printk(KERN_ERR "HIL: IOPORT region already used\n");
0371         return -EIO;
0372     }
0373 
0374     error = hil_keyb_init();
0375     if (error) {
0376         release_region(HILBASE + HIL_DATA, 2);
0377         return error;
0378     }
0379 
0380     return 0;
0381 }
0382 
0383 static void __exit hil_exit(void)
0384 {
0385     hil_keyb_exit();
0386     release_region(HILBASE + HIL_DATA, 2);
0387 }
0388 
0389 #endif /* CONFIG_PARISC */
0390 
0391 module_init(hil_init);
0392 module_exit(hil_exit);