linux/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
   3 *
   4 *      ADDI-DATA GmbH
   5 *      Dieselstrasse 3
   6 *      D-77833 Ottersweier
   7 *      Tel: +19(0)7223/9493-0
   8 *      Fax: +49(0)7223/9493-92
   9 *      http://www.addi-data.com
  10 *      info@addi-data.com
  11 *
  12 * This program is free software; you can redistribute it and/or modify it
  13 * under the terms of the GNU General Public License as published by the Free
  14 * Software Foundation; either version 2 of the License, or (at your option)
  15 * any later version.
  16 */
  17
  18/* Header file for AMCC  s 5933 */
  19
  20#ifndef _AMCC_S5933_H_
  21#define _AMCC_S5933_H_
  22
  23#include "../../comedidev.h"
  24
  25#include "../comedi_pci.h"
  26
  27#ifdef PCI_SUPPORT_VER1
  28#error     No support for 2.1.55 and older
  29#endif
  30
  31/* written on base0 */
  32#define FIFO_ADVANCE_ON_BYTE_2  0x20000000
  33
  34/* added for step 6 dma written on base2 */
  35#define AMWEN_ENABLE            0x02
  36
  37#define A2P_FIFO_WRITE_ENABLE   0x01
  38
  39/* for transfer count enable bit */
  40#define AGCSTS_TC_ENABLE        0x10000000
  41
  42/*
  43 * ADDON RELATED ADDITIONS
  44 */
  45/* Constant */
  46#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW             0x00
  47#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH            0x1200
  48#define APCI3120_A2P_FIFO_MANAGEMENT                    0x04000400L
  49#define APCI3120_AMWEN_ENABLE                           0x02
  50#define APCI3120_A2P_FIFO_WRITE_ENABLE                  0x01
  51#define APCI3120_FIFO_ADVANCE_ON_BYTE_2                 0x20000000L
  52#define APCI3120_ENABLE_WRITE_TC_INT                    0x00004000L
  53#define APCI3120_CLEAR_WRITE_TC_INT                     0x00040000L
  54#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE       0x0
  55#define APCI3120_DISABLE_BUS_MASTER_ADD_ON              0x0
  56#define APCI3120_DISABLE_BUS_MASTER_PCI                 0x0
  57
  58/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */
  59#define APCI3120_ADD_ON_AGCSTS_LOW      0x3C
  60#define APCI3120_ADD_ON_AGCSTS_HIGH     (APCI3120_ADD_ON_AGCSTS_LOW + 2)
  61#define APCI3120_ADD_ON_MWAR_LOW        0x24
  62#define APCI3120_ADD_ON_MWAR_HIGH       (APCI3120_ADD_ON_MWAR_LOW + 2)
  63#define APCI3120_ADD_ON_MWTC_LOW        0x058
  64#define APCI3120_ADD_ON_MWTC_HIGH       (APCI3120_ADD_ON_MWTC_LOW + 2)
  65
  66/* AMCC */
  67#define APCI3120_AMCC_OP_MCSR           0x3C
  68#define APCI3120_AMCC_OP_REG_INTCSR     0x38
  69
  70/*
  71 * AMCC Operation Register Offsets - PCI
  72 */
  73#define AMCC_OP_REG_OMB1                0x00
  74#define AMCC_OP_REG_OMB2                0x04
  75#define AMCC_OP_REG_OMB3                0x08
  76#define AMCC_OP_REG_OMB4                0x0c
  77#define AMCC_OP_REG_IMB1                0x10
  78#define AMCC_OP_REG_IMB2                0x14
  79#define AMCC_OP_REG_IMB3                0x18
  80#define AMCC_OP_REG_IMB4                0x1c
  81#define AMCC_OP_REG_FIFO                0x20
  82#define AMCC_OP_REG_MWAR                0x24
  83#define AMCC_OP_REG_MWTC                0x28
  84#define AMCC_OP_REG_MRAR                0x2c
  85#define AMCC_OP_REG_MRTC                0x30
  86#define AMCC_OP_REG_MBEF                0x34
  87#define AMCC_OP_REG_INTCSR              0x38
  88/* int source */
  89#define  AMCC_OP_REG_INTCSR_SRC         (AMCC_OP_REG_INTCSR + 2)
  90/* FIFO ctrl */
  91#define  AMCC_OP_REG_INTCSR_FEC         (AMCC_OP_REG_INTCSR + 3)
  92#define AMCC_OP_REG_MCSR                0x3c
  93/* Data in byte 2 */
  94#define  AMCC_OP_REG_MCSR_NVDATA        (AMCC_OP_REG_MCSR + 2)
  95/* Command in byte 3 */
  96#define  AMCC_OP_REG_MCSR_NVCMD         (AMCC_OP_REG_MCSR + 3)
  97
  98#define AMCC_FIFO_DEPTH_DWORD   8
  99#define AMCC_FIFO_DEPTH_BYTES   (8 * sizeof(u32))
 100
 101/*
 102 * AMCC Operation Registers Size - PCI
 103 */
 104#define AMCC_OP_REG_SIZE         64     /* in bytes */
 105
 106/*
 107 * AMCC Operation Register Offsets - Add-on
 108 */
 109#define AMCC_OP_REG_AIMB1       0x00
 110#define AMCC_OP_REG_AIMB2       0x04
 111#define AMCC_OP_REG_AIMB3       0x08
 112#define AMCC_OP_REG_AIMB4       0x0c
 113#define AMCC_OP_REG_AOMB1       0x10
 114#define AMCC_OP_REG_AOMB2       0x14
 115#define AMCC_OP_REG_AOMB3       0x18
 116#define AMCC_OP_REG_AOMB4       0x1c
 117#define AMCC_OP_REG_AFIFO       0x20
 118#define AMCC_OP_REG_AMWAR       0x24
 119#define AMCC_OP_REG_APTA        0x28
 120#define AMCC_OP_REG_APTD        0x2c
 121#define AMCC_OP_REG_AMRAR       0x30
 122#define AMCC_OP_REG_AMBEF       0x34
 123#define AMCC_OP_REG_AINT        0x38
 124#define AMCC_OP_REG_AGCSTS      0x3c
 125#define AMCC_OP_REG_AMWTC       0x58
 126#define AMCC_OP_REG_AMRTC       0x5c
 127
 128/*
 129 * AMCC - Add-on General Control/Status Register
 130 */
 131#define AGCSTS_CONTROL_MASK     0xfffff000
 132#define  AGCSTS_NV_ACC_MASK     0xe0000000
 133#define  AGCSTS_RESET_MASK      0x0e000000
 134#define  AGCSTS_NV_DA_MASK      0x00ff0000
 135#define  AGCSTS_BIST_MASK       0x0000f000
 136#define AGCSTS_STATUS_MASK      0x000000ff
 137#define  AGCSTS_TCZERO_MASK     0x000000c0
 138#define  AGCSTS_FIFO_ST_MASK    0x0000003f
 139
 140#define AGCSTS_RESET_MBFLAGS    0x08000000
 141#define AGCSTS_RESET_P2A_FIFO   0x04000000
 142#define AGCSTS_RESET_A2P_FIFO   0x02000000
 143#define AGCSTS_RESET_FIFOS      (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
 144
 145#define AGCSTS_A2P_TCOUNT       0x00000080
 146#define AGCSTS_P2A_TCOUNT       0x00000040
 147
 148#define AGCSTS_FS_P2A_EMPTY     0x00000020
 149#define AGCSTS_FS_P2A_HALF      0x00000010
 150#define AGCSTS_FS_P2A_FULL      0x00000008
 151
 152#define AGCSTS_FS_A2P_EMPTY     0x00000004
 153#define AGCSTS_FS_A2P_HALF      0x00000002
 154#define AGCSTS_FS_A2P_FULL      0x00000001
 155
 156/*
 157 * AMCC - Add-on Interrupt Control/Status Register
 158 */
 159#define AINT_INT_MASK           0x00ff0000
 160#define AINT_SEL_MASK           0x0000ffff
 161#define  AINT_IS_ENSEL_MASK     0x00001f1f
 162
 163#define AINT_INT_ASSERTED       0x00800000
 164#define AINT_BM_ERROR           0x00200000
 165#define AINT_BIST_INT           0x00100000
 166
 167#define AINT_RT_COMPLETE        0x00080000
 168#define AINT_WT_COMPLETE        0x00040000
 169
 170#define AINT_OUT_MB_INT         0x00020000
 171#define AINT_IN_MB_INT          0x00010000
 172
 173#define AINT_READ_COMPL         0x00008000
 174#define AINT_WRITE_COMPL        0x00004000
 175
 176#define AINT_OMB_ENABLE         0x00001000
 177#define AINT_OMB_SELECT         0x00000c00
 178#define AINT_OMB_BYTE           0x00000300
 179
 180#define AINT_IMB_ENABLE         0x00000010
 181#define AINT_IMB_SELECT         0x0000000c
 182#define AINT_IMB_BYTE           0x00000003
 183
 184/* Enable Bus Mastering */
 185#define EN_A2P_TRANSFERS        0x00000400
 186/* FIFO Flag Reset */
 187#define RESET_A2P_FLAGS         0x04000000L
 188/* FIFO Relative Priority */
 189#define A2P_HI_PRIORITY         0x00000100L
 190/* Identify Interrupt Sources */
 191#define ANY_S593X_INT           0x00800000L
 192#define READ_TC_INT             0x00080000L
 193#define WRITE_TC_INT            0x00040000L
 194#define IN_MB_INT               0x00020000L
 195#define MASTER_ABORT_INT        0x00100000L
 196#define TARGET_ABORT_INT        0x00200000L
 197#define BUS_MASTER_INT          0x00200000L
 198
 199/****************************************************************************/
 200
 201struct pcilst_struct {
 202        struct pcilst_struct *next;
 203        int used;
 204        struct pci_dev *pcidev;
 205        unsigned short vendor;
 206        unsigned short device;
 207        unsigned char pci_bus;
 208        unsigned char pci_slot;
 209        unsigned char pci_func;
 210        resource_size_t io_addr[5];
 211        unsigned int irq;
 212};
 213
 214/* ptr to root list of all amcc devices */
 215static struct pcilst_struct *amcc_devices;
 216
 217static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 };
 218
 219/****************************************************************************/
 220
 221void v_pci_card_list_init(unsigned short pci_vendor, char display);
 222void v_pci_card_list_cleanup(unsigned short pci_vendor);
 223struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
 224                                                       unsigned short
 225                                                       device_id);
 226int i_find_free_pci_card_by_position(unsigned short vendor_id,
 227                                     unsigned short device_id,
 228                                     unsigned short pci_bus,
 229                                     unsigned short pci_slot,
 230                                     struct pcilst_struct **card);
 231struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
 232                                                    unsigned short device_id,
 233                                                    unsigned short pci_bus,
 234                                                    unsigned short pci_slot,
 235                                                    int i_Master);
 236
 237int pci_card_alloc(struct pcilst_struct *amcc, int master);
 238int i_pci_card_free(struct pcilst_struct *amcc);
 239void v_pci_card_list_display(void);
 240int i_pci_card_data(struct pcilst_struct *amcc,
 241                    unsigned char *pci_bus, unsigned char *pci_slot,
 242                    unsigned char *pci_func, resource_size_t * io_addr,
 243                    unsigned int *irq);
 244
 245/****************************************************************************/
 246
 247/* build list of amcc cards in this system */
 248void v_pci_card_list_init(unsigned short pci_vendor, char display)
 249{
 250        struct pci_dev *pcidev = NULL;
 251        struct pcilst_struct *amcc, *last;
 252        int i;
 253        int i_Count = 0;
 254        amcc_devices = NULL;
 255        last = NULL;
 256
 257        for_each_pci_dev(pcidev) {
 258                for (i_Count = 0; i_Count < 2; i_Count++) {
 259                        pci_vendor = i_ADDIDATADeviceID[i_Count];
 260                        if (pcidev->vendor == pci_vendor) {
 261                                amcc = kzalloc(sizeof(*amcc), GFP_KERNEL);
 262                                if (amcc == NULL)
 263                                        continue;
 264
 265                                amcc->pcidev = pcidev;
 266                                if (last)
 267                                        last->next = amcc;
 268                                else
 269                                        amcc_devices = amcc;
 270                                last = amcc;
 271
 272                                amcc->vendor = pcidev->vendor;
 273                                amcc->device = pcidev->device;
 274                                amcc->pci_bus = pcidev->bus->number;
 275                                amcc->pci_slot = PCI_SLOT(pcidev->devfn);
 276                                amcc->pci_func = PCI_FUNC(pcidev->devfn);
 277                                /* Note: resources may be invalid if PCI device
 278                                 * not enabled, but they are corrected in
 279                                 * pci_card_alloc. */
 280                                for (i = 0; i < 5; i++)
 281                                        amcc->io_addr[i] =
 282                                            pci_resource_start(pcidev, i);
 283                                amcc->irq = pcidev->irq;
 284
 285                        }
 286                }
 287        }
 288
 289        if (display)
 290                v_pci_card_list_display();
 291}
 292
 293/****************************************************************************/
 294/* free up list of amcc cards in this system */
 295void v_pci_card_list_cleanup(unsigned short pci_vendor)
 296{
 297        struct pcilst_struct *amcc, *next;
 298
 299        for (amcc = amcc_devices; amcc; amcc = next) {
 300                next = amcc->next;
 301                kfree(amcc);
 302        }
 303
 304        amcc_devices = NULL;
 305}
 306
 307/****************************************************************************/
 308/* find first unused card with this device_id */
 309struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
 310                                                       unsigned short device_id)
 311{
 312        struct pcilst_struct *amcc, *next;
 313
 314        for (amcc = amcc_devices; amcc; amcc = next) {
 315                next = amcc->next;
 316                if ((!amcc->used) && (amcc->device == device_id)
 317                    && (amcc->vendor == vendor_id))
 318                        return amcc;
 319
 320        }
 321
 322        return NULL;
 323}
 324
 325/****************************************************************************/
 326/* find card on requested position */
 327int i_find_free_pci_card_by_position(unsigned short vendor_id,
 328                                     unsigned short device_id,
 329                                     unsigned short pci_bus,
 330                                     unsigned short pci_slot,
 331                                     struct pcilst_struct **card)
 332{
 333        struct pcilst_struct *amcc, *next;
 334
 335        *card = NULL;
 336        for (amcc = amcc_devices; amcc; amcc = next) {
 337                next = amcc->next;
 338                if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
 339                    && (amcc->pci_bus == pci_bus)
 340                    && (amcc->pci_slot == pci_slot)) {
 341                        if (!(amcc->used)) {
 342                                *card = amcc;
 343                                return 0;       /* ok, card is found */
 344                        } else {
 345                                printk(" - \nCard on requested position is used b:s %d:%d!\n",
 346                                          pci_bus, pci_slot);
 347                                return 2;       /* card exist but is used */
 348                        }
 349                }
 350        }
 351
 352        /* no card found */
 353        return 1;
 354}
 355
 356/****************************************************************************/
 357/* mark card as used */
 358int pci_card_alloc(struct pcilst_struct *amcc, int master)
 359{
 360        int i;
 361
 362        if (!amcc)
 363                return -1;
 364
 365        if (amcc->used)
 366                return 1;
 367        if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933"))
 368                return -1;
 369        /* Resources will be accurate now. */
 370        for (i = 0; i < 5; i++)
 371                amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i);
 372        if (master)
 373                pci_set_master(amcc->pcidev);
 374        amcc->used = 1;
 375
 376        return 0;
 377}
 378
 379/****************************************************************************/
 380/* mark card as free */
 381int i_pci_card_free(struct pcilst_struct *amcc)
 382{
 383        if (!amcc)
 384                return -1;
 385
 386        if (!amcc->used)
 387                return 1;
 388        amcc->used = 0;
 389        comedi_pci_disable(amcc->pcidev);
 390        return 0;
 391}
 392
 393/****************************************************************************/
 394/* display list of found cards */
 395void v_pci_card_list_display(void)
 396{
 397        struct pcilst_struct *amcc, *next;
 398
 399        printk(KERN_DEBUG "List of pci cards\n");
 400        printk(KERN_DEBUG "bus:slot:func vendor device io_amcc io_daq irq used\n");
 401
 402        for (amcc = amcc_devices; amcc; amcc = next) {
 403                next = amcc->next;
 404                printk
 405                    ("%2d   %2d   %2d  0x%4x 0x%4x   0x%8llx 0x%8llx  %2u  %2d\n",
 406                     amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
 407                     amcc->vendor, amcc->device,
 408                     (unsigned long long)amcc->io_addr[0],
 409                     (unsigned long long)amcc->io_addr[2], amcc->irq,
 410                     amcc->used);
 411
 412        }
 413}
 414
 415/****************************************************************************/
 416/* return all card information for driver */
 417int i_pci_card_data(struct pcilst_struct *amcc,
 418                    unsigned char *pci_bus, unsigned char *pci_slot,
 419                    unsigned char *pci_func, resource_size_t * io_addr,
 420                    unsigned int *irq)
 421{
 422        int i;
 423
 424        if (!amcc)
 425                return -1;
 426        *pci_bus = amcc->pci_bus;
 427        *pci_slot = amcc->pci_slot;
 428        *pci_func = amcc->pci_func;
 429        for (i = 0; i < 5; i++)
 430                io_addr[i] = amcc->io_addr[i];
 431        *irq = amcc->irq;
 432        return 0;
 433}
 434
 435/****************************************************************************/
 436/* select and alloc card */
 437struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
 438                                                    unsigned short device_id,
 439                                                    unsigned short pci_bus,
 440                                                    unsigned short pci_slot,
 441                                                    int i_Master)
 442{
 443        struct pcilst_struct *card;
 444
 445        if ((pci_bus < 1) & (pci_slot < 1)) {
 446                /* use autodetection */
 447                card = ptr_find_free_pci_card_by_device(vendor_id, device_id);
 448                if (card == NULL) {
 449                        printk(" - Unused card not found in system!\n");
 450                        return NULL;
 451                }
 452        } else {
 453                switch (i_find_free_pci_card_by_position(vendor_id, device_id,
 454                                                         pci_bus, pci_slot,
 455                                                         &card)) {
 456                case 1:
 457                        printk(" - Card not found on requested position b:s %d:%d!\n",
 458                                  pci_bus, pci_slot);
 459                        return NULL;
 460                case 2:
 461                        printk(" - Card on requested position is used b:s %d:%d!\n",
 462                                  pci_bus, pci_slot);
 463                        return NULL;
 464                }
 465        }
 466
 467        if (pci_card_alloc(card, i_Master) != 0) {
 468                printk(" - Can't allocate card!\n");
 469                return NULL;
 470
 471        }
 472
 473        return card;
 474}
 475#endif
 476