3 Copyright (C) 2004-2012 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <exec/types.h>
24 #include <libraries/openpci.h>
26 #include <proto/exec.h>
27 #include <proto/openpci.h>
33 #include "pci_protos.h"
34 #include "openpci_protos.h"
35 #include "timer_protos.h"
38 /****i* prism2.device/GetOpenPCICount **************************************
44 * count = GetOpenPCICount()
46 * ULONG GetOpenPCICount();
48 ****************************************************************************
52 ULONG
GetOpenPCICount(struct DevBase
*base
)
55 struct pci_dev
*card
= NULL
;
56 UWORD vendor_id
, product_id
;
58 while((card
= pci_find_device(0xffff, 0xffff, card
)) != NULL
)
60 product_id
= pci_read_config_word(PCI_DEVICE_ID
, card
);
61 vendor_id
= pci_read_config_word(PCI_VENDOR_ID
, card
);
62 if(IsCardCompatible(vendor_id
, product_id
, base
))
71 /****i* prism2.device/AllocOpenPCICard *************************************
74 * AllocOpenPCICard -- Create a unit.
77 * context = AllocOpenPCICard(index)
79 * struct BusContext *AllocOpenPCICard(ULONG);
81 ****************************************************************************
85 struct BusContext
*AllocOpenPCICard(ULONG index
, struct DevBase
*base
)
88 struct BusContext
*context
;
89 struct pci_dev
*card
= NULL
;
90 UWORD i
= 0, vendor_id
, product_id
, io_range_no
;
92 UPINT io_reg
, int_reg
;
93 volatile UBYTE
*cor_reg
;
95 /* Find a compatible card */
97 context
= AllocMem(sizeof(struct BusContext
), MEMF_PUBLIC
| MEMF_CLEAR
);
105 card
= pci_find_device(0xffff, 0xffff, card
);
106 product_id
= pci_read_config_word(PCI_DEVICE_ID
, card
);
107 vendor_id
= pci_read_config_word(PCI_VENDOR_ID
, card
);
108 if(IsCardCompatible(vendor_id
, product_id
, base
))
112 context
->card
= card
;
119 /* Find out what type of Prism II PCI card this is */
121 context
->bus_type
= GetBusType(product_id
, base
);
122 pci_write_config_word(PCI_COMMAND
,
123 PCI_COMMAND_MEMORY
| PCI_COMMAND_IO
, card
);
125 if(context
->bus_type
== TMD_BUS
)
127 /* Reset and enable the PCCard */
129 io_reg
= (UPINT
)card
->base_address
[1];
130 BYTEOUT(io_reg
, COR_RESET
);
131 BusyMilliDelay(RESET_DELAY
, base
);
132 BYTEOUT(io_reg
, COR_ENABLE
);
133 BusyMilliDelay(RESET_DELAY
, base
);
136 else if(context
->bus_type
== PLX_BUS
)
138 /* Reset and enable the PCCard */
140 cor_reg
= (volatile UBYTE
*)card
->base_address
[2] + 0x3e0;
141 *cor_reg
= COR_ENABLE
;
142 BusyMilliDelay(RESET_DELAY
, base
);
144 /* Enable interrupts on the bridge */
146 int_reg
= (UPINT
)card
->base_address
[1] + PLX9052_INTS
;
147 value
= LONGIN(int_reg
);
148 LONGOUT(int_reg
, value
| (1 << 6));
149 if((LONGIN(int_reg
) & (1 << 6)) == 0)
156 /* Get the I/O base of the wireless chip */
158 context
->have_card
= TRUE
;
159 context
->io_base
= (UPINT
)card
->base_address
[io_range_no
];
161 if(context
->bus_type
== PCI_BUS
)
163 /* Reset and enable the card */
165 cor_reg
= (volatile UBYTE
*)context
->io_base
+ (P2_REG_PCICOR
* 2);
166 *cor_reg
= COR_RESET
;
167 BusyMilliDelay(250, base
);
169 BusyMilliDelay(500, base
);
175 FreeOpenPCICard(context
, base
);
184 /****i* prism2.device/FreeOpenPCICard **************************************
190 * FreeOpenPCICard(context)
192 * VOID FreeOpenPCICard(struct BusContext *);
194 ****************************************************************************
198 VOID
FreeOpenPCICard(struct BusContext
*context
, struct DevBase
*base
)
200 struct pci_dev
*card
;
203 UPINT io_reg
, int_reg
;
204 volatile UBYTE
*cor_reg
;
208 card
= context
->card
;
211 if(context
->bus_type
== TMD_BUS
)
213 /* Disable the PCCard */
215 io_reg
= (UPINT
)card
->base_address
[1];
218 else if(context
->bus_type
== PLX_BUS
)
220 /* Disable interrupts on the bridge */
222 int_reg
= (UPINT
)card
->base_address
[1] + PLX9052_INTS
;
223 value
= LONGIN(int_reg
);
224 LONGOUT(int_reg
, value
& ~(1 << 6));
226 /* Disable the PCCard */
228 cor_reg
= (volatile UBYTE
*)card
->base_address
[2] + 0x3e0;
229 *cor_reg
= COR_RESET
;
230 BusyMilliDelay(250, base
);
234 FreeMem(context
, sizeof(struct BusContext
));
243 /****i* prism2.device/AddOpenPCIIntServer **********************************
246 * AddOpenPCIIntServer
249 * success = AddOpenPCIIntServer(card, interrupt)
251 * BOOL AddOpenPCIIntServer(APTR, struct Interrupt *);
253 ****************************************************************************
257 BOOL
AddOpenPCIIntServer(APTR card
, struct Interrupt
*interrupt
,
258 struct DevBase
*base
)
260 return pci_add_intserver(interrupt
, card
);
265 /****i* prism2.device/RemOpenPCIIntServer **********************************
268 * RemOpenPCIIntServer
271 * RemOpenPCIIntServer(card, interrupt)
273 * VOID RemOpenPCIIntServer(APTR, struct Interrupt *);
275 ****************************************************************************
279 VOID
RemOpenPCIIntServer(APTR card
, struct Interrupt
*interrupt
,
280 struct DevBase
*base
)
282 pci_rem_intserver(interrupt
, card
);