1 /**************************************************************************/
2 /* File: mscan.h - Freescale MPC5200 MSCAN controller support */
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 /* Copyright (C) 2007-2008 Martin Petera <peterm4@fel.cvut.cz> */
8 /* Funded by OCERA and FRESCOR IST projects */
9 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
11 /* LinCAN is free software; you can redistribute it and/or modify it */
12 /* under terms of the GNU General Public License as published by the */
13 /* Free Software Foundation; either version 2, or (at your option) any */
14 /* later version. LinCAN is distributed in the hope that it will be */
15 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
16 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
17 /* General Public License for more details. You should have received a */
18 /* copy of the GNU General Public License along with LinCAN; see file */
19 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
20 /* Cambridge, MA 02139, USA. */
22 /* To allow use of LinCAN in the compact embedded systems firmware */
23 /* and RT-executives (RTEMS for example), main authors agree with next */
24 /* special exception: */
26 /* Including LinCAN header files in a file, instantiating LinCAN generics */
27 /* or templates, or linking other files with LinCAN objects to produce */
28 /* an application image/executable, does not by itself cause the */
29 /* resulting application image/executable to be covered by */
30 /* the GNU General Public License. */
31 /* This exception does not however invalidate any other reasons */
32 /* why the executable file might be covered by the GNU Public License. */
33 /* Publication of enhanced or derived LinCAN files is required although. */
34 /**************************************************************************/
36 #ifndef LINCAN_MSCAN_H
37 #define LINCAN_MSCAN_H
43 /* Debug - coarse approach */
45 /* standard LinCAN core debug - used only for MPC5200 driver part */
46 #define DEBUGMSG(fmt,args...) can_printk(KERN_ERR "lincan (debug): " fmt,##args)
48 /* dump specific parts of chip memory */
49 #define DUMPREGS(canchip) dump_regs(canchip)
50 #define DUMPBUFF(canchip, offset) dump_buff(canchip, offset)
51 #define DUMPFLT(canchip) dump_filter(canchip)
53 /* Debug Tx Rx operations */
54 #define DEBUGTX(fmt,args...) can_printk(KERN_ERR "lincan (debug): " fmt,##args)
55 #define DEBUGRX(fmt,args...) can_printk(KERN_ERR "lincan (debug): " fmt,##args)
57 #define DUMPREGS(canchip)
58 #define DUMPBUFF(canchip, offset)
59 #define DUMPFLT(canchip)
60 #define DEBUGTX(fmt,args...)
61 #define DEBUGRX(fmt,args...)
62 #endif /* MPC5200_DBG */
67 /* MSCAN register size */
71 /* Determine which clock source to use */
72 /* 0 - use IP Bus clock */
73 /* 1 - use SYS_XTAL_IN frequency */
74 #define MPC5200_CLKSRC 1
77 #define MPC5200_CLK_FREQ (MPC5200_SHARK_SYS_XTAL_FREQ/12) /* 33MHz */
79 #define MPC5200_CLK_FREQ (MPC5200_SHARK_IPB_FREQ/4) /* 33MHz */
83 int mscan_chip_config(struct canchip_t *chip);
84 int mscan_enable_configuration(struct canchip_t *chip);
85 int mscan_disable_configuration(struct canchip_t *chip);
87 int mscan_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, int sampl_pt, int flags);
88 int mscan_set_btregs(struct canchip_t *chip, unsigned short bcr0, unsigned short bcr1);
90 int mscan_start_chip(struct canchip_t *chip);
91 int mscan_stop_chip(struct canchip_t *chip);
92 int mscan_attach_to_chip(struct canchip_t *chip);
93 int mscan_release_chip(struct canchip_t *chip);
95 int mscan_standard_mask(struct canchip_t *chip, unsigned short code, unsigned short mask);
96 int mscan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask);
97 /* int mscan_message15_mask(int irq, struct canchip_t *chip); */
99 int mscan_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj);
100 int mscan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg);
101 int mscan_send_msg(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg);
102 int mscan_remote_request(struct canchip_t *chip, struct msgobj_t *obj);
104 int mscan_irq_handler(int irq, struct canchip_t *chip);
105 /* int mscan_irq_accept(int irq, struct canchip_t *chip); */
106 int mscan_config_irqs(struct canchip_t *chip, short irqs);
108 int mscan_clear_objects(struct canchip_t *chip);
109 int mscan_check_tx_stat(struct canchip_t *chip);
110 int mscan_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj);
111 int mscan_filtch_rq(struct canchip_t *chip, struct msgobj_t * obj);
113 int mscan_register(struct chipspecops_t *chipspecops);
114 int mscan_fill_chipspecops(struct canchip_t *chip);
116 int mscan_reset_chip(struct canchip_t * chip);
118 extern inline void can_write_reg_w(const struct canchip_t *pchip, uint16_t data, unsigned reg)
120 can_ioptr_t address = pchip->chip_base_addr + reg;
121 #ifndef CONFIG_OC_LINCAN_DYNAMICIO
122 writew(data,address);
123 #else /*CONFIG_OC_LINCAN_DYNAMICIO*/
124 pchip->write_register(data, address);
125 #endif /*CONFIG_OC_LINCAN_DYNAMICIO*/
128 extern inline uint16_t can_read_reg_w(const struct canchip_t *pchip, unsigned reg)
130 can_ioptr_t address = pchip->chip_base_addr + reg;
131 #ifndef CONFIG_OC_LINCAN_DYNAMICIO
132 return readw(address);
133 #else /*CONFIG_OC_LINCAN_DYNAMICIO*/
134 return pchip->read_register(address);
135 #endif /*CONFIG_OC_LINCAN_DYNAMICIO*/
139 /* BasicCAN mode address map */
140 #define MSCAN_CTL0 0x00 /* Control Register 0 */
141 #define MSCAN_CTL1 0x01 /* Control Register 1 */
142 #define MSCAN_BTR0 0x04 /* Bus Timing Register 0 */
143 #define MSCAN_BTR1 0x05 /* Bus Timing Register 1 */
144 #define MSCAN_RFLG 0x08 /* Receive Flag Register */
145 #define MSCAN_RIER 0x09 /* Receiver Interrupt Enable Register */
146 #define MSCAN_TFLG 0x0c /* Transmitter Flag Register */
147 #define MSCAN_TIER 0x0d /* Transmitter Interrupt Enable Register */
148 #define MSCAN_TARQ 0x10 /* Transmitter Message Abort Request Register */
149 #define MSCAN_TAAK 0x11 /* Transmitter Message Abort Acknowledge Register */
150 #define MSCAN_TBSEL 0x14 /* Transmitter Buffer Selection */
151 #define MSCAN_IDAC 0x15 /* Identifier Acceptance Control Register */
152 /* Reserved 0x18, 0x19 */
153 #define MSCAN_RXERR 0x1c /* Receive Error Counter Register */
154 #define MSCAN_TXERR 0x1d /* Transmitt Error Counter Register */
156 /* Acceptance Filters */
157 #define MSCAN_IDAR0 0x20 /* Identifier Acceptance Register 0 */
158 #define MSCAN_IDAR1 0x21 /* Identifier Acceptance Register 1 */
159 #define MSCAN_IDAR2 0x24 /* Identifier Acceptance Register 2 */
160 #define MSCAN_IDAR3 0x25 /* Identifier Acceptance Register 3 */
161 #define MSCAN_IDMR0 0x28 /* Identifier Mask Register 0 */
162 #define MSCAN_IDMR1 0x29 /* Identifier Mask Register 1 */
163 #define MSCAN_IDMR2 0x2c /* Identifier Mask Register 2 */
164 #define MSCAN_IDMR3 0x2d /* Identifier Mask Register 3 */
166 #define MSCAN_IDAR4 0x30 /* Identifier Acceptance Register 4 */
167 #define MSCAN_IDAR5 0x31 /* Identifier Acceptance Register 5 */
168 #define MSCAN_IDAR6 0x34 /* Identifier Acceptance Register 6 */
169 #define MSCAN_IDAR7 0x35 /* Identifier Acceptance Register 7 */
170 #define MSCAN_IDMR4 0x38 /* Identifier Mask Register 4 */
171 #define MSCAN_IDMR5 0x39 /* Identifier Mask Register 5 */
172 #define MSCAN_IDMR6 0x3c /* Identifier Mask Register 6 */
173 #define MSCAN_IDMR7 0x3d /* Identifier Mask Register 7 */
176 #define MSCAN_RXFG 0x40 /* Foregroung Receive Buffer 0x40-0x5f */
177 #define MSCAN_TXFG 0x60 /* Foregroung Receive Buffer 0x60-0x7f */
180 /* BaudRate minimal and maximal TSEG values */
181 #define MSCAN_TSEG1_MIN 4 /* means 1 Tq clock cycle */
182 #define MSCAN_TSEG1_MAX 16 /* means 16 Tq clock cycles */
183 #define MSCAN_TSEG2_MIN 2 /* means 1 Tq clock cycle */
184 #define MSCAN_TSEG2_MAX 8 /* means 8 Tq clock cycles */
185 #define MSCAN_TSEG_MIN (MSCAN_TSEG1_MIN + MSCAN_TSEG2_MIN)
186 #define MSCAN_TSEG_MAX (MSCAN_TSEG1_MAX + MSCAN_TSEG2_MAX)
188 #define MSCAN_BRP_MIN 1
189 #define MSCAN_BRP_MAX 64
192 MSCAN_CTL0_RXFRM = 1 << 7, /* Received Frame Flag - rw */
193 MSCAN_CTL0_RXACT = 1 << 6, /* Receiver Active Status - ro */
194 MSCAN_CTL0_CSWAI = 1 << 5, /* CAN Stops in Wait Mode - rw */
195 MSCAN_CTL0_SYNCH = 1 << 4, /* Synchronized Status - ro */
196 MSCAN_CTL0_TIME = 1 << 3, /* Timer Enable - rw */
197 MSCAN_CTL0_WUPE = 1 << 2, /* WakeUp Enable - rw */
198 MSCAN_CTL0_SLPRQ = 1 << 1, /* Sleep Request - rw */
199 MSCAN_CTL0_INITRQ = 1 << 0, /* Initialization Mode Request - rw */
203 MSCAN_CTL1_CANE = 1 << 7, /* MSCAN Enable rw */
204 MSCAN_CTL1_CLKSRC = 1 << 6, /* MSCAN Clock Source rw */
205 MSCAN_CTL1_LOOPB = 1 << 5, /* Loob-Back Self Test Mode rw */
206 MSCAN_CTL1_LISTEN = 1 << 4, /* Listen-Only Mode rw */
207 MSCAN_CTL1_WUPM = 1 << 2, /* WakeUp Mode rw */
208 MSCAN_CTL1_SLPAK = 1 << 1, /* Sleep Mode Acknowledge - ro */
209 MSCAN_CTL1_INITAK = 1 << 0, /* Initialization Mode Acknowledge - ro */
211 MSCAN_CTL1_RSVD = 1 << 3, /* Reserved */
215 MSCAN_BTR0_SJW = 0xa0, /* Synchronization Jump Width: 0 to 3 (1 to 4 Tq) */
216 MSCAN_BTR0_BRP = 0x3f, /* Baud Rate Prescaler: 0 to 63 (1 to 64) */
220 MSCAN_BTR1_SAMP = 1 << 7, /* Sampling: 0-One sample, 1-Three samples per bit */
221 MSCAN_BTR1_TSEG2 = 0x70, /* TSEG2: 3 bits */
222 MSCAN_BTR1_TSEG1 = 0x0f, /* TSEG1: 4 bits */
225 /* Interupt & Interrupt Enable Registers */
227 MSCAN_RFLG_WUPIF = 1 << 7, /* WakeUp Interrupt Flag - rw */
228 MSCAN_RFLG_CSCIF = 1 << 6, /* CAN Status Change Interrupt Flag - rw */
229 MSCAN_RFLG_RSTAT = 0x30, /* Receiver Status Bits: 0-RxOK, 1-RxWRN, 2-RxERR, 3-BusOff - ro */
230 MSCAN_RFLG_TSTAT = 0x0c, /* Transmitter Status Bits: 0-TxOK, 1-TxWRN, 2-TxErr, 3-BusOff - ro */
231 MSCAN_RFLG_OVRIF = 1 << 1, /* Overrun Interrupt Flag - rw */
232 MSCAN_RFLG_RXF = 1 << 0, /* Receive Buffer Full - rw */
236 MSCAN_RIER_WUPIE = 1 << 7, /* WakeUp Interrupt Enable - rw */
237 MSCAN_RIER_CSCIE = 1 << 6, /* CAN Status Change Interrupt Enable - rw */
238 MSCAN_RIER_RSTATE = 0x30, /* Receiver Status Change Enable: 0-Never, 1-BusOff, 2-BusOff+RxErr, 3-All - rw */
239 MSCAN_RIER_TSTATE = 0x0c, /* Transmitter Status Change Enable: 0-Never, 1-BusOff, 2-BusOff+TxErr, 3-All - rw */
240 MSCAN_RIER_OVRIE = 1 << 1, /* Overrun Interrupt Enable - rw */
241 MSCAN_RIER_RXFIE = 1 << 0, /* Receive Buffer Full Interrupt Enable - rw */
245 MSCAN_TFLG_TXE = 0x07, /* Transmitter Buffer Empty */
247 MSCAN_TFLG_RSVD = 0xf8, /* Reserved */
251 MSCAN_TIER_TXE = 0x07, /* Transmitter Empty Interrupt Enable */
253 MSCAN_TIER_RSVD = 0xf8, /* Reserved */
258 MSCAN_TARQ_ABTRQ = 0x07, /* Abort Request */
260 MSCAN_TARQ_RSVD = 0xf8, /* Reserved */
264 MSCAN_TAAK_ABTAK = 0x07, /* Abort Acknowledge */
266 MSCAN_TAAK_RSVD = 0xf8, /* Reserved */
270 MSCAN_TBSEL_TX = 0x07, /* Transmitt Buffer Select - prioritize lower */
272 MSCAN_TBSEL_RSVD = 0xf8, /* Reserved */
276 MSCAN_IDAC_IDAM = 0x30, /* Identifier Acceptance Mode: 0-Two 32bit, 1-Four 16-bit. 2-Eight 8bit, 3-Closed */
277 MSCAN_IDAC_IDHIT = 0x07, /* Identifier Acceptance Hit Indicator */
279 MSCAN_IDAC_RSVD = 0xa8, /* Reserved */
282 /* Message Buffer Organization */
283 #define MSCAN_MSGBUFF_ID0 0x00 /* Identifier Register 0 */
284 #define MSCAN_MSGBUFF_ID1 0x01 /* Identifier Register 1 */
285 #define MSCAN_MSGBUFF_ID2 0x04 /* Identifier Register 2 */
286 #define MSCAN_MSGBUFF_ID3 0x05 /* Identifier Register 3 */
288 #define MSCAN_MSGBUFF_DATA0 0x08 /* Data Segment Register 0 */
289 #define MSCAN_MSGBUFF_DATA1 0x09 /* Data Segment Register 1 */
290 #define MSCAN_MSGBUFF_DATA2 0x0c /* Data Segment Register 2 */
291 #define MSCAN_MSGBUFF_DATA3 0x0d /* Data Segment Register 3 */
292 #define MSCAN_MSGBUFF_DATA4 0x10 /* Data Segment Register 4 */
293 #define MSCAN_MSGBUFF_DATA5 0x11 /* Data Segment Register 5 */
294 #define MSCAN_MSGBUFF_DATA6 0x14 /* Data Segment Register 6 */
295 #define MSCAN_MSGBUFF_DATA7 0x15 /* Data Segment Register 7 */
297 #define MSCAN_MSGBUFF_DLEN 0x18 /* Data Length Register */
298 #define MSCAN_MSGBUFF_TXPRIO 0x19 /* Transmitt Buffer Priority - Not Applicable for Rx buffers */
299 #define MSCAN_MSGBUFF_TSH 0x1c /* Time Stamp Register High */
300 #define MSCAN_MSGBUFF_TSL 0x1d /* Time Stamp Register Low */
302 struct mscan_msg_buffer{
304 uint8_t id_0; /* CAN identifier: ID_EXT {28:21} OR ID_STD {10:3} */
305 uint8_t id_1; /* CAN identifier: ID_EXT {20:18},SRR,IDE,ID_EXT{17:15} OR ID_STD{2:0},RTR,IDE, reserved */
306 uint16_t spacer_0; /* spacer for compatibility */
307 uint8_t id_2; /* CAN identifier: IDE_EXT{14:7} OR reserved for ID_STD */
308 uint8_t id_3; /* CAN identifier: ID_EXT{6:0},RTR OR reserved for ID_STD */
309 uint16_t spacer_1; /* spacer for compatibility */
310 uint8_t data_0; /* CAN data byte 0 */
311 uint8_t data_1; /* CAN data byte 1 */
312 uint16_t spacer_2; /* spacer for compatibility */
313 uint8_t data_2; /* CAN data byte 2 */
314 uint8_t data_3; /* CAN data byte 3 */
315 uint16_t spacer_3; /* spacer for compatibility */
316 uint8_t data_4; /* CAN data byte 4 */
317 uint8_t data_5; /* CAN data byte 5 */
318 uint16_t spacer_4; /* spacer for compatibility */
319 uint8_t data_6; /* CAN data byte 6 */
320 uint8_t data_7; /* CAN data byte 7 */
321 uint16_t spacer_5; /* spacer for compatibility */
322 uint8_t data_len; /* CAN data length: 0xf0 reserved, DLC{3:0} */
323 uint8_t local_prio; /* MSCAN TX local priority - unused fro TX buffer */
324 uint16_t spacer_6; /* spacer for compatibility */
325 uint8_t timestamp_h; /* local timestamp - High byte - Read Only */
326 uint8_t timestamp_l; /* local timestamp - Low byte - Read Only */
329 /* structure for memory layout of acceptance
332 struct mscan_flt_regs{
365 #endif /* LINCAN_MSCAN_H */