aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/cc770/cc770.h
blob: ca5b768663672840930f37cbb6dd5548f74df670 (plain) (blame)
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*
 * cc770.h - Bosch CC770 and Intel AN82527 network device driver
 *
 * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
 *
 * Derived from the old Socket-CAN i82527 driver:
 *
 * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Volkswagen nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * Alternatively, provided that this notice is retained in full, this
 * software may be distributed under the terms of the GNU General
 * Public License ("GPL") version 2, in which case the provisions of the
 * GPL apply INSTEAD OF those given above.
 *
 * The provided data structures and external interfaces from this code
 * are not restricted to be used by modules with a GPL compatible license.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * Send feedback to <socketcan-users@lists.berlios.de>
 */

#ifndef CC770_DEV_H
#define CC770_DEV_H

#include <linux/can/dev.h>

struct cc770_msgobj {
	u8 ctrl0;
	u8 ctrl1;
	u8 id[4];
	u8 config;
	u8 data[8];
	u8 dontuse;		/* padding */
} __attribute__ ((packed));

struct cc770_regs {
	union {
		struct cc770_msgobj msgobj[16]; /* Message object 1..15 */
		struct {
			u8 control;		/* Control Register */
			u8 status;		/* Status Register */
			u8 cpu_interface;	/* CPU Interface Register */
			u8 dontuse1;
			u8 high_speed_read[2];	/* High Speed Read */
			u8 global_mask_std[2];	/* Standard Global Mask */
			u8 global_mask_ext[4];	/* Extended Global Mask */
			u8 msg15_mask[4];	/* Message 15 Mask */
			u8 dontuse2[15];
			u8 clkout;		/* Clock Out Register */
			u8 dontuse3[15];
			u8 bus_config;		/* Bus Configuration Register */
			u8 dontuse4[15];
			u8 bit_timing_0;	/* Bit Timing Register byte 0 */
			u8 dontuse5[15];
			u8 bit_timing_1;	/* Bit Timing Register byte 1 */
			u8 dontuse6[15];
			u8 interrupt;		/* Interrupt Register */
			u8 dontuse7[15];
			u8 rx_error_counter;	/* Receive Error Counter */
			u8 dontuse8[15];
			u8 tx_error_counter;	/* Transmit Error Counter */
			u8 dontuse9[31];
			u8 p1_conf;
			u8 dontuse10[15];
			u8 p2_conf;
			u8 dontuse11[15];
			u8 p1_in;
			u8 dontuse12[15];
			u8 p2_in;
			u8 dontuse13[15];
			u8 p1_out;
			u8 dontuse14[15];
			u8 p2_out;
			u8 dontuse15[15];
			u8 serial_reset_addr;
		};
	};
} __attribute__ ((packed));

/* Control Register (0x00) */
#define CTRL_INI	0x01	/* Initialization */
#define CTRL_IE		0x02	/* Interrupt Enable */
#define CTRL_SIE	0x04	/* Status Interrupt Enable */
#define CTRL_EIE	0x08	/* Error Interrupt Enable */
#define CTRL_EAF	0x20	/* Enable additional functions */
#define CTRL_CCE	0x40	/* Change Configuration Enable */

/* Status Register (0x01) */
#define STAT_LEC_STUFF	0x01	/* Stuff error */
#define STAT_LEC_FORM	0x02	/* Form error */
#define STAT_LEC_ACK	0x03	/* Acknowledgement error */
#define STAT_LEC_BIT1	0x04	/* Bit1 error */
#define STAT_LEC_BIT0	0x05	/* Bit0 error */
#define STAT_LEC_CRC	0x06	/* CRC error */
#define STAT_LEC_MASK	0x07	/* Last Error Code mask */
#define STAT_TXOK	0x08	/* Transmit Message Successfully */
#define STAT_RXOK	0x10	/* Receive Message Successfully */
#define STAT_WAKE	0x20	/* Wake Up Status */
#define STAT_WARN	0x40	/* Warning Status */
#define STAT_BOFF	0x80	/* Bus Off Status */

/* CPU Interface Register (0x02) */
#define CPUIF_CEN	0x01	/* Clock Out Enable */
#define CPUIF_MUX	0x04	/* Multiplex */
#define CPUIF_SLP	0x08	/* Sleep */
#define CPUIF_PWD	0x10	/* Power Down Mode */
#define CPUIF_DMC	0x20	/* Divide Memory Clock */
#define CPUIF_DSC	0x40	/* Divide System Clock */
#define CPUIF_RST	0x80	/* Hardware Reset Status */

/* Clock Out Register (0x1f) */
#define CLKOUT_CD_MASK  0x0f	/* Clock Divider mask */
#define CLKOUT_SL_MASK	0x30	/* Slew Rate mask */
#define CLKOUT_SL_SHIFT	4

/* Bus Configuration Register (0x2f) */
#define BUSCFG_DR0	0x01	/* Disconnect RX0 Input / Select RX input */
#define BUSCFG_DR1	0x02	/* Disconnect RX1 Input / Silent mode */
#define BUSCFG_DT1	0x08	/* Disconnect TX1 Output */
#define BUSCFG_POL	0x20	/* Polarity dominant or recessive */
#define BUSCFG_CBY	0x40	/* Input Comparator Bypass */

/* Message Control Register 0 (Base Address + 0x0) */
#define INTPND_RES	0x01	/* No Interrupt pending */
#define INTPND_SET	0x02	/* Interrupt pending */
#define INTPND_UNC	0x03
#define RXIE_RES	0x04	/* Receive Interrupt Disable */
#define RXIE_SET	0x08	/* Receive Interrupt Enable */
#define RXIE_UNC	0x0c
#define TXIE_RES	0x10	/* Transmit Interrupt Disable */
#define TXIE_SET	0x20	/* Transmit Interrupt Enable */
#define TXIE_UNC	0x30
#define MSGVAL_RES	0x40	/* Message Invalid */
#define MSGVAL_SET	0x80	/* Message Valid */
#define MSGVAL_UNC	0xc0

/* Message Control Register 1 (Base Address + 0x01) */
#define NEWDAT_RES	0x01	/* No New Data */
#define NEWDAT_SET	0x02	/* New Data */
#define NEWDAT_UNC	0x03
#define MSGLST_RES	0x04	/* No Message Lost */
#define MSGLST_SET	0x08	/* Message Lost */
#define MSGLST_UNC	0x0c
#define CPUUPD_RES	0x04	/* No CPU Updating */
#define CPUUPD_SET	0x08	/* CPU Updating */
#define CPUUPD_UNC	0x0c
#define TXRQST_RES	0x10	/* No Transmission Request */
#define TXRQST_SET	0x20	/* Transmission Request */
#define TXRQST_UNC	0x30
#define RMTPND_RES	0x40	/* No Remote Request Pending */
#define RMTPND_SET	0x80	/* Remote Request Pending */
#define RMTPND_UNC	0xc0

/* Message Configuration Register (Base Address + 0x06) */
#define MSGCFG_XTD	0x04	/* Extended Identifier */
#define MSGCFG_DIR	0x08	/* Direction is Transmit */

#define MSGOBJ_FIRST	1
#define MSGOBJ_LAST	15

#define CC770_IO_SIZE	0x100
#define CC770_MAX_IRQ	20	/* max. number of interrupts handled in ISR */

#define CC770_ECHO_SKB_MAX	1

#define cc770_read_reg(priv, member)					\
	priv->read_reg(priv, offsetof(struct cc770_regs, member))

#define cc770_write_reg(priv, member, value)				\
	priv->write_reg(priv, offsetof(struct cc770_regs, member), value)

/*
 * Message objects and flags used by this driver
 */
#define CC770_OBJ_FLAG_RX 	0x01
#define CC770_OBJ_FLAG_RTR	0x02
#define CC770_OBJ_FLAG_EFF	0x04

enum {
	CC770_OBJ_RX0 = 0,	/* for receiving normal messages */
	CC770_OBJ_RX1,		/* for receiving normal messages */
	CC770_OBJ_RX_RTR0,	/* for receiving remote transmission requests */
	CC770_OBJ_RX_RTR1,	/* for receiving remote transmission requests */
	CC770_OBJ_TX,		/* for sending messages */
	CC770_OBJ_MAX
};

#define obj2msgobj(o)	(MSGOBJ_LAST - (o)) /* message object 11..15 */

/*
 * CC770 private data structure
 */
struct cc770_priv {
	struct can_priv can;	/* must be the first member */
	int open_time;
	struct sk_buff *echo_skb;

	/* the lower-layer is responsible for appropriate locking */
	u8 (*read_reg)(const struct cc770_priv *priv, int reg);
	void (*write_reg)(const struct cc770_priv *priv, int reg, u8 val);
	void (*pre_irq)(const struct cc770_priv *priv);
	void (*post_irq)(const struct cc770_priv *priv);

	void *priv;		/* for board-specific data */
	struct net_device *dev;

	void __iomem *reg_base;	/* ioremap'ed address to registers */
	unsigned long irq_flags;	/* for request_irq() */

	unsigned char obj_flags[CC770_OBJ_MAX];
	u8 control_normal_mode;	/* Control register for normal mode */
	u8 cpu_interface;	/* CPU interface register */
	u8 clkout;		/* Clock out register */
	u8 bus_config;		/* Bus conffiguration register */
};

struct net_device *alloc_cc770dev(int sizeof_priv);
void free_cc770dev(struct net_device *dev);
int register_cc770dev(struct net_device *dev);
void unregister_cc770dev(struct net_device *dev);

#endif /* CC770_DEV_H */