Ignore:
Timestamp:
2009-07-02T19:39:29Z (15 years ago)
Author:
Jiri Svoboda <jirik.svoboda@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d68e4d5
Parents:
bb8dc88
Message:

Kernel Mac ADB keyboard driver revived.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/drivers/via-cuda/cuda.c

    rbb8dc88 r2a77841d  
    11/*
    22 * Copyright (c) 2006 Martin Decky
     3 * Copyright (c) 2009 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    3940#include <mm/slab.h>
    4041#include <ddi/device.h>
     42#include <synch/spinlock.h>
     43
     44static void cuda_packet_handle(cuda_instance_t *instance, size_t len);
     45
     46/** B register fields */
     47enum {
     48        TREQ    = 0x08,
     49        TACK    = 0x10,
     50        TIP     = 0x20
     51};
     52
     53/** IER register fields */
     54enum {
     55        IER_SET = 0x80,
     56        SR_INT  = 0x04
     57};
    4158
    4259static irq_ownership_t cuda_claim(irq_t *irq)
    4360{
    44         return IRQ_DECLINE;
     61        cuda_instance_t *instance = irq->instance;
     62        cuda_t *dev = instance->cuda;
     63        uint8_t ifr;
     64
     65        ifr = pio_read_8(&dev->ifr);
     66
     67        if ((ifr & SR_INT) != 0)
     68                return IRQ_ACCEPT;
     69        else
     70                return IRQ_DECLINE;
    4571}
    4672
    4773static void cuda_irq_handler(irq_t *irq)
    4874{
     75        cuda_instance_t *instance = irq->instance;
     76        cuda_t *dev = instance->cuda;
     77        uint8_t b, data;
     78        size_t pos;
     79
     80        spinlock_lock(&instance->dev_lock);
     81
     82        /* We have received one or more CUDA packets. Process them all. */
     83        while (true) {
     84                b = pio_read_8(&dev->b);
     85
     86                if ((b & TREQ) != 0)
     87                        break;  /* No data */
     88
     89                pio_write_8(&dev->b, b & ~TIP);
     90
     91                /* Read one packet. */
     92
     93                pos = 0;
     94                do {
     95                        data = pio_read_8(&dev->sr);
     96                        b = pio_read_8(&dev->b);
     97                        pio_write_8(&dev->b, b ^ TACK);
     98
     99                        if (pos < CUDA_RCV_BUF_SIZE)
     100                                instance->rcv_buf[pos++] = data;
     101                } while ((b & TREQ) == 0);
     102
     103                pio_write_8(&dev->b, b | TACK | TIP);
     104
     105                cuda_packet_handle(instance, pos);
     106        }
     107
     108        spinlock_unlock(&instance->dev_lock);
     109}
     110
     111static void cuda_packet_handle(cuda_instance_t *instance, size_t len)
     112{
     113        uint8_t *data = instance->rcv_buf;
     114
     115        if (data[0] != 0x00 || data[1] != 0x40 || data[2] != 0x2c)
     116                return;
     117
     118        /* The packet contains one or two scancodes. */
     119        if (data[3] != 0xff)
     120                indev_push_character(instance->kbrdin, data[3]);               
     121        if (data[4] != 0xff)
     122                indev_push_character(instance->kbrdin, data[4]);
    49123}
    50124
     
    56130                instance->cuda = dev;
    57131                instance->kbrdin = NULL;
    58                
     132
     133                spinlock_initialize(&instance->dev_lock, "cuda_dev");
     134
    59135                irq_initialize(&instance->irq);
    60136                instance->irq.devno = device_assign_devno();
     
    72148void cuda_wire(cuda_instance_t *instance, indev_t *kbrdin)
    73149{
     150        ASSERT(instance);
     151        ASSERT(kbrdin);
     152
     153        instance->kbrdin = kbrdin;
     154        irq_register(&instance->irq);
     155
     156        /* Enable SR interrupt. */
     157        pio_write_8(&instance->cuda->ier, IER_SET | SR_INT);
    74158}
    75 
    76159
    77160/** @}
Note: See TracChangeset for help on using the changeset viewer.