]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/oscar.c
LinCAN sources go through big white-space cleanup.
[lincan.git] / lincan / src / oscar.c
1 /**************************************************************************/
2 /* File: oscar.c - SJA1000 based card connected to ARM LH7A400 SoC        */
3 /*                                                                        */
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>      */
9 /*                                                                        */
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.                                              */
20 /*                                                                        */
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:                                                     */
24 /*                                                                        */
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 /**************************************************************************/
34
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"
40
41 #define IO_RANGE 0x80 // allow both basic CAN and PeliCAN modes for sja1000
42
43 int oscar_request_io(struct candevice_t *candev)
44 {
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);
47                 return -ENODEV;
48         }else {
49                 DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1);
50         }
51         return 0;
52 }
53
54 int oscar_release_io(struct candevice_t *candev)
55 {
56         can_release_io_region(candev->io_addr,IO_RANGE);
57
58         return 0;
59 }
60
61 int oscar_reset(struct candevice_t *candev)
62 {
63         int i;
64         struct canchip_t *chip=candev->chip[0];
65         unsigned cdr;
66
67         oscar_write_register(sjaMOD_RM, chip->chip_base_addr+SJAMOD);
68         udelay(1000);
69
70         cdr=oscar_read_register(chip->chip_base_addr+SJACDR);
71         oscar_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
72
73         oscar_write_register(0, chip->chip_base_addr+SJAIER);
74
75         i=20;
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;
79                 udelay(1000);
80                 oscar_write_register(0, chip->chip_base_addr+SJAMOD);
81         }
82
83         cdr=oscar_read_register(chip->chip_base_addr+SJACDR);
84         oscar_write_register(cdr|sjaCDR_PELICAN, chip->chip_base_addr+SJACDR);
85
86         oscar_write_register(0, chip->chip_base_addr+SJAIER);
87
88         return 0;
89 }
90
91 int oscar_init_hw_data(struct candevice_t *candev)
92 {
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;
98
99     return 0;
100 }
101
102 int oscar_init_chip_data(struct candevice_t *candev, int chipnr)
103 {
104     // i82527_fill_chipspecops(candev->chip[chipnr]);
105     // sja1000_fill_chipspecops(candev->chip[chipnr]);
106     sja1000p_fill_chipspecops(candev->chip[chipnr]);
107
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;
116
117     return 0;
118 }
119
120 int oscar_init_obj_data(struct canchip_t *chip, int objnr)
121 {
122     chip->msgobj[objnr]->obj_base_addr = chip->chip_base_addr;
123
124     return 0;
125 }
126
127 int oscar_program_irq(struct candevice_t *candev)
128 {
129     // CAN_IRQ_L (active low) interrupt: PF2 / INT2 on our LH7A400 SoC
130     // This IRQ is set up already by the kernel.
131
132     return 0;
133 }
134
135 void oscar_write_register(unsigned data, can_ioptr_t address)
136 {
137         can_outb(data,address);
138 }
139
140 unsigned oscar_read_register(can_ioptr_t address)
141 {
142         return can_inb(address);
143 }
144
145 /* !!! Don't change this function !!! */
146 int oscar_register(struct hwspecops_t *hwspecops)
147 {
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;
157         return 0;
158 }