Changeset ec2c55a in mainline


Ignore:
Timestamp:
2006-08-11T09:35:01Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f9a56c0
Parents:
2d99709
Message:

Rework the z8530 driver so that it is based on z8530 specification rather
than on accidental and limited "compatibility" with i8042.

Location:
kernel
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/include/drivers/z8530.h

    r2d99709 rec2c55a  
    3737
    3838#include <arch/types.h>
     39#include <typedefs.h>
    3940#include <arch/drivers/kbd.h>
    4041
    41 #define STATUS_REG      4
    42 #define COMMAND_REG     4
    43 #define DATA_REG        6
     42#define Z8530_CHAN_A    4
     43#define Z8530_CHAN_B    0
    4444
    45 #define LAST_REG        DATA_REG
     45#define WR0     0
     46#define WR1     1
     47#define WR2     2
     48#define WR3     3
     49#define WR4     4
     50#define WR5     5
     51#define WR6     6
     52#define WR7     7
     53#define WR8     8
     54#define WR9     9
     55#define WR10    10
     56#define WR11    11
     57#define WR12    12
     58#define WR13    13
     59#define WR14    14
     60#define WR15    15
    4661
    47 static inline void z8530_data_write(uint8_t data)
     62#define RR0     0
     63#define RR1     1
     64#define RR2     2
     65#define RR3     3
     66#define RR8     8
     67#define RR10    10
     68#define RR12    12
     69#define RR13    13
     70#define RR14    14
     71#define RR15    15
     72
     73/* Write Register 1 */
     74#define WR1_RID         (0x0<<3)        /** Receive Interrupts Disabled. */
     75#define WR1_RIFCSC      (0x1<<3)        /** Receive Interrupt on First Character or Special Condition. */
     76#define WR1_IARCSC      (0x2<<3)        /** Interrupt on All Receive Characters or Special Conditions. */
     77#define WR1_RISC        (0x3<<3)        /** Receive Interrupt on Special Condition. */
     78#define WR1_PISC        (0x1<<2)        /** Parity Is Special Condition. */
     79
     80/* Write Register 3 */
     81#define WR3_RX_ENABLE   (0x1<<0)        /** Rx Enable. */
     82#define WR3_RX8BITSCH   (0x3<<6)        /** 8-bits per character. */
     83
     84/* Write Register 9 */
     85#define WR9_MIE         (0x1<<3)        /** Master Interrupt Enable. */
     86
     87/* Read Register 0 */
     88#define RR0_RCA         (0x1<<0)        /** Receive Character Available. */
     89
     90static inline void z8530_write(index_t chan, uint8_t reg, uint8_t val)
    4891{
    49         kbd_virt_address[DATA_REG] = data;
     92        /*
     93         * Registers 8-15 will automatically issue the Point High
     94         * command as their bit 3 is 1.
     95         */
     96        kbd_virt_address[WR0+chan] = reg;       /* select register */
     97        kbd_virt_address[WR0+chan] = val;       /* write value */
    5098}
    5199
    52 static inline uint8_t z8530_data_read(void)
     100static inline void z8530_write_a(uint8_t reg, uint8_t val)
    53101{
    54         return kbd_virt_address[DATA_REG];
     102        z8530_write(Z8530_CHAN_A, reg, val);
     103}
     104static inline void z8530_write_b(uint8_t reg, uint8_t val)
     105{
     106        z8530_write(Z8530_CHAN_B, reg, val);
    55107}
    56108
    57 static inline uint8_t z8530_status_read(void)
     109static inline uint8_t z8530_read(index_t chan, uint8_t reg)
    58110{
    59         return kbd_virt_address[STATUS_REG];
     111        /*
     112         * Registers 8-15 will automatically issue the Point High
     113         * command as their bit 3 is 1.
     114         */
     115        kbd_virt_address[WR0+chan] = reg;       /* select register */
     116        return kbd_virt_address[WR0+chan];
    60117}
    61118
    62 static inline void z8530_command_write(uint8_t command)
     119static inline uint8_t z8530_read_a(uint8_t reg)
    63120{
    64         kbd_virt_address[COMMAND_REG] = command;
     121        return z8530_read(Z8530_CHAN_A, reg);
     122}
     123static inline uint8_t z8530_read_b(uint8_t reg)
     124{
     125        return z8530_read(Z8530_CHAN_B, reg);
    65126}
    66127
  • kernel/genarch/src/kbd/z8530.c

    r2d99709 rec2c55a  
    3333 * @file
    3434 * @brief       Zilog 8530 serial port / keyboard driver.
    35  *
    36  * Note that this file is derived from the i8042.c.
    37  * The i8042 driver could be persuaded to control
    38  * the z8530 at least in the polling mode.
    39  * As a result, this file may contain inaccurate
    40  * and z8530-irrelevant constants, code and comments.
    41  * Still it miraculously works.
    4235 */
    4336
     
    4740#include <genarch/kbd/scanc_sun.h>
    4841#include <arch/drivers/z8530.h>
     42#include <arch/drivers/kbd.h>
    4943#include <arch/interrupt.h>
    5044#include <cpu.h>
     
    5549#include <console/console.h>
    5650#include <interrupt.h>
    57 
    58 /* Keyboard commands. */
    59 #define KBD_ENABLE      0xf4
    60 #define KBD_DISABLE     0xf5
    61 #define KBD_ACK         0xfa
    62 
    63 /*
    64  * 60  Write 8042 Command Byte: next data byte written to port 60h is
    65  *     placed in 8042 command register. Format:
    66  *
    67  *    |7|6|5|4|3|2|1|0|8042 Command Byte
    68  *     | | | | | | | `---- 1=enable output register full interrupt
    69  *     | | | | | | `----- should be 0
    70  *     | | | | | `------ 1=set status register system, 0=clear
    71  *     | | | | `------- 1=override keyboard inhibit, 0=allow inhibit
    72  *     | | | `-------- disable keyboard I/O by driving clock line low
    73  *     | | `--------- disable auxiliary device, drives clock line low
    74  *     | `---------- IBM scancode translation 0=AT, 1=PC/XT
    75  *     `----------- reserved, should be 0
    76  */
    77 
    78 #define z8530_SET_COMMAND       0x60
    79 #define z8530_COMMAND           0x69
    80 
    81 #define z8530_BUFFER_FULL_MASK  0x01
    82 #define z8530_WAIT_MASK         0x02
    83 #define z8530_MOUSE_DATA        0x20
    8451
    8552/*
     
    9865};
    9966
    100 static void z8530_interrupt(int n, istate_t *istate);
    101 static void z8530_wait(void);
     67void z8530_interrupt(int n, istate_t *istate);
     68void z8530_wait(void);
    10269
    103 static iroutine oldvector;
    10470/** Initialize keyboard and service interrupts using kernel routine */
    10571void z8530_grab(void)
    10672{
    107         oldvector = exc_register(VECTOR_KBD, "z8530_interrupt", (iroutine) z8530_interrupt);
    108         z8530_wait();
    109         z8530_command_write(z8530_SET_COMMAND);
    110         z8530_wait();
    111         z8530_data_write(z8530_COMMAND);
    112         z8530_wait();
    11373}
    11474/** Resume the former interrupt vector */
    11575void z8530_release(void)
    11676{
    117         if (oldvector)
    118                 exc_register(VECTOR_KBD, "user_interrupt", oldvector);
    11977}
     78
     79#include <print.h>
    12080
    12181/** Initialize z8530. */
    12282void z8530_init(void)
    12383{
    124         int i;
    125 
    126         z8530_grab();
    127         /* Prevent user from accidentaly releasing calling z8530_resume
    128          * and disabling keyboard
    129          */
    130         oldvector = NULL;
    131 
    132         trap_virtual_enable_irqs(1<<IRQ_KBD);
    13384        chardev_initialize("z8530_kbd", &kbrd, &ops);
    13485        stdin = &kbrd;
    13586
    136         /*
    137          * Clear input buffer.
    138          * Number of iterations is limited to prevent infinite looping.
    139         */
    140         for (i = 0; (z8530_status_read() & z8530_BUFFER_FULL_MASK) && i < 100; i++) {
    141                 z8530_data_read();
    142        
     87        z8530_write_a(WR1, WR1_IARCSC); /* interrupt on all characters */
     88        z8530_write_a(WR2, 12);         /* FIXME: IRQ12 ??? */
     89
     90        /* 8 bits per character and enable receiver */
     91        z8530_write_a(WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);
     92       
     93        z8530_write_a(WR9, WR9_MIE);    /* Master Interrupt Enable. */
    14394}
    14495
     
    150101void z8530_interrupt(int n, istate_t *istate)
    151102{
    152         uint8_t x;
    153         uint8_t status;
    154 
    155         while (((status=z8530_status_read()) & z8530_BUFFER_FULL_MASK)) {
    156                 x = z8530_data_read();
    157 
    158                 if ((status & z8530_MOUSE_DATA))
    159                         continue;
    160 
    161                 if (x & KEY_RELEASE)
    162                         key_released(x ^ KEY_RELEASE);
    163                 else
    164                         key_pressed(x);
    165         }
    166         trap_virtual_eoi();
    167103}
    168104
    169105/** Wait until the controller reads its data. */
    170106void z8530_wait(void) {
    171         while (z8530_status_read() & z8530_WAIT_MASK) {
    172                 /* wait */
    173         }
    174107}
    175108
     
    190123        while(!(ch = active_read_buff_read())) {
    191124                uint8_t x;
    192                 while (!(z8530_status_read() & z8530_BUFFER_FULL_MASK))
     125                while (!(z8530_read_a(RR0) & RR0_RCA))
    193126                        ;
    194                 x = z8530_data_read();
     127                x = z8530_read_a(RR8);
    195128                if (x != IGNORE_CODE) {
    196129                        if (x & KEY_RELEASE)
     
    211144        uint8_t x;
    212145
    213         while (((x = z8530_status_read() & z8530_BUFFER_FULL_MASK))) {
    214                 x = z8530_data_read();
     146        while (z8530_read_a(RR0) & RR0_RCA) {
     147                x = z8530_read_a(RR8);
    215148                if (x != IGNORE_CODE) {
    216149                        if (x & KEY_RELEASE)
Note: See TracChangeset for help on using the changeset viewer.