ocfs2: Enable refcount tree support.
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / cpc-usb / sja2m16c_2.c
blobbf0230fb7780991ef4c9cc56fcfae1c5d8cbdab3
1 /****************************************************************************
3 * Copyright (c) 2003,2004 by EMS Dr. Thomas Wuensche
5 * - All rights reserved -
7 * This code is provided "as is" without warranty of any kind, either
8 * expressed or implied, including but not limited to the liability
9 * concerning the freedom from material defects, the fitness for parti-
10 * cular purposes or the freedom of proprietary rights of third parties.
12 *****************************************************************************
13 * Module name.: cpcusb
14 *****************************************************************************
15 * Include file: cpc.h
16 *****************************************************************************
17 * Project.....: Windows Driver Development Kit
18 * Filename....: sja2m16c.cpp
19 * Authors.....: (GU) Gerhard Uttenthaler
20 * (CS) Christian Schoett
21 *****************************************************************************
22 * Short descr.: converts baudrate between SJA1000 and M16C
23 *****************************************************************************
24 * Description.: handles the baudrate conversion from SJA1000 parameters to
25 * M16C parameters
26 *****************************************************************************
27 * Address : EMS Dr. Thomas Wuensche
28 * Sonnenhang 3
29 * D-85304 Ilmmuenster
30 * Tel. : +49-8441-490260
31 * Fax. : +49-8441-81860
32 * email: support@ems-wuensche.com
33 *****************************************************************************
34 * History
35 *****************************************************************************
36 * Version Date Auth Remark
38 * 01.00 ?? GU - initial release
39 * 01.10 ?????????? CS - adapted to fit into the USB Windows driver
40 * 02.00 18.08.2004 GU - improved the baudrate calculating algorithm
41 * - implemented acceptance filtering
42 * 02.10 10.09.2004 CS - adapted to fit into the USB Windows driver
43 *****************************************************************************
44 * ToDo's
45 *****************************************************************************
48 /****************************************************************************/
49 /* I N C L U D E S
51 #include <linux/kernel.h>
52 #include <linux/errno.h>
53 #include <linux/init.h>
54 #include <linux/slab.h>
55 #include <linux/vmalloc.h>
56 #include <linux/module.h>
57 #include <linux/poll.h>
58 #include <linux/smp_lock.h>
59 #include <linux/completion.h>
60 #include <asm/uaccess.h>
61 #include <linux/usb.h>
63 #include "cpc.h"
64 #include "cpc_int.h"
65 #include "cpcusb.h"
67 #include "sja2m16c.h"
69 /*********************************************************************/
70 int baudrate_m16c(int clk, int brp, int pr, int ph1, int ph2)
72 return (16000000 / (1 << clk)) / 2 / (brp + 1) / (1 + pr + 1 +
73 ph1 + 1 + ph2 +
74 1);
78 /*********************************************************************/
79 int samplepoint_m16c(int brp, int pr, int ph1, int ph2)
81 return (100 * (1 + pr + 1 + ph1 + 1)) / (1 + pr + 1 + ph1 + 1 +
82 ph2 + 1);
86 /****************************************************************************
87 * Function.....: SJA1000_TO_M16C_BASIC_Params
89 * Task.........: This routine converts SJA1000 CAN btr parameters into M16C
90 * parameters based on the sample point and the error. In
91 * addition it converts the acceptance filter parameters to
92 * suit the M16C parameters
94 * Parameters...: None
96 * Return values: None
98 * Comments.....:
99 *****************************************************************************
100 * History
101 *****************************************************************************
102 * 19.01.2005 CS - modifed the conversion of SJA1000 filter params into
103 * M16C params. Due to compatibility reasons with the
104 * older 82C200 CAN controller the SJA1000
105 ****************************************************************************/
106 int SJA1000_TO_M16C_BASIC_Params(CPC_MSG_T * in)
108 int sjaBaudrate;
109 int sjaSamplepoint;
110 int *baudrate_error; // BRP[0..15], PR[0..7], PH1[0..7], PH2[0..7]
111 int *samplepoint_error; // BRP[0..15], PR[0..7], PH1[0..7], PH2[0..7]
112 int baudrate_error_merk;
113 int clk, brp, pr, ph1, ph2;
114 int clk_merk, brp_merk, pr_merk, ph1_merk, ph2_merk;
115 int index;
116 unsigned char acc_code0, acc_code1, acc_code2, acc_code3;
117 unsigned char acc_mask0, acc_mask1, acc_mask2, acc_mask3;
118 CPC_MSG_T * out;
119 C0CONR_T c0con;
120 C1CONR_T c1con;
121 int tmpAccCode;
122 int tmpAccMask;
124 // we have to convert the parameters into M16C parameters
125 CPC_SJA1000_PARAMS_T * pParams;
127 // check if the type is CAN parameters and if we have to convert the given params
128 if (in->type != CPC_CMD_T_CAN_PRMS
129 || in->msg.canparams.cc_type != SJA1000)
130 return 0;
131 pParams =
132 (CPC_SJA1000_PARAMS_T *) & in->msg.canparams.cc_params.sja1000;
133 acc_code0 = pParams->acc_code0;
134 acc_code1 = pParams->acc_code1;
135 acc_code2 = pParams->acc_code2;
136 acc_code3 = pParams->acc_code3;
137 acc_mask0 = pParams->acc_mask0;
138 acc_mask1 = pParams->acc_mask1;
139 acc_mask2 = pParams->acc_mask2;
140 acc_mask3 = pParams->acc_mask3;
142 #ifdef _DEBUG_OUTPUT_CAN_PARAMS
143 info("acc_code0: %2.2Xh\n", acc_code0);
144 info("acc_code1: %2.2Xh\n", acc_code1);
145 info("acc_code2: %2.2Xh\n", acc_code2);
146 info("acc_code3: %2.2Xh\n", acc_code3);
147 info("acc_mask0: %2.2Xh\n", acc_mask0);
148 info("acc_mask1: %2.2Xh\n", acc_mask1);
149 info("acc_mask2: %2.2Xh\n", acc_mask2);
150 info("acc_mask3: %2.2Xh\n", acc_mask3);
152 #endif /* */
153 if (!
154 (baudrate_error =
155 (int *) vmalloc(sizeof(int) * 16 * 8 * 8 * 8 * 5))) {
156 err("Could not allocate memory\n");
157 return -3;
159 if (!
160 (samplepoint_error =
161 (int *) vmalloc(sizeof(int) * 16 * 8 * 8 * 8 * 5))) {
162 err("Could not allocate memory\n");
163 vfree(baudrate_error);
164 return -3;
166 memset(baudrate_error, 0xff, sizeof(baudrate_error));
167 memset(samplepoint_error, 0xff, sizeof(baudrate_error));
168 sjaBaudrate =
169 16000000 / 2 / SJA_BRP / (1 + SJA_TSEG1 + SJA_TSEG2);
170 sjaSamplepoint =
171 100 * (1 + SJA_TSEG1) / (1 + SJA_TSEG1 + SJA_TSEG2);
172 if (sjaBaudrate == 0) {
173 vfree(baudrate_error);
174 vfree(samplepoint_error);
175 return -2;
178 #ifdef _DEBUG_OUTPUT_CAN_PARAMS
179 info("\nStarting SJA CAN params\n");
180 info("-------------------------\n");
181 info("TS1 : %2.2Xh TS2 : %2.2Xh\n", SJA_TSEG1, SJA_TSEG2);
182 info("BTR0 : %2.2Xh BTR1: %2.2Xh\n", pParams->btr0,
183 pParams->btr1);
184 info("Baudrate: %d.%dkBaud\n", sjaBaudrate / 1000,
185 sjaBaudrate % 1000);
186 info("Sample P: 0.%d\n", sjaSamplepoint);
187 info("\n");
189 #endif /* */
190 c0con.bc0con.sam = SJA_SAM;
191 c1con.bc1con.sjw = SJA_SJW;
193 // calculate errors for all baudrates
194 index = 0;
195 for (clk = 0; clk < 5; clk++) {
196 for (brp = 0; brp < 16; brp++) {
197 for (pr = 0; pr < 8; pr++) {
198 for (ph1 = 0; ph1 < 8; ph1++) {
199 for (ph2 = 0; ph2 < 8; ph2++) {
200 baudrate_error[index] =
201 100 *
202 abs(baudrate_m16c
203 (clk, brp, pr, ph1,
204 ph2) -
205 sjaBaudrate) /
206 sjaBaudrate;
207 samplepoint_error[index] =
208 abs(samplepoint_m16c
209 (brp, pr, ph1,
210 ph2) -
211 sjaSamplepoint);
213 #if 0
214 info
215 ("Baudrate : %d kBaud\n",
216 baudrate_m16c(clk,
217 brp, pr,
218 ph1,
219 ph2));
220 info
221 ("Baudrate Error: %d\n",
222 baudrate_error
223 [index]);
224 info
225 ("Sample P Error: %d\n",
226 samplepoint_error
227 [index]);
228 info
229 ("clk : %d\n",
230 clk);
232 #endif /* */
233 index++;
240 // mark all baudrate_error entries which are outer limits
241 index = 0;
242 for (clk = 0; clk < 5; clk++) {
243 for (brp = 0; brp < 16; brp++) {
244 for (pr = 0; pr < 8; pr++) {
245 for (ph1 = 0; ph1 < 8; ph1++) {
246 for (ph2 = 0; ph2 < 8; ph2++) {
247 if ((baudrate_error[index]
249 BAUDRATE_TOLERANCE_PERCENT)
251 (samplepoint_error
252 [index] >
253 SAMPLEPOINT_TOLERANCE_PERCENT)
255 (samplepoint_m16c
256 (brp, pr, ph1,
257 ph2) >
258 SAMPLEPOINT_UPPER_LIMIT))
260 baudrate_error
261 [index] = -1;
262 } else
263 if (((1 + pr + 1 +
264 ph1 + 1 + ph2 +
265 1) < 8)
267 ((1 + pr + 1 +
268 ph1 + 1 + ph2 +
269 1) > 25)) {
270 baudrate_error
271 [index] = -1;
274 #if 0
275 else {
276 info
277 ("Baudrate : %d kBaud\n",
278 baudrate_m16c
279 (clk, brp, pr,
280 ph1, ph2));
281 info
282 ("Baudrate Error: %d\n",
283 baudrate_error
284 [index]);
285 info
286 ("Sample P Error: %d\n",
287 samplepoint_error
288 [index]);
291 #endif /* */
292 index++;
299 // find list of minimum of baudrate_error within unmarked entries
300 clk_merk = brp_merk = pr_merk = ph1_merk = ph2_merk = 0;
301 baudrate_error_merk = 100;
302 index = 0;
303 for (clk = 0; clk < 5; clk++) {
304 for (brp = 0; brp < 16; brp++) {
305 for (pr = 0; pr < 8; pr++) {
306 for (ph1 = 0; ph1 < 8; ph1++) {
307 for (ph2 = 0; ph2 < 8; ph2++) {
308 if (baudrate_error[index]
309 != -1) {
310 if (baudrate_error
311 [index] <
312 baudrate_error_merk)
314 baudrate_error_merk
316 baudrate_error
317 [index];
318 brp_merk =
319 brp;
320 pr_merk =
322 ph1_merk =
323 ph1;
324 ph2_merk =
325 ph2;
326 clk_merk =
327 clk;
329 #if 0
330 info
331 ("brp: %2.2Xh pr: %2.2Xh ph1: %2.2Xh ph2: %2.2Xh\n",
332 brp,
334 ph1,
335 ph2);
336 info
337 ("Baudrate : %d kBaud\n",
338 baudrate_m16c
339 (clk,
340 brp,
342 ph1,
343 ph2));
344 info
345 ("Baudrate Error: %d\n",
346 baudrate_error
347 [index]);
348 info
349 ("Sample P Error: %d\n",
350 samplepoint_error
351 [index]);
353 #endif /* */
356 index++;
362 if (baudrate_error_merk == 100) {
363 info("ERROR: Could not convert CAN init parameter\n");
364 vfree(baudrate_error);
365 vfree(samplepoint_error);
366 return -1;
369 // setting m16c CAN parameter
370 c0con.bc0con.brp = brp_merk;
371 c0con.bc0con.pr = pr_merk;
372 c1con.bc1con.ph1 = ph1_merk;
373 c1con.bc1con.ph2 = ph2_merk;
375 #ifdef _DEBUG_OUTPUT_CAN_PARAMS
376 info("\nResulting M16C CAN params\n");
377 info("-------------------------\n");
378 info("clk : %2.2Xh\n", clk_merk);
379 info("ph1 : %2.2Xh ph2: %2.2Xh\n", c1con.bc1con.ph1 + 1,
380 c1con.bc1con.ph2 + 1);
381 info("pr : %2.2Xh brp: %2.2Xh\n", c0con.bc0con.pr + 1,
382 c0con.bc0con.brp + 1);
383 info("sjw : %2.2Xh sam: %2.2Xh\n", c1con.bc1con.sjw,
384 c0con.bc0con.sam);
385 info("co1 : %2.2Xh co0: %2.2Xh\n", c1con.c1con, c0con.c0con);
386 info("Baudrate: %d.%dBaud\n",
387 baudrate_m16c(clk_merk, c0con.bc0con.brp, c0con.bc0con.pr,
388 c1con.bc1con.ph1, c1con.bc1con.ph2) / 1000,
389 baudrate_m16c(clk_merk, c0con.bc0con.brp, c0con.bc0con.pr,
390 c1con.bc1con.ph1, c1con.bc1con.ph2) % 1000);
391 info("Sample P: 0.%d\n",
392 samplepoint_m16c(c0con.bc0con.brp, c0con.bc0con.pr,
393 c1con.bc1con.ph1, c1con.bc1con.ph2));
394 info("\n");
396 #endif /* */
397 out = in;
398 out->type = 6;
399 out->length = sizeof(CPC_M16C_BASIC_PARAMS_T) + 1;
400 out->msg.canparams.cc_type = M16C_BASIC;
401 out->msg.canparams.cc_params.m16c_basic.con0 = c0con.c0con;
402 out->msg.canparams.cc_params.m16c_basic.con1 = c1con.c1con;
403 out->msg.canparams.cc_params.m16c_basic.ctlr0 = 0x4C;
404 out->msg.canparams.cc_params.m16c_basic.ctlr1 = 0x00;
405 out->msg.canparams.cc_params.m16c_basic.clk = clk_merk;
406 out->msg.canparams.cc_params.m16c_basic.acc_std_code0 =
407 acc_code0;
408 out->msg.canparams.cc_params.m16c_basic.acc_std_code1 = acc_code1;
410 // info("code0: 0x%2.2X, code1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_code0, out->msg.canparams.cc_params.m16c_basic.acc_std_code1);
411 tmpAccCode = (acc_code1 >> 5) + (acc_code0 << 3);
412 out->msg.canparams.cc_params.m16c_basic.acc_std_code0 =
413 (unsigned char) tmpAccCode;
414 out->msg.canparams.cc_params.m16c_basic.acc_std_code1 =
415 (unsigned char) (tmpAccCode >> 8);
417 // info("code0: 0x%2.2X, code1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_code0, out->msg.canparams.cc_params.m16c_basic.acc_std_code1);
418 out->msg.canparams.cc_params.m16c_basic.acc_std_mask0 =
419 ~acc_mask0;
420 out->msg.canparams.cc_params.m16c_basic.acc_std_mask1 =
421 ~acc_mask1;
423 // info("mask0: 0x%2.2X, mask1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_mask0, out->msg.canparams.cc_params.m16c_basic.acc_std_mask1);
424 tmpAccMask = ((acc_mask1) >> 5) + ((acc_mask0) << 3);
426 // info("tmpAccMask: 0x%4.4X\n", tmpAccMask);
427 out->msg.canparams.cc_params.m16c_basic.acc_std_mask0 =
428 (unsigned char) ~tmpAccMask;
429 out->msg.canparams.cc_params.m16c_basic.acc_std_mask1 =
430 (unsigned char) ~(tmpAccMask >> 8);
432 // info("mask0: 0x%2.2X, mask1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_mask0, out->msg.canparams.cc_params.m16c_basic.acc_std_mask1);
433 out->msg.canparams.cc_params.m16c_basic.acc_ext_code0 =
434 (unsigned char) tmpAccCode;
435 out->msg.canparams.cc_params.m16c_basic.acc_ext_code1 =
436 (unsigned char) (tmpAccCode >> 8);
437 out->msg.canparams.cc_params.m16c_basic.acc_ext_code2 = acc_code2;
438 out->msg.canparams.cc_params.m16c_basic.acc_ext_code3 = acc_code3;
439 out->msg.canparams.cc_params.m16c_basic.acc_ext_mask0 =
440 (unsigned char) ~tmpAccMask;
441 out->msg.canparams.cc_params.m16c_basic.acc_ext_mask1 =
442 (unsigned char) ~(tmpAccMask >> 8);
443 out->msg.canparams.cc_params.m16c_basic.acc_ext_mask2 =
444 ~acc_mask2;
445 out->msg.canparams.cc_params.m16c_basic.acc_ext_mask3 =
446 ~acc_mask3;
447 vfree(baudrate_error);
448 vfree(samplepoint_error);
449 return 0;