addi_amcc_s5933.h revision 5f74ea14c07fee91d3bdbaad88bff6264c6200e6
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 */ 215struct 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; 251 struct pcilst_struct *amcc, *last; 252 int i; 253 int i_Count = 0; 254 amcc_devices = NULL; 255 last = NULL; 256 257 for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); 258 pcidev != NULL; 259 pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { 260 for (i_Count = 0; i_Count < 2; i_Count++) { 261 pci_vendor = i_ADDIDATADeviceID[i_Count]; 262 if (pcidev->vendor == pci_vendor) { 263 amcc = kmalloc(sizeof(*amcc), GFP_KERNEL); 264 memset(amcc, 0, sizeof(*amcc)); 265 266 amcc->pcidev = pcidev; 267 if (last) 268 last->next = amcc; 269 else 270 amcc_devices = amcc; 271 last = amcc; 272 273 amcc->vendor = pcidev->vendor; 274 amcc->device = pcidev->device; 275 amcc->pci_bus = pcidev->bus->number; 276 amcc->pci_slot = PCI_SLOT(pcidev->devfn); 277 amcc->pci_func = PCI_FUNC(pcidev->devfn); 278 /* Note: resources may be invalid if PCI device 279 * not enabled, but they are corrected in 280 * pci_card_alloc. */ 281 for (i = 0; i < 5; i++) 282 amcc->io_addr[i] = 283 pci_resource_start(pcidev, i); 284 amcc->irq = pcidev->irq; 285 286 } 287 } 288 } 289 290 if (display) 291 v_pci_card_list_display(); 292} 293 294/****************************************************************************/ 295/* free up list of amcc cards in this system */ 296void v_pci_card_list_cleanup(unsigned short pci_vendor) 297{ 298 struct pcilst_struct *amcc, *next; 299 300 for (amcc = amcc_devices; amcc; amcc = next) { 301 next = amcc->next; 302 kfree(amcc); 303 } 304 305 amcc_devices = NULL; 306} 307 308/****************************************************************************/ 309/* find first unused card with this device_id */ 310struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, 311 unsigned short device_id) 312{ 313 struct pcilst_struct *amcc, *next; 314 315 for (amcc = amcc_devices; amcc; amcc = next) { 316 next = amcc->next; 317 if ((!amcc->used) && (amcc->device == device_id) 318 && (amcc->vendor == vendor_id)) 319 return amcc; 320 321 } 322 323 return NULL; 324} 325 326/****************************************************************************/ 327/* find card on requested position */ 328int i_find_free_pci_card_by_position(unsigned short vendor_id, 329 unsigned short device_id, 330 unsigned short pci_bus, 331 unsigned short pci_slot, 332 struct pcilst_struct **card) 333{ 334 struct pcilst_struct *amcc, *next; 335 336 *card = NULL; 337 for (amcc = amcc_devices; amcc; amcc = next) { 338 next = amcc->next; 339 if ((amcc->vendor == vendor_id) && (amcc->device == device_id) 340 && (amcc->pci_bus == pci_bus) 341 && (amcc->pci_slot == pci_slot)) { 342 if (!(amcc->used)) { 343 *card = amcc; 344 return 0; /* ok, card is found */ 345 } else { 346 printk(" - \nCard on requested position is used b:s %d:%d!\n", 347 pci_bus, pci_slot); 348 return 2; /* card exist but is used */ 349 } 350 } 351 } 352 353 /* no card found */ 354 return 1; 355} 356 357/****************************************************************************/ 358/* mark card as used */ 359int pci_card_alloc(struct pcilst_struct *amcc, int master) 360{ 361 int i; 362 363 if (!amcc) 364 return -1; 365 366 if (amcc->used) 367 return 1; 368 if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933")) 369 return -1; 370 /* Resources will be accurate now. */ 371 for (i = 0; i < 5; i++) 372 amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i); 373 if (master) 374 pci_set_master(amcc->pcidev); 375 amcc->used = 1; 376 377 return 0; 378} 379 380/****************************************************************************/ 381/* mark card as free */ 382int i_pci_card_free(struct pcilst_struct *amcc) 383{ 384 if (!amcc) 385 return -1; 386 387 if (!amcc->used) 388 return 1; 389 amcc->used = 0; 390 comedi_pci_disable(amcc->pcidev); 391 return 0; 392} 393 394/****************************************************************************/ 395/* display list of found cards */ 396void v_pci_card_list_display(void) 397{ 398 struct pcilst_struct *amcc, *next; 399 400 printk(KERN_DEBUG "List of pci cards\n"); 401 printk(KERN_DEBUG "bus:slot:func vendor device io_amcc io_daq irq used\n"); 402 403 for (amcc = amcc_devices; amcc; amcc = next) { 404 next = amcc->next; 405 printk 406 ("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n", 407 amcc->pci_bus, amcc->pci_slot, amcc->pci_func, 408 amcc->vendor, amcc->device, 409 (unsigned long long)amcc->io_addr[0], 410 (unsigned long long)amcc->io_addr[2], amcc->irq, 411 amcc->used); 412 413 } 414} 415 416/****************************************************************************/ 417/* return all card information for driver */ 418int i_pci_card_data(struct pcilst_struct *amcc, 419 unsigned char *pci_bus, unsigned char *pci_slot, 420 unsigned char *pci_func, resource_size_t * io_addr, 421 unsigned int *irq) 422{ 423 int i; 424 425 if (!amcc) 426 return -1; 427 *pci_bus = amcc->pci_bus; 428 *pci_slot = amcc->pci_slot; 429 *pci_func = amcc->pci_func; 430 for (i = 0; i < 5; i++) 431 io_addr[i] = amcc->io_addr[i]; 432 *irq = amcc->irq; 433 return 0; 434} 435 436/****************************************************************************/ 437/* select and alloc card */ 438struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, 439 unsigned short device_id, 440 unsigned short pci_bus, 441 unsigned short pci_slot, 442 int i_Master) 443{ 444 struct pcilst_struct *card; 445 446 if ((pci_bus < 1) & (pci_slot < 1)) { 447 /* use autodetection */ 448 card = ptr_find_free_pci_card_by_device(vendor_id, device_id); 449 if (card == NULL) { 450 printk(" - Unused card not found in system!\n"); 451 return NULL; 452 } 453 } else { 454 switch (i_find_free_pci_card_by_position(vendor_id, device_id, 455 pci_bus, pci_slot, 456 &card)) { 457 case 1: 458 printk(" - Card not found on requested position b:s %d:%d!\n", 459 pci_bus, pci_slot); 460 return NULL; 461 case 2: 462 printk(" - Card on requested position is used b:s %d:%d!\n", 463 pci_bus, pci_slot); 464 return NULL; 465 } 466 } 467 468 if (pci_card_alloc(card, i_Master) != 0) { 469 printk(" - Can't allocate card!\n"); 470 return NULL; 471 472 } 473 474 return card; 475} 476#endif 477