]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/bfadcan.c
changed usb vendor and product id.
[lincan.git] / lincan / src / bfadcan.c
1 /* bfadcan.c
2  * Linux CAN-bus device driver.
3  * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
4  * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
5  * email:pisa@cmp.felk.cvut.cz
6  * This software is released under the GPL-License.
7  * Version lincan-0.3  17 Jun 2004
8  */
9
10 /* This file is intended as a bfadcan file for currently unsupported hardware.
11  * Once you've changed/added the functions specific to your hardware it is
12  * possible to load the driver with the hardware option hw=bfadcan.
13  */
14
15
16 #define WINDOWED_ACCESS
17
18 #include "../include/can.h"
19 #include "../include/can_sysdep.h"
20 #include "../include/main.h"
21 #include "../include/sja1000p.h"
22
23 #define __NO_VERSION__
24 #include <linux/module.h>
25
26 long clock_freq;
27 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
28 MODULE_PARM(clock_freq,"i");
29 #else
30 module_param(clock_freq,int,0);
31 #endif
32
33 /* cli and sti are not allowed in 2.5.5x SMP kernels */
34 #ifdef WINDOWED_ACCESS
35 static CAN_DEFINE_SPINLOCK(bfadcan_win_lock);
36 #endif
37
38 /*
39  * IO_RANGE is the io-memory range that gets reserved, please adjust according
40  * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
41  * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
42  */
43 #ifdef WINDOWED_ACCESS
44 #define IO_RANGE 0x4
45 #else
46 #define IO_RANGE 0x100
47 #endif
48
49 unsigned bfadcan_read_register(unsigned long address);
50 void bfadcan_write_register(unsigned data, unsigned long address);
51
52
53 /**
54  * bfadcan_request_io: - reserve io or memory range for can board
55  * @candev: pointer to candevice/board which asks for io. Field @io_addr
56  *      of @candev is used in most cases to define start of the range
57  *
58  * The function bfadcan_request_io() is used to reserve the io-memory. If your
59  * hardware uses a dedicated memory range as hardware control registers you
60  * will have to add the code to reserve this memory as well.
61  * %IO_RANGE is the io-memory range that gets reserved, please adjust according
62  * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
63  * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
64  * Return Value: The function returns zero on success or %-ENODEV on failure
65  * File: src/bfadcan.c
66  */
67 int bfadcan_request_io(struct candevice_t *candev)
68 {
69         if (!can_request_io_region(candev->io_addr,IO_RANGE,DEVICE_NAME)) {
70                 CANMSG("Unable to open port: 0x%lx\n",candev->io_addr);
71                 return -ENODEV;
72         } else {
73                 DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1);
74         }
75         return 0;
76 }
77
78 /**
79  * bfadcan_elease_io - free reserved io memory range
80  * @candev: pointer to candevice/board which releases io
81  *
82  * The function bfadcan_release_io() is used to free reserved io-memory.
83  * In case you have reserved more io memory, don't forget to free it here.
84  * IO_RANGE is the io-memory range that gets released, please adjust according
85  * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
86  * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
87  * Return Value: The function always returns zero
88  * File: src/bfadcan.c
89  */
90 int bfadcan_release_io(struct candevice_t *candev)
91 {
92         can_release_io_region(candev->io_addr,IO_RANGE);
93
94         return 0;
95 }
96
97 /**
98  * bfadcan_reset - hardware reset routine
99  * @candev: Pointer to candevice/board structure
100  *
101  * The function bfadcan_reset() is used to give a hardware reset. This is
102  * rather hardware specific so I haven't included example code. Don't forget to
103  * check the reset status of the chip before returning.
104  * Return Value: The function returns zero on success or %-ENODEV on failure
105  * File: src/bfadcan.c
106  */
107 int bfadcan_reset(struct candevice_t *candev)
108 {
109
110         int i;
111         struct canchip_t *chip=candev->chip[0];
112         unsigned cdr;
113
114         bfadcan_write_register(sjaMOD_RM, chip->chip_base_addr+SJAMOD);
115         udelay(1000);
116
117         cdr=bfadcan_read_register(chip->chip_base_addr+SJACDR);
118         bfadcan_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
119
120         bfadcan_write_register(0, chip->chip_base_addr+SJAIER);
121
122         i=20;
123         bfadcan_write_register(0, chip->chip_base_addr+SJAMOD);
124         while (bfadcan_read_register(chip->chip_base_addr+SJAMOD)&sjaMOD_RM){
125                 if(!i--) return -ENODEV;
126                 udelay(1000);
127                 bfadcan_write_register(0, chip->chip_base_addr+SJAMOD);
128         }
129
130         cdr=bfadcan_read_register(chip->chip_base_addr+SJACDR);
131         bfadcan_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
132
133         bfadcan_write_register(0, chip->chip_base_addr+SJAIER);
134
135         return 0;
136 }
137
138 #define RESET_ADDR 0x202
139 #define NR_82527 0
140 #define NR_SJA1000 1
141
142 /**
143  * bfadcan_init_hw_data - Initialize hardware cards
144  * @candev: Pointer to candevice/board structure
145  *
146  * The function bfadcan_init_hw_data() is used to initialize the hardware
147  * structure containing information about the installed CAN-board.
148  * %RESET_ADDR represents the io-address of the hardware reset register.
149  * %NR_82527 represents the number of intel 82527 chips on the board.
150  * %NR_SJA1000 represents the number of philips sja1000 chips on the board.
151  * The flags entry can currently only be %CANDEV_PROGRAMMABLE_IRQ to indicate that
152  * the hardware uses programmable interrupts.
153  * Return Value: The function always returns zero
154  * File: src/bfadcan.c
155  */
156 int bfadcan_init_hw_data(struct candevice_t *candev)
157 {
158         candev->res_addr=RESET_ADDR;
159         candev->nr_82527_chips=NR_82527;
160         candev->nr_sja1000_chips=NR_SJA1000;
161         candev->nr_all_chips=NR_82527+NR_SJA1000;
162         candev->flags |= 0 /* CANDEV_PROGRAMMABLE_IRQ */ ;
163
164         return 0;
165 }
166
167 /**
168  * bfadcan_init_chip_data - Initialize chips
169  * @candev: Pointer to candevice/board structure
170  * @chipnr: Number of the CAN chip on the hardware card
171  *
172  * The function bfadcan_init_chip_data() is used to initialize the hardware
173  * structure containing information about the CAN chips.
174  * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or
175  * "sja1000".
176  * The @chip_base_addr entry represents the start of the 'official' memory map
177  * of the installed chip. It's likely that this is the same as the @io_addr
178  * argument supplied at module loading time.
179  * The @clock entry holds the chip clock value in Hz.
180  * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider
181  * register. Options defined in the %sja1000.h file:
182  * %sjaCDR_CLKOUT_MASK, %sjaCDR_CLK_OFF, %sjaCDR_RXINPEN, %sjaCDR_CBP, %sjaCDR_PELICAN
183  * The entry @sja_ocr_reg holds hardware specific options for the Output Control
184  * register. Options defined in the %sja1000.h file:
185  * %sjaOCR_MODE_BIPHASE, %sjaOCR_MODE_TEST, %sjaOCR_MODE_NORMAL, %sjaOCR_MODE_CLOCK,
186  * %sjaOCR_TX0_LH, %sjaOCR_TX1_ZZ.
187  * The entry @int_clk_reg holds hardware specific options for the Clock Out
188  * register. Options defined in the %i82527.h file:
189  * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.
190  * The entry @int_bus_reg holds hardware specific options for the Bus
191  * Configuration register. Options defined in the %i82527.h file:
192  * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.
193  * The entry @int_cpu_reg holds hardware specific options for the cpu interface
194  * register. Options defined in the %i82527.h file:
195  * %iCPU_CEN, %iCPU_MUX, %iCPU_SLP, %iCPU_PWD, %iCPU_DMC, %iCPU_DSC, %iCPU_RST.
196  * Return Value: The function always returns zero
197  * File: src/bfadcan.c
198  */
199 int bfadcan_init_chip_data(struct candevice_t *candev, int chipnr)
200 {
201         unsigned int id1, id2;
202         sja1000p_fill_chipspecops(candev->chip[chipnr]);
203         candev->chip[chipnr]->chip_base_addr=candev->io_addr;
204         candev->chip[chipnr]->clock = clock_freq;
205         candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF;
206         candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;
207         id1 = inb(0xe284);
208         id2 = inb(0xe285);
209
210
211         CANMSG("can driver ver lincan-0.3, at %04lx, CPLD v%d.%d.%d.%d\n",
212                                         candev->chip[chipnr]->chip_base_addr,
213                                                         id1>>4, id1&0x0f, id2>>4, id2&0x0f);
214
215
216         return 0;
217 }
218
219 /**
220  * bfadcan_init_obj_data - Initialize message buffers
221  * @chip: Pointer to chip specific structure
222  * @objnr: Number of the message buffer
223  *
224  * The function bfadcan_init_obj_data() is used to initialize the hardware
225  * structure containing information about the different message objects on the
226  * CAN chip. In case of the sja1000 there's only one message object but on the
227  * i82527 chip there are 15.
228  * The code below is for a i82527 chip and initializes the object base addresses
229  * The entry @obj_base_addr represents the first memory address of the message
230  * object. In case of the sja1000 @obj_base_addr is taken the same as the chips
231  * base address.
232  * Unless the hardware uses a segmented memory map, flags can be set zero.
233  * Return Value: The function always returns zero
234  * File: src/bfadcan.c
235  */
236 int bfadcan_init_obj_data(struct canchip_t *chip, int objnr)
237 {
238         chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr+(objnr+1)*0x10;
239
240         return 0;
241 }
242
243 /**
244  * bfadcan_program_irq - program interrupts
245  * @candev: Pointer to candevice/board structure
246  *
247  * The function bfadcan_program_irq() is used for hardware that uses
248  * programmable interrupts. If your hardware doesn't use programmable interrupts
249  * you should not set the @candevices_t->flags entry to %CANDEV_PROGRAMMABLE_IRQ and
250  * leave this function unedited. Again this function is hardware specific so
251  * there's no example code.
252  * Return value: The function returns zero on success or %-ENODEV on failure
253  * File: src/bfadcan.c
254  */
255 int bfadcan_program_irq(struct candevice_t *candev)
256 {
257         return 0;
258 }
259
260 /**
261  * bfadcan_write_register - Low level write register routine
262  * @data: data to be written
263  * @address: memory address to write to
264  *
265  * The function bfadcan_write_register() is used to write to hardware registers
266  * on the CAN chip. You should only have to edit this function if your hardware
267  * uses some specific write process.
268  * Return Value: The function does not return a value
269  * File: src/bfadcan.c
270  */
271 void bfadcan_write_register(unsigned data, unsigned long address)
272 {
273 #ifdef WINDOWED_ACCESS
274         can_spin_irqflags_t flags;
275         can_spin_lock_irqsave(&bfadcan_win_lock,flags);
276         outb(address&0x00ff,0x200);
277         outb(data, 0x201);
278         can_spin_unlock_irqrestore(&bfadcan_win_lock,flags);
279 #else
280         outb(data,address);
281 #endif
282 }
283
284 /**
285  * bfadcan_read_register - Low level read register routine
286  * @address: memory address to read from
287  *
288  * The function bfadcan_read_register() is used to read from hardware registers
289  * on the CAN chip. You should only have to edit this function if your hardware
290  * uses some specific read process.
291  * Return Value: The function returns the value stored in @address
292  * File: src/bfadcan.c
293  */
294 unsigned bfadcan_read_register(unsigned long address)
295 {
296 #ifdef WINDOWED_ACCESS
297         can_spin_irqflags_t flags;
298         int ret;
299         can_spin_lock_irqsave(&bfadcan_win_lock,flags);
300         outb(address&0x00ff,0x200);
301         ret = inb(0x201);
302         can_spin_unlock_irqrestore(&bfadcan_win_lock,flags);
303         return ret;
304 #else
305         return inb(address);
306 #endif
307 }
308
309 /* !!! Don't change this function !!! */
310 int bfadcan_register(struct hwspecops_t *hwspecops)
311 {
312         hwspecops->request_io = bfadcan_request_io;
313         hwspecops->release_io = bfadcan_release_io;
314         hwspecops->reset = bfadcan_reset;
315         hwspecops->init_hw_data = bfadcan_init_hw_data;
316         hwspecops->init_chip_data = bfadcan_init_chip_data;
317         hwspecops->init_obj_data = bfadcan_init_obj_data;
318         hwspecops->write_register = bfadcan_write_register;
319         hwspecops->read_register = bfadcan_read_register;
320         hwspecops->program_irq = bfadcan_program_irq;
321         return 0;
322 }