Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | /* * CAN bus driver for Bosch C_CAN controller * * Copyright (C) 2010 ST Microelectronics * Bhupesh Sharma <bhupesh.sharma@st.com> * * Borrowed heavily from the C_CAN driver originally written by: * Copyright (C) 2007 * - Sascha Hauer, Marc Kleine-Budde, Pengutronix <s.hauer@pengutronix.de> * - Simon Kallweit, intefo AG <simon.kallweit@intefo.ch> * * Bosch C_CAN controller is compliant to CAN protocol version 2.0 part A and B. * Bosch C_CAN user manual can be obtained from: * http://www.semiconductors.bosch.de/media/en/pdf/ipmodules_1/c_can/ * users_manual_c_can.pdf * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ #ifndef C_CAN_H #define C_CAN_H /* message object split */ #define C_CAN_NO_OF_OBJECTS 32 #define C_CAN_MSG_OBJ_RX_NUM 16 #define C_CAN_MSG_OBJ_TX_NUM 16 #define C_CAN_MSG_OBJ_RX_FIRST 1 #define C_CAN_MSG_OBJ_RX_LAST (C_CAN_MSG_OBJ_RX_FIRST + \ C_CAN_MSG_OBJ_RX_NUM - 1) #define C_CAN_MSG_OBJ_TX_FIRST (C_CAN_MSG_OBJ_RX_LAST + 1) #define C_CAN_MSG_OBJ_TX_LAST (C_CAN_MSG_OBJ_TX_FIRST + \ C_CAN_MSG_OBJ_TX_NUM - 1) #define C_CAN_MSG_OBJ_RX_SPLIT 9 #define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) #define RECEIVE_OBJECT_BITS 0x0000ffff enum reg { C_CAN_CTRL_REG = 0, C_CAN_CTRL_EX_REG, C_CAN_STS_REG, C_CAN_ERR_CNT_REG, C_CAN_BTR_REG, C_CAN_INT_REG, C_CAN_TEST_REG, C_CAN_BRPEXT_REG, C_CAN_IF1_COMREQ_REG, C_CAN_IF1_COMMSK_REG, C_CAN_IF1_MASK1_REG, C_CAN_IF1_MASK2_REG, C_CAN_IF1_ARB1_REG, C_CAN_IF1_ARB2_REG, C_CAN_IF1_MSGCTRL_REG, C_CAN_IF1_DATA1_REG, C_CAN_IF1_DATA2_REG, C_CAN_IF1_DATA3_REG, C_CAN_IF1_DATA4_REG, C_CAN_IF2_COMREQ_REG, C_CAN_IF2_COMMSK_REG, C_CAN_IF2_MASK1_REG, C_CAN_IF2_MASK2_REG, C_CAN_IF2_ARB1_REG, C_CAN_IF2_ARB2_REG, C_CAN_IF2_MSGCTRL_REG, C_CAN_IF2_DATA1_REG, C_CAN_IF2_DATA2_REG, C_CAN_IF2_DATA3_REG, C_CAN_IF2_DATA4_REG, C_CAN_TXRQST1_REG, C_CAN_TXRQST2_REG, C_CAN_NEWDAT1_REG, C_CAN_NEWDAT2_REG, C_CAN_INTPND1_REG, C_CAN_INTPND2_REG, C_CAN_MSGVAL1_REG, C_CAN_MSGVAL2_REG, C_CAN_FUNCTION_REG, }; static const u16 reg_map_c_can[] = { [C_CAN_CTRL_REG] = 0x00, [C_CAN_STS_REG] = 0x02, [C_CAN_ERR_CNT_REG] = 0x04, [C_CAN_BTR_REG] = 0x06, [C_CAN_INT_REG] = 0x08, [C_CAN_TEST_REG] = 0x0A, [C_CAN_BRPEXT_REG] = 0x0C, [C_CAN_IF1_COMREQ_REG] = 0x10, [C_CAN_IF1_COMMSK_REG] = 0x12, [C_CAN_IF1_MASK1_REG] = 0x14, [C_CAN_IF1_MASK2_REG] = 0x16, [C_CAN_IF1_ARB1_REG] = 0x18, [C_CAN_IF1_ARB2_REG] = 0x1A, [C_CAN_IF1_MSGCTRL_REG] = 0x1C, [C_CAN_IF1_DATA1_REG] = 0x1E, [C_CAN_IF1_DATA2_REG] = 0x20, [C_CAN_IF1_DATA3_REG] = 0x22, [C_CAN_IF1_DATA4_REG] = 0x24, [C_CAN_IF2_COMREQ_REG] = 0x40, [C_CAN_IF2_COMMSK_REG] = 0x42, [C_CAN_IF2_MASK1_REG] = 0x44, [C_CAN_IF2_MASK2_REG] = 0x46, [C_CAN_IF2_ARB1_REG] = 0x48, [C_CAN_IF2_ARB2_REG] = 0x4A, [C_CAN_IF2_MSGCTRL_REG] = 0x4C, [C_CAN_IF2_DATA1_REG] = 0x4E, [C_CAN_IF2_DATA2_REG] = 0x50, [C_CAN_IF2_DATA3_REG] = 0x52, [C_CAN_IF2_DATA4_REG] = 0x54, [C_CAN_TXRQST1_REG] = 0x80, [C_CAN_TXRQST2_REG] = 0x82, [C_CAN_NEWDAT1_REG] = 0x90, [C_CAN_NEWDAT2_REG] = 0x92, [C_CAN_INTPND1_REG] = 0xA0, [C_CAN_INTPND2_REG] = 0xA2, [C_CAN_MSGVAL1_REG] = 0xB0, [C_CAN_MSGVAL2_REG] = 0xB2, }; static const u16 reg_map_d_can[] = { [C_CAN_CTRL_REG] = 0x00, [C_CAN_CTRL_EX_REG] = 0x02, [C_CAN_STS_REG] = 0x04, [C_CAN_ERR_CNT_REG] = 0x08, [C_CAN_BTR_REG] = 0x0C, [C_CAN_BRPEXT_REG] = 0x0E, [C_CAN_INT_REG] = 0x10, [C_CAN_TEST_REG] = 0x14, [C_CAN_FUNCTION_REG] = 0x18, [C_CAN_TXRQST1_REG] = 0x88, [C_CAN_TXRQST2_REG] = 0x8A, [C_CAN_NEWDAT1_REG] = 0x9C, [C_CAN_NEWDAT2_REG] = 0x9E, [C_CAN_INTPND1_REG] = 0xB0, [C_CAN_INTPND2_REG] = 0xB2, [C_CAN_MSGVAL1_REG] = 0xC4, [C_CAN_MSGVAL2_REG] = 0xC6, [C_CAN_IF1_COMREQ_REG] = 0x100, [C_CAN_IF1_COMMSK_REG] = 0x102, [C_CAN_IF1_MASK1_REG] = 0x104, [C_CAN_IF1_MASK2_REG] = 0x106, [C_CAN_IF1_ARB1_REG] = 0x108, [C_CAN_IF1_ARB2_REG] = 0x10A, [C_CAN_IF1_MSGCTRL_REG] = 0x10C, [C_CAN_IF1_DATA1_REG] = 0x110, [C_CAN_IF1_DATA2_REG] = 0x112, [C_CAN_IF1_DATA3_REG] = 0x114, [C_CAN_IF1_DATA4_REG] = 0x116, [C_CAN_IF2_COMREQ_REG] = 0x120, [C_CAN_IF2_COMMSK_REG] = 0x122, [C_CAN_IF2_MASK1_REG] = 0x124, [C_CAN_IF2_MASK2_REG] = 0x126, [C_CAN_IF2_ARB1_REG] = 0x128, [C_CAN_IF2_ARB2_REG] = 0x12A, [C_CAN_IF2_MSGCTRL_REG] = 0x12C, [C_CAN_IF2_DATA1_REG] = 0x130, [C_CAN_IF2_DATA2_REG] = 0x132, [C_CAN_IF2_DATA3_REG] = 0x134, [C_CAN_IF2_DATA4_REG] = 0x136, }; enum c_can_dev_id { BOSCH_C_CAN_PLATFORM, BOSCH_C_CAN, BOSCH_D_CAN, }; /* c_can private data structure */ struct c_can_priv { struct can_priv can; /* must be the first member */ struct napi_struct napi; struct net_device *dev; struct device *device; atomic_t tx_active; unsigned long tx_dir; int last_status; u16 (*read_reg) (const struct c_can_priv *priv, enum reg index); void (*write_reg) (const struct c_can_priv *priv, enum reg index, u16 val); u32 (*read_reg32) (const struct c_can_priv *priv, enum reg index); void (*write_reg32) (const struct c_can_priv *priv, enum reg index, u32 val); void __iomem *base; const u16 *regs; void *priv; /* for board-specific data */ enum c_can_dev_id type; u32 __iomem *raminit_ctrlreg; int instance; void (*raminit) (const struct c_can_priv *priv, bool enable); u32 comm_rcv_high; u32 rxmasked; u32 dlc[C_CAN_MSG_OBJ_TX_NUM]; }; struct net_device *alloc_c_can_dev(void); void free_c_can_dev(struct net_device *dev); int register_c_can_dev(struct net_device *dev); void unregister_c_can_dev(struct net_device *dev); #ifdef CONFIG_PM int c_can_power_up(struct net_device *dev); int c_can_power_down(struct net_device *dev); #endif #endif /* C_CAN_H */ |