1 /**************************************************************************/
2 /* File: ns_dev_can.c - FPGA version of C_CAN ARM device specific */
3 /* Ported to FS Forth-Systeme GmbH A9M9750DEVx development boardscode */
5 /* LinCAN - (Not only) Linux CAN bus driver */
6 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
7 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
8 /* Copyright (C) 2004 Sebastian Stolzenberg <stolzi@sebastian-stolzenberg.de> */
9 /* Copyright (C) 2005 Neil Bryan <nbryan@embebidos.com> */
10 /* Funded by OCERA and FRESCOR IST projects */
11 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
12 /* and Ake Hedman, eurosource <akhe@eurosource.se> */
14 /* LinCAN is free software; you can redistribute it and/or modify it */
15 /* under terms of the GNU General Public License as published by the */
16 /* Free Software Foundation; either version 2, or (at your option) any */
17 /* later version. LinCAN is distributed in the hope that it will be */
18 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
19 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
20 /* General Public License for more details. You should have received a */
21 /* copy of the GNU General Public License along with LinCAN; see file */
22 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
23 /* Cambridge, MA 02139, USA. */
25 /* To allow use of LinCAN in the compact embedded systems firmware */
26 /* and RT-executives (RTEMS for example), main authors agree with next */
27 /* special exception: */
29 /* Including LinCAN header files in a file, instantiating LinCAN generics */
30 /* or templates, or linking other files with LinCAN objects to produce */
31 /* an application image/executable, does not by itself cause the */
32 /* resulting application image/executable to be covered by */
33 /* the GNU General Public License. */
34 /* This exception does not however invalidate any other reasons */
35 /* why the executable file might be covered by the GNU Public License. */
36 /* Publication of enhanced or derived LinCAN files is required although. */
37 /**************************************************************************/
39 #include <linux/delay.h>
41 #include "../include/can.h"
42 #include "../include/can_sysdep.h"
43 #include "../include/main.h"
44 #include "../include/c_can.h"
45 #include "../include/ns_dev_can.h"
48 * IO range for the C_CAN 1.2 memory map is 0x100 (256bytes)
50 #define IO_RANGE 0x100
53 * ns_dev_request_io: - reserve io or memory range for can board
54 * @candev: pointer to candevice/board which asks for io. Field @io_addr
55 * of @candev is used in most cases to define start of the range
58 int ns_dev_request_io(struct candevice_t *candev)
60 /* Note hard-coded index for the chip number as this
61 * only supports a single instance of the C_CAN controller.
63 DEBUGMSG("(c%d)ns_dev_request_io (...)\n", candev->chip[0]->chip_idx);
65 if (!can_request_mem_region(candev->io_addr, IO_RANGE, DEVICE_NAME)) {
66 CANMSG("ns_dev failed to mem region %lx.\n",
67 (unsigned long)candev->io_addr);
70 if (!(candev->dev_base_addr = ioremap(candev->io_addr, IO_RANGE))) {
72 ("Failed to map IO-memory: 0x%lx - 0x%lx, mapped to 0x%lx\n",
73 (unsigned long)candev->io_addr,
74 (unsigned long)candev->io_addr + IO_RANGE - 1,
75 (unsigned long)candev->dev_base_addr);
76 can_release_mem_region(candev->io_addr, IO_RANGE);
80 DEBUGMSG("Mapped IO-memory: 0x%lx - 0x%lx, mapped to 0x%lx\n",
81 (unsigned long)candev->io_addr,
82 (unsigned long)candev->io_addr + IO_RANGE - 1,
83 (unsigned long)candev->dev_base_addr);
87 candev->chip[0]->chip_base_addr = candev->dev_base_addr;
88 candev->chip[0]->chipspecops->start_chip(candev->chip[0]);
94 * ns_dev_release_io - free reserved io memory range
95 * @candev: pointer to candevice/board which releases io
97 * The function ns_dev_release_io() is used to free reserved io-memory.
98 * In case you have reserved more io memory, don't forget to free it here.
101 int ns_dev_release_io(struct candevice_t *candev)
103 DEBUGMSG("(c%d)ns_dev_release_io (...)\n", candev->chip[0]->chip_idx);
105 /* Release I/O memory mapping */
106 iounmap(candev->dev_base_addr);
108 /* Release the memory region */
109 can_release_mem_region(candev->io_addr, IO_RANGE);
115 * ns_dev_reset - hardware reset routine
116 * @card: Number of the hardware card.
118 * The function ns_dev_reset() is used to give a hardware reset. This is
119 * rather hardware specific so I haven't included example code. Don't forget to
120 * check the reset status of the chip before returning.
121 * Return Value: The function returns zero on success or %-ENODEV on failure
124 int ns_dev_reset(struct candevice_t *candev)
130 struct canchip_t *pchip = candev->chip[0];
132 enableTest = pchip->chipspecops->enable_configuration(pchip);
133 disableTest = pchip->chipspecops->disable_configuration(pchip);
135 if (enableTest || disableTest) {
136 CANMSG("Enable or Disable status failed!\n");
137 CANMSG("Please check your hardware.\n");
141 /* Check busoff status */
142 while ((c_can_read_reg_w(pchip, CCSR) & SR_BOFF) && (i <= 15)) {
148 CANMSG("Reset status timeout!\n");
149 CANMSG("Please check your hardware.\n");
152 //pchip->config_irqs(pchip, CR_MIE | CR_SIE | CR_EIE);
156 #define RESET_ADDR 0x0
161 * ns_dev_hw_data - Initialize hardware cards
162 * @candev: Pointer to candevice/board structure
164 * The function ns_dev_init_hw_data() is used to initialize the hardware
165 * structure containing information about the installed CAN-board.
166 * The flags entry can currently only be %CANDEV_PROGRAMMABLE_IRQ to indicate that
167 * the hardware uses programmable interrupts.
168 * Return Value: The function always returns zero
170 int ns_dev_init_hw_data(struct candevice_t *candev)
172 can_ioptr_t sys_contVA = NULL;
174 /* LUCAN : Magic numbers */
175 if (!(sys_contVA = ioremap(NS9750_PERIPHERAL_BASE_ADDRESS,
176 NS9750_PERIPHERAL_MAP_SIZE))) {
177 DEBUGMSG("Failed to map FPGA memory\n");
180 DEBUGMSG("Writing to NS9750 sys cont\n");
181 can_writel((BUS_WIDTH_16BIT | ACTIVE_LOW_CHIP_SELECT),
182 sys_contVA + NS9750_SYSTEM_CONTROLLER_OFFSET);
185 /* We have finished with this mapping */
188 candev->nr_82527_chips = 0;
189 candev->nr_sja1000_chips = 0;
190 candev->nr_all_chips = NR_C_CAN;
191 candev->flags |= CANDEV_PROGRAMMABLE_IRQ;
197 * ns_dev_init_chip_data - Initialize chips
198 * @candev: Pointer to candevice/board structure
199 * @chipnr: Number of the CAN chip on the hardware card
201 * The function ns_dev_init_chip_data() is used to initialize the hardware
202 * structure containing information about the CAN chips.
203 * %CHIP_TYPE represents the type of CAN chip.
204 * The @chip_base_addr entry represents the start of the 'official' memory map
205 * of the installed chip. It's likely that this is the same as the @io_addr
206 * argument supplied at module loading time.
207 * The @clock entry holds the chip clock value in Hz.
208 * File: src/template.c
210 int ns_dev_init_chip_data(struct candevice_t *candev, int chipnr)
212 /* Register chip operations */
213 c_can_fill_chipspecops(candev->chip[chipnr]);
215 /* override chip provided default value */
216 candev->chip[chipnr]->max_objects = MAX_MSGOBJS;
217 candev->chip[chipnr]->chip_base_addr = candev->io_addr;
218 candev->chip[chipnr]->clock = C_CAN_CLOCK_INPUT_FREQUENCY;
224 * ns_dev_init_obj_data - Initialize message buffers
225 * @chip: Pointer to chip specific structure
226 * @objnr: Number of the message buffer
228 * The function ns_dev_init_obj_data() is used to initialize the hardware
229 * structure containing information about the different message objects on the
231 * The entry @obj_base_addr represents the first memory address of the message
233 * Unless the hardware uses a segmented memory map, flags can be set zero.
234 * Return Value: The function always returns zero
235 * File: src/template.c
237 int ns_dev_init_obj_data(struct canchip_t *chip, int objnr)
240 DEBUGMSG("(c%d)calling ns_dev_init_obj_data( ...)\n", chip->chip_idx);
242 /* It seems, that there is no purpose to setup object base address */
243 chip->msgobj[objnr]->obj_base_addr = 0;
245 /*can_msgobj_test_fl(pmsgobj,RX_MODE_EXT); */
250 * ns_dev_write_register - Low level write register routine
251 * @data: data to be written
252 * @address: memory address to write to
254 * The function ns_dev_write_register() is used to write to hardware registers
255 * on the CAN chip. You should only have to edit this function if your hardware
256 * uses some specific write process.
257 * Return Value: The function does not return a value
258 * File: src/template.c
260 void ns_dev_write_register(unsigned data, can_ioptr_t address)
263 //unsigned long usecs = 1;
265 can_writew(data, address);
267 for (i = 0; i < 5; i++) ;
271 * ns_dev_read_register - Low level read register routine
272 * @address: memory address to read from
274 * The function ns_dev_read_register() is used to read from hardware registers
275 * on the CAN chip. You should only have to edit this function if your hardware
276 * uses some specific read process.
277 * Return Value: The function returns the value stored in @address
278 * File: src/template.c
280 unsigned ns_dev_read_register(can_ioptr_t address)
284 value = can_readw(address);
286 for (i = 0; i < 5; i++) ;
287 value = can_readw(address);
289 for (i = 0; i < 5; i++) ;
295 * ns_dev_program_irq - program interrupts
296 * @candev: Pointer to candevice/board structure
298 * The function ns_dev_program_irq() is used for hardware that uses
299 * programmable interrupts. If your hardware doesn't use programmable interrupts
300 * you should not set the @candevices_t->flags entry to %CANDEV_PROGRAMMABLE_IRQ and
301 * leave this function unedited. Again this function is hardware specific so
302 * there's no example code.
303 * Return value: The function returns zero on success or %-ENODEV on failure
304 * File: src/template.c
306 int ns_dev_program_irq(struct candevice_t *candev)
311 int ns_dev_register(struct hwspecops_t *hwspecops)
313 hwspecops->request_io = ns_dev_request_io;
314 hwspecops->release_io = ns_dev_release_io;
315 hwspecops->reset = ns_dev_reset;
316 hwspecops->init_hw_data = ns_dev_init_hw_data;
317 hwspecops->init_chip_data = ns_dev_init_chip_data;
318 hwspecops->init_obj_data = ns_dev_init_obj_data;
319 hwspecops->write_register = ns_dev_write_register;
320 hwspecops->read_register = ns_dev_read_register;
321 hwspecops->program_irq = ns_dev_program_irq;