1 /**************************************************************************/
2 /* File: oscar.c - SJA1000 based card connected to ARM LH7A400 SoC */
4 /* LinCAN - (Not only) Linux CAN bus driver */
5 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
6 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
7 /* Funded by OCERA and FRESCOR IST projects */
8 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
10 /* LinCAN is free software; you can redistribute it and/or modify it */
11 /* under terms of the GNU General Public License as published by the */
12 /* Free Software Foundation; either version 2, or (at your option) any */
13 /* later version. LinCAN is distributed in the hope that it will be */
14 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
15 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
16 /* General Public License for more details. You should have received a */
17 /* copy of the GNU General Public License along with LinCAN; see file */
18 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
19 /* Cambridge, MA 02139, USA. */
21 /* To allow use of LinCAN in the compact embedded systems firmware */
22 /* and RT-executives (RTEMS for example), main authors agree with next */
23 /* special exception: */
25 /* Including LinCAN header files in a file, instantiating LinCAN generics */
26 /* or templates, or linking other files with LinCAN objects to produce */
27 /* an application image/executable, does not by itself cause the */
28 /* resulting application image/executable to be covered by */
29 /* the GNU General Public License. */
30 /* This exception does not however invalidate any other reasons */
31 /* why the executable file might be covered by the GNU Public License. */
32 /* Publication of enhanced or derived LinCAN files is required although. */
33 /**************************************************************************/
35 #include "../include/can.h"
36 #include "../include/can_sysdep.h"
37 #include "../include/main.h"
38 #include "../include/oscar.h"
39 #include "../include/sja1000p.h"
41 #define IO_RANGE 0x80 // allow both basic CAN and PeliCAN modes for sja1000
43 int oscar_request_io(struct candevice_t *candev)
45 if (!can_request_io_region(candev->io_addr,IO_RANGE,DEVICE_NAME)) {
46 CANMSG("Unable to open port: 0x%lx\n",candev->io_addr);
49 DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1);
54 int oscar_release_io(struct candevice_t *candev)
56 can_release_io_region(candev->io_addr,IO_RANGE);
61 int oscar_reset(struct candevice_t *candev)
64 struct canchip_t *chip=candev->chip[0];
67 oscar_write_register(sjaMOD_RM, chip->chip_base_addr+SJAMOD);
70 cdr=oscar_read_register(chip->chip_base_addr+SJACDR);
71 oscar_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
73 oscar_write_register(0, chip->chip_base_addr+SJAIER);
76 oscar_write_register(0, chip->chip_base_addr+SJAMOD);
77 while (oscar_read_register(chip->chip_base_addr+SJAMOD)&sjaMOD_RM){
78 if(!i--) return -ENODEV;
80 oscar_write_register(0, chip->chip_base_addr+SJAMOD);
83 cdr=oscar_read_register(chip->chip_base_addr+SJACDR);
84 oscar_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
86 oscar_write_register(0, chip->chip_base_addr+SJAIER);
91 int oscar_init_hw_data(struct candevice_t *candev)
93 candev->res_addr = 0x0; // RESET address?
94 candev->nr_82527_chips = 0;
95 candev->nr_sja1000_chips = 1; // We've got a SJA1000 variant
96 candev->nr_all_chips= 1;
97 candev->flags |= CANDEV_PROGRAMMABLE_IRQ;
102 int oscar_init_chip_data(struct candevice_t *candev, int chipnr)
104 // i82527_fill_chipspecops(candev->chip[chipnr]);
105 // sja1000_fill_chipspecops(candev->chip[chipnr]);
106 sja1000p_fill_chipspecops(candev->chip[chipnr]);
108 candev->chip[chipnr]->chip_base_addr = can_ioport2ioptr(candev->io_addr);
109 candev->chip[chipnr]->clock = 12000000;
110 candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP; // we use an external tranceiver
111 candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | sjaOCR_TX0_LH;
112 // these three int_ registers are unused (we don't have this chip)
113 candev->chip[chipnr]->int_cpu_reg = 0;
114 candev->chip[chipnr]->int_clk_reg = 0;
115 candev->chip[chipnr]->int_bus_reg = 0;
120 int oscar_init_obj_data(struct canchip_t *chip, int objnr)
122 chip->msgobj[objnr]->obj_base_addr = chip->chip_base_addr;
127 int oscar_program_irq(struct candevice_t *candev)
129 // CAN_IRQ_L (active low) interrupt: PF2 / INT2 on our LH7A400 SoC
130 // This IRQ is set up already by the kernel.
135 void oscar_write_register(unsigned data, can_ioptr_t address)
137 can_outb(data,address);
140 unsigned oscar_read_register(can_ioptr_t address)
142 return can_inb(address);
145 /* !!! Don't change this function !!! */
146 int oscar_register(struct hwspecops_t *hwspecops)
148 hwspecops->request_io = oscar_request_io;
149 hwspecops->release_io = oscar_release_io;
150 hwspecops->reset = oscar_reset;
151 hwspecops->init_hw_data = oscar_init_hw_data;
152 hwspecops->init_chip_data = oscar_init_chip_data;
153 hwspecops->init_obj_data = oscar_init_obj_data;
154 hwspecops->write_register = oscar_write_register;
155 hwspecops->read_register = oscar_read_register;
156 hwspecops->program_irq = oscar_program_irq;