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