]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/pikronisa.c
104cbbc726cc2af89b5df07efa8a3d758ff422c5
[lincan.git] / lincan / src / pikronisa.c
1 /* pikronisa.c
2  * Linux CAN-bus device driver.
3  * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
4  * This software is released under the GPL-License.
5  * Version 0.7  6 Aug 2001
6  */ 
7
8 #include <linux/autoconf.h>
9 #if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)
10 #define MODVERSIONS
11 #endif
12
13 #if defined (MODVERSIONS)
14 #include <linux/modversions.h>
15 #endif
16
17 #include <linux/ioport.h>
18 #include <linux/delay.h>
19 #include <asm/errno.h>
20 #include <asm/io.h>
21
22 #include "../include/main.h"
23 #include "../include/pikronisa.h"
24 #include "../include/i82527.h"
25 #include "../include/sja1000p.h"
26
27 /*
28  * IO_RANGE is the io-memory range that gets reserved, please adjust according
29  * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
30  * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
31  */
32 #define IO_RANGE 0x100
33
34 static long base = 0L; 
35
36 /**
37  * pikronisa_request_io: - reserve io memory
38  * @io_addr: The reserved memory starts at @io_addr, wich is the module 
39  * parameter @io.
40  *
41  * The function pikronisa_request_io() is used to reserve the io-memory. If your
42  * hardware uses a dedicated memory range as hardware control registers you
43  * will have to add the code to reserve this memory as well. 
44  * %IO_RANGE is the io-memory range that gets reserved, please adjust according
45  * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
46  * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
47  * Return Value: The function returns zero on success or %-ENODEV on failure
48  * File: src/pikronisa.c
49  */
50 int pikronisa_request_io(unsigned long io_addr)
51 {
52         int remap_addr;
53         if ( !( remap_addr = (long) ioremap( io_addr, IO_RANGE ) ) ) {
54                 CANMSG("Unable to access I/O memory at: 0x%lx\n", io_addr);
55                 return -ENODEV;
56         
57         }
58         base=remap_addr-io_addr;
59         DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", io_addr, io_addr + IO_RANGE - 1);
60         return 0;
61 }
62
63 /**
64  * pikronisa_release_io - free reserved io-memory
65  * @io_addr: Start of the memory range to be released.
66  *
67  * The function pikronisa_release_io() is used to free reserved io-memory.
68  * In case you have reserved more io memory, don't forget to free it here.
69  * IO_RANGE is the io-memory range that gets released, please adjust according
70  * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
71  * #define IO_RANGE 0x20 for sja1000 chips in basic CAN mode.
72  * Return Value: The function always returns zero
73  * File: src/pikronisa.c
74  */
75 int pikronisa_release_io(unsigned long io_addr)
76 {
77         /* release I/O memory mapping */
78         iounmap((void*)base);
79
80         return 0;
81 }
82
83 /**
84  * pikronisa_reset - hardware reset routine
85  * @card: Number of the hardware card.
86  *
87  * The function pikronisa_reset() is used to give a hardware reset. This is 
88  * rather hardware specific so I haven't included example code. Don't forget to 
89  * check the reset status of the chip before returning.
90  * Return Value: The function returns zero on success or %-ENODEV on failure
91  * File: src/pikronisa.c
92  */
93 int pikronisa_reset(int card)
94 {
95         int i;
96         struct chip_t *chip=candevices_p[card]->chip[0];
97         unsigned cdr;
98         
99         pikronisa_write_register(MOD_RM, chip->chip_base_addr+SJAMOD);
100         udelay(1000);
101         
102         cdr=pikronisa_read_register(chip->chip_base_addr+SJACDR);
103         pikronisa_write_register(cdr|CDR_PELICAN, chip->chip_base_addr+SJACDR);
104
105         pikronisa_write_register(0, chip->chip_base_addr+SJAIER);
106
107         i=20;
108         pikronisa_write_register(0, chip->chip_base_addr+SJAMOD);
109         while (pikronisa_read_register(chip->chip_base_addr+SJAMOD)&MOD_RM){
110                 if(!i--) return -ENODEV;
111                 udelay(1000);
112                 pikronisa_write_register(0, chip->chip_base_addr+SJAMOD);
113         }
114
115         cdr=pikronisa_read_register(chip->chip_base_addr+SJACDR);
116         pikronisa_write_register(cdr|CDR_PELICAN, chip->chip_base_addr+SJACDR);
117
118         pikronisa_write_register(0, chip->chip_base_addr+SJAIER);
119         
120         return 0;
121 }
122
123 #define RESET_ADDR 0x0
124 #define NR_82527 0
125 #define NR_SJA1000 1
126
127 /**
128  * pikronisa_init_hw_data - Initialze hardware cards
129  * @card: Number of the hardware card.
130  *
131  * The function pikronisa_init_hw_data() is used to initialize the hardware
132  * structure containing information about the installed CAN-board.
133  * %RESET_ADDR represents the io-address of the hardware reset register.
134  * %NR_82527 represents the number of intel 82527 chips on the board.
135  * %NR_SJA1000 represents the number of philips sja1000 chips on the board.
136  * The flags entry can currently only be %PROGRAMMABLE_IRQ to indicate that
137  * the hardware uses programmable interrupts.
138  * Return Value: The function always returns zero
139  * File: src/pikronisa.c
140  */
141 int pikronisa_init_hw_data(int card) 
142 {
143         candevices_p[card]->res_addr=RESET_ADDR;
144         candevices_p[card]->nr_82527_chips=0;
145         candevices_p[card]->nr_sja1000_chips=1;
146         candevices_p[card]->flags |= PROGRAMMABLE_IRQ*0;
147
148         return 0;
149 }
150
151 #define CHIP_TYPE "sja1000p"
152 /* #define CHIP_TYPE "sja1000" */
153
154 /**
155  * pikronisa_init_chip_data - Initialize chips
156  * @card: Number of the hardware card
157  * @chipnr: Number of the CAN chip on the hardware card
158  *
159  * The function pikronisa_init_chip_data() is used to initialize the hardware
160  * structure containing information about the CAN chips.
161  * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or
162  * "sja1000".
163  * The @chip_base_addr entry represents the start of the 'official' memory map
164  * of the installed chip. It's likely that this is the same as the @io_addr
165  * argument supplied at module loading time.
166  * The @clock entry holds the chip clock value in Hz.
167  * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider
168  * register. Options defined in the %sja1000.h file:
169  * %CDR_CLKOUT_MASK, %CDR_CLK_OFF, %CDR_RXINPEN, %CDR_CBP, %CDR_PELICAN
170  * The entry @sja_ocr_reg holds hardware specific options for the Output Control
171  * register. Options defined in the %sja1000.h file:
172  * %OCR_MODE_BIPHASE, %OCR_MODE_TEST, %OCR_MODE_NORMAL, %OCR_MODE_CLOCK,
173  * %OCR_TX0_LH, %OCR_TX1_ZZ.
174  * The entry @int_clk_reg holds hardware specific options for the Clock Out
175  * register. Options defined in the %i82527.h file:
176  * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1.
177  * The entry @int_bus_reg holds hardware specific options for the Bus 
178  * Configuration register. Options defined in the %i82527.h file:
179  * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY.
180  * The entry @int_cpu_reg holds hardware specific options for the cpu interface
181  * register. Options defined in the %i82527.h file:
182  * %iCPU_CEN, %iCPU_MUX, %iCPU_SLP, %iCPU_PWD, %iCPU_DMC, %iCPU_DSC, %iCPU_RST.
183  * Return Value: The function always returns zero
184  * File: src/pikronisa.c
185  */
186 int pikronisa_init_chip_data(int card, int chipnr)
187 {
188         /* pikronisa_base_addr = candevices_p[card]->io_addr; */
189         candevices_p[card]->chip[chipnr]->chip_type=CHIP_TYPE;
190         candevices_p[card]->chip[chipnr]->chip_base_addr=candevices_p[card]->io_addr;
191         candevices_p[card]->chip[chipnr]->clock = 24000000;
192         candevices_p[card]->chip[chipnr]->int_clk_reg = 0x0;
193         candevices_p[card]->chip[chipnr]->int_bus_reg = 0x0;
194         candevices_p[card]->chip[chipnr]->sja_cdr_reg = CDR_CBP | CDR_CLK_OFF;
195         candevices_p[card]->chip[chipnr]->sja_ocr_reg = OCR_MODE_NORMAL |
196                                                                 OCR_TX0_LH;
197
198         return 0;
199 }
200
201 /**
202  * pikronisa_init_obj_data - Initialize message buffers
203  * @chipnr: Number of the CAN chip
204  * @objnr: Number of the message buffer
205  *
206  * The function pikronisa_init_obj_data() is used to initialize the hardware
207  * structure containing information about the different message objects on the
208  * CAN chip. In case of the sja1000 there's only one message object but on the
209  * i82527 chip there are 15.
210  * The code below is for a i82527 chip and initializes the object base addresses
211  * The entry @obj_base_addr represents the first memory address of the message 
212  * object. In case of the sja1000 @obj_base_addr is taken the same as the chips
213  * base address.
214  * Unless the hardware uses a segmented memory map, flags can be set zero.
215  * Return Value: The function always returns zero
216  * File: src/pikronisa.c
217  */
218 int pikronisa_init_obj_data(int chipnr, int objnr)
219 {
220         chips_p[chipnr]->msgobj[objnr]->obj_base_addr=chips_p[chipnr]->chip_base_addr;
221         chips_p[chipnr]->msgobj[objnr]->flags=0;
222         return 0;
223 }
224
225 /**
226  * pikronisa_program_irq - program interrupts
227  * @card: Number of the hardware card.
228  *
229  * The function pikronisa_program_irq() is used for hardware that uses 
230  * programmable interrupts. If your hardware doesn't use programmable interrupts
231  * you should not set the @candevices_t->flags entry to %PROGRAMMABLE_IRQ and 
232  * leave this function unedited. Again this function is hardware specific so 
233  * there's no example code.
234  * Return value: The function returns zero on success or %-ENODEV on failure
235  * File: src/pikronisa.c
236  */
237 int pikronisa_program_irq(int card)
238 {
239         return 0;
240 }
241
242 /**
243  * pikronisa_write_register - Low level write register routine
244  * @data: data to be written
245  * @address: memory address to write to
246  *
247  * The function pikronisa_write_register() is used to write to hardware registers
248  * on the CAN chip. You should only have to edit this function if your hardware
249  * uses some specific write process.
250  * Return Value: The function does not return a value
251  * File: src/pikronisa.c
252  */
253 void pikronisa_write_register(unsigned char data, unsigned long address)
254 {
255         /*DEBUGMSG("pikronisa_write_register: base=0x%lx addr=0x%lx data=0x%x",
256                 base,address,data);*/
257         writeb(data,base+address);
258 }
259
260 /**
261  * pikronisa_read_register - Low level read register routine
262  * @address: memory address to read from
263  *
264  * The function pikronisa_read_register() is used to read from hardware registers
265  * on the CAN chip. You should only have to edit this function if your hardware
266  * uses some specific read process.
267  * Return Value: The function returns the value stored in @address
268  * File: src/pikronisa.c
269  */
270 unsigned pikronisa_read_register(unsigned long address)
271 {
272         return readb(base+address);
273 }
274
275 /* !!! Don't change this function !!! */
276 int pikronisa_register(struct hwspecops_t *hwspecops)
277 {
278         hwspecops->request_io = pikronisa_request_io;
279         hwspecops->release_io = pikronisa_release_io;
280         hwspecops->reset = pikronisa_reset;
281         hwspecops->init_hw_data = pikronisa_init_hw_data;
282         hwspecops->init_chip_data = pikronisa_init_chip_data;
283         hwspecops->init_obj_data = pikronisa_init_obj_data;
284         hwspecops->write_register = pikronisa_write_register;
285         hwspecops->read_register = pikronisa_read_register;
286         hwspecops->program_irq = pikronisa_program_irq;
287         return 0;
288 }