Changeset 75fe97b in mainline for uspace/drv/char/pl050/pl050.c


Ignore:
Timestamp:
2014-09-03T10:52:10Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
95b2276
Parents:
b3222a3
Message:

IntegratorCP mouse support.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/char/pl050/pl050.c

    rb3222a3 r75fe97b  
    3232
    3333#include <assert.h>
     34#include <bitops.h>
    3435#include <stdio.h>
    3536#include <errno.h>
     
    3940#include <device/hw_res_parsed.h>
    4041#include <io/chardev_srv.h>
     42#include <irc.h>
     43
     44#include "pl050_hw.h"
    4145
    4246#define NAME "pl050"
    43 
    44 #define PL050_STAT      4
    45 #define PL050_DATA      8
    46 
    47 #define PL050_STAT_RXFULL  (1 << 4)
    4847
    4948enum {
     
    7776        async_sess_t *parent_sess;
    7877        ddf_dev_t *dev;
     78        char *name;
    7979
    8080        ddf_fun_t *fun_a;
     
    8383        uintptr_t iobase;
    8484        size_t iosize;
     85        kmi_regs_t *regs;
    8586        uint8_t buffer[buffer_size];
    8687        size_t buf_rp;
     
    105106        {
    106107                .cmd = CMD_AND,
    107                 .value = PL050_STAT_RXFULL,
     108                .value = BIT_V(uint8_t, kmi_stat_rxfull),
    108109                .srcarg = 1,
    109110                .dstarg = 3
     
    159160{
    160161        hw_res_list_parsed_t res;
     162        void *regs;
    161163        int rc;
    162164
     
    190192
    191193        pl050_irq_code.ranges[0].base = pl050->iobase;
    192         pl050_irq_code.cmds[0].addr = (void *) pl050->iobase + PL050_STAT;
    193         pl050_irq_code.cmds[3].addr = (void *) pl050->iobase + PL050_DATA;
     194        kmi_regs_t *regsphys = (kmi_regs_t *) pl050->iobase;
     195        pl050_irq_code.cmds[0].addr = &regsphys->stat;
     196        pl050_irq_code.cmds[3].addr = &regsphys->data;
    194197
    195198        if (res.irqs.count != 1) {
     
    202205            res.irqs.irqs[0]);
    203206
     207        rc = pio_enable((void *)pl050->iobase, sizeof(kmi_regs_t), &regs);
     208        if (rc != EOK) {
     209                ddf_msg(LVL_ERROR, "Error enabling PIO");
     210                goto error;
     211        }
     212
     213        pl050->regs = regs;
     214
    204215        rc = register_interrupt_handler(pl050->dev, res.irqs.irqs[0],
    205216            pl050_interrupt, &pl050_irq_code);
     
    209220                goto error;
    210221        }
     222
     223        rc = irc_enable_interrupt(res.irqs.irqs[0]);
     224        if (rc != EOK) {
     225                ddf_msg(LVL_ERROR, "Failed enabling interrupt. (%d)", rc);
     226                goto error;
     227        }
     228
     229        pio_write_8(&pl050->regs->cr,
     230            BIT_V(uint8_t, kmi_cr_enable) |
     231            BIT_V(uint8_t, kmi_cr_rxintr));
    211232
    212233        return EOK;
     
    220241        uint8_t *bp = buffer;
    221242        size_t left;
     243
    222244        fibril_mutex_lock(&pl050->buf_lock);
    223245
     
    238260static int pl050_write(chardev_srv_t *srv, const void *data, size_t size)
    239261{
     262        pl050_t *pl050 = (pl050_t *)srv->srvs->sarg;
     263        uint8_t *dp = (uint8_t *)data;
     264        uint8_t status;
     265        size_t i;
     266
     267        ddf_msg(LVL_NOTE, "%s/pl050_write(%zu bytes)", pl050->name, size);
     268        for (i = 0; i < size; i++) {
     269                while (true) {
     270                        status = pio_read_8(&pl050->regs->stat);
     271                        if ((status & BIT_V(uint8_t, kmi_stat_txempty)) != 0)
     272                                break;
     273                }
     274                pio_write_8(&pl050->regs->data, dp[i]);
     275        }
     276        ddf_msg(LVL_NOTE, "%s/pl050_write() success", pl050->name);
     277
    240278        return size;
    241279}
     
    252290{
    253291        ddf_fun_t *fun_a;
    254         pl050_t *pl050;
     292        pl050_t *pl050 = NULL;
     293        const char *mname;
    255294        int rc;
    256295
     
    264303        }
    265304
     305        pl050->name = (char *)ddf_dev_get_name(dev);
     306        if (pl050->name == NULL) {
     307                rc = ENOMEM;
     308                goto error;
     309        }
     310
    266311        fun_a = ddf_fun_create(dev, fun_inner, "a");
    267312        if (fun_a == NULL) {
     
    278323                goto error;
    279324
    280         rc = ddf_fun_add_match_id(fun_a, "char/xtkbd", 10);
     325        if (str_cmp(pl050->name, "kbd") == 0)
     326                mname = "char/xtkbd";
     327        else
     328                mname = "char/ps2mouse";
     329
     330        rc = ddf_fun_add_match_id(fun_a, mname, 10);
    281331        if (rc != EOK) {
    282332                ddf_msg(LVL_ERROR, "Failed adding match IDs to function %s",
     
    284334                goto error;
    285335        }
    286 
    287336
    288337        chardev_srvs_init(&pl050->cds);
     
    302351        return EOK;
    303352error:
     353        if (pl050 != NULL)
     354                free(pl050->name);
    304355        return rc;
    305356}
Note: See TracChangeset for help on using the changeset viewer.