a64aeb3c4917a2bde70720a7d4f5afbb067b0a82
[lincan.git] / lincan / src / unican.c
1 /* unican.c
2  * Linux CAN-bus device driver.
3  * Written for new CAN driver version by Pavel Pisa - OCERA team member
4  * email:pisa@cmp.felk.cvut.cz
5  * This software is released under the GPL-License.
6  * Version lincan-0.2  9 Jul 2003
7  */ 
8
9 #include "../include/can.h"
10 #include "../include/can_sysdep.h"
11 #include "../include/main.h"
12 #include "../include/unican_cl2.h"
13
14
15 long unican_bus_latency(struct msgobj_t *obj)
16 {
17         long latency;
18         latency=obj->hostchip->baudrate;
19         if(latency){
20                 latency=(long)HZ*1000/latency;
21         }
22         return latency;
23 }
24
25
26 /* * * unican Chip Functionality * * */
27
28 int unican_enable_configuration(struct chip_t *chip)
29 {
30         return 0;
31 }
32
33 int unican_disable_configuration(struct chip_t *chip)
34 {
35         return 0;
36 }
37
38 /**
39  * unican_chip_config: - can chip configuration
40  * @chip: pointer to chip state structure
41  *
42  * Return Value: negative value reports error.
43  * File: src/unican.c
44  */
45 int unican_chip_config(struct chip_t *chip)
46 {
47         return 0;
48 }
49
50 /**
51  * unican_extended_mask: - setup of extended mask for message filtering
52  * @chip: pointer to chip state structure
53  * @code: can message acceptance code
54  * @mask: can message acceptance mask
55  *
56  * Return Value: negative value reports error.
57  * File: src/unican.c
58  */
59 int unican_extended_mask(struct chip_t *chip, unsigned long code, unsigned  long mask)
60 {
61         return 0;
62 }
63
64 /**
65  * unican_baud_rate: - set communication parameters.
66  * @chip: pointer to chip state structure
67  * @rate: baud rate in Hz
68  * @clock: frequency of sja1000 clock in Hz (ISA osc is 14318000)
69  * @sjw: synchronization jump width (0-3) prescaled clock cycles
70  * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
71  * @flags: fields %BTR1_SAM, %OCMODE, %OCPOL, %OCTP, %OCTN, %CLK_OFF, %CBP
72  *
73  * Return Value: negative value reports error.
74  * File: src/unican.c
75  */
76 int unican_baud_rate(struct chip_t *chip, int rate, int clock, int sjw,
77                                                         int sampl_pt, int flags)
78 {
79         return 0;
80 }
81
82 /**
83  * unican_read: - reads and distributes one or more received messages
84  * @chip: pointer to chip state structure
85  * @obj: pinter to CAN message queue information
86  *
87  * File: src/unican.c
88  */
89 void unican_read(struct chip_t *chip, struct msgobj_t *obj) {
90
91 }
92
93 /**
94  * unican_pre_read_config: - prepares message object for message reception
95  * @chip: pointer to chip state structure
96  * @obj: pointer to message object state structure
97  *
98  * Return Value: negative value reports error.
99  *      Positive value indicates immediate reception of message.
100  * File: src/unican.c
101  */
102 int unican_pre_read_config(struct chip_t *chip, struct msgobj_t *obj)
103 {
104         return 0;
105 }
106
107 #define MAX_TRANSMIT_WAIT_LOOPS 10
108 /**
109  * unican_pre_write_config: - prepares message object for message transmission
110  * @chip: pointer to chip state structure
111  * @obj: pointer to message object state structure
112  * @msg: pointer to CAN message
113  *
114  * Return Value: negative value reports error.
115  * File: src/unican.c
116  */
117 int unican_pre_write_config(struct chip_t *chip, struct msgobj_t *obj, 
118                                                         struct canmsg_t *msg)
119 {
120         return 0;
121 }
122
123 /**
124  * unican_send_msg: - initiate message transmission
125  * @chip: pointer to chip state structure
126  * @obj: pointer to message object state structure
127  * @msg: pointer to CAN message
128  *
129  * This function is called after unican_pre_write_config() function,
130  * which prepares data in chip buffer.
131  * Return Value: negative value reports error.
132  * File: src/unican.c
133  */
134 int unican_send_msg(struct chip_t *chip, struct msgobj_t *obj, 
135                                                         struct canmsg_t *msg)
136 {
137         return 0;
138 }
139
140 /**
141  * unican_check_tx_stat: - checks state of transmission engine
142  * @chip: pointer to chip state structure
143  *
144  * Return Value: negative value reports error.
145  *      Positive return value indicates transmission under way status.
146  *      Zero value indicates finishing of all issued transmission requests.
147  * File: src/unican.c
148  */
149 int unican_check_tx_stat(struct chip_t *chip)
150 {
151         return 0;
152 }
153
154 /**
155  * unican_set_btregs: -  configures bitrate registers
156  * @chip: pointer to chip state structure
157  * @btr0: bitrate register 0
158  * @btr1: bitrate register 1
159  *
160  * Return Value: negative value reports error.
161  * File: src/unican.c
162  */
163 int unican_set_btregs(struct chip_t *chip, unsigned short btr0, 
164                                                         unsigned short btr1)
165 {
166         return 0;
167 }
168
169 /**
170  * unican_stop_chip: -  starts chip message processing
171  * @chip: pointer to chip state structure
172  *
173  * Return Value: negative value reports error.
174  * File: src/unican.c
175  */
176 int unican_start_chip(struct chip_t *chip)
177 {
178         return 0;
179 }
180
181 /**
182  * unican_stop_chip: -  stops chip message processing
183  * @chip: pointer to chip state structure
184  *
185  * Return Value: negative value reports error.
186  * File: src/unican.c
187  */
188 int unican_stop_chip(struct chip_t *chip)
189 {
190         return 0;
191 }
192
193
194 /**
195  * unican_remote_request: - configures message object and asks for RTR message
196  * @chip: pointer to chip state structure
197  * @obj: pointer to message object structure
198  *
199  * Return Value: negative value reports error.
200  * File: src/unican.c
201  */
202 int unican_remote_request(struct chip_t *chip, struct msgobj_t *obj)
203 {
204         CANMSG("unican_remote_request not implemented\n");
205         return -ENOSYS;
206 }
207
208 /**
209  * unican_standard_mask: - setup of mask for message filtering
210  * @chip: pointer to chip state structure
211  * @code: can message acceptance code
212  * @mask: can message acceptance mask
213  *
214  * Return Value: negative value reports error.
215  * File: src/unican.c
216  */
217 int unican_standard_mask(struct chip_t *chip, unsigned short code,
218                 unsigned short mask)
219 {
220         CANMSG("unican_standard_mask not implemented\n");
221         return -ENOSYS;
222 }
223
224 /**
225  * unican_clear_objects: - clears state of all message object residing in chip
226  * @chip: pointer to chip state structure
227  *
228  * Return Value: negative value reports error.
229  * File: src/unican.c
230  */
231 int unican_clear_objects(struct chip_t *chip)
232 {
233         CANMSG("unican_clear_objects not implemented\n");
234         return -ENOSYS;
235 }
236
237 /**
238  * unican_config_irqs: - tunes chip hardware interrupt delivery
239  * @chip: pointer to chip state structure
240  * @irqs: requested chip IRQ configuration
241  *
242  * Return Value: negative value reports error.
243  * File: src/unican.c
244  */
245 int unican_config_irqs(struct chip_t *chip, short irqs)
246 {
247         CANMSG("unican_config_irqs not implemented\n");
248         return -ENOSYS;
249 }
250
251 /**
252  * unican_irq_write_handler: - part of ISR code responsible for transmit events
253  * @chip: pointer to chip state structure
254  * @obj: pointer to attached queue description
255  *
256  * The main purpose of this function is to read message from attached queues
257  * and transfer message contents into CAN controller chip.
258  * This subroutine is called by
259  * unican_irq_write_handler() for transmit events.
260  * File: src/unican.c
261  */
262 void unican_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj)
263 {
264
265 }
266
267 #define MAX_RETR 10
268
269 /**
270  * unican_irq_handler: - interrupt service routine
271  * @irq: interrupt vector number, this value is system specific
272  * @dev_id: driver private pointer registered at time of request_irq() call.
273  *      The CAN driver uses this pointer to store relationship of interrupt
274  *      to chip state structure - @struct chip_t
275  * @regs: system dependent value pointing to registers stored in exception frame
276  * 
277  * Interrupt handler is activated when state of CAN controller chip changes,
278  * there is message to be read or there is more space for new messages or
279  * error occurs. The receive events results in reading of the message from
280  * CAN controller chip and distribution of message through attached
281  * message queues.
282  * File: src/unican.c
283  */
284 can_irqreturn_t unican_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
285 {
286         return CAN_IRQ_HANDLED;
287 }
288
289
290 void unican_schedule_next(struct msgobj_t *obj)
291 {
292         int cmd;
293
294         can_preempt_disable();
295
296         can_msgobj_set_fl(obj,TX_REQUEST);
297         
298         while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
299
300                 can_msgobj_clear_fl(obj,TX_REQUEST);
301                 
302                 cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
303                 if(cmd>=0) {
304                         mod_timer(&obj->tx_timeout,
305                                 jiffies+unican_bus_latency(obj));
306                         DEBUGMSG("unican: scheduled delivery\n");
307
308                 } else          
309                         can_msgobj_clear_fl(obj,TX_LOCK);
310                 
311                 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
312                 DEBUGMSG("TX looping in unican_schedule_next\n");
313         }
314
315         can_preempt_enable();
316 }
317
318
319 void unican_do_tx_timeout(unsigned long data)
320 {
321         struct msgobj_t *obj=(struct msgobj_t *)data;
322         
323         if(obj->tx_slot) {
324                 /* Deliver message to edges */
325                 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
326                 /* Free transmitted slot */
327                 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
328                 obj->tx_slot=NULL;
329                 DEBUGMSG("unican: delayed delivery\n");
330         }
331         can_msgobj_clear_fl(obj,TX_LOCK);
332
333         unican_schedule_next(obj);
334 }
335
336 /**
337  * unican_wakeup_tx: - wakeups TX processing
338  * @chip: pointer to chip state structure
339  * @obj: pointer to message object structure
340  *
341  * Return Value: negative value reports error.
342  * File: src/unican.c
343  */
344 int unican_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj)
345 {
346         /* can_msgobj_set_fl(obj,TX_REQUEST); */
347         
348         struct canque_edge_t *qedge;
349         struct canque_slot_t *slot;
350         int cmd;
351
352         can_msgobj_clear_fl(obj,TX_REQUEST);
353
354     #ifndef CAN_WITH_RTL
355         if(!unican_bus_latency(obj)) {
356     #endif /*CAN_WITH_RTL*/
357                 /* Ensure delivery of all ready slots */
358                 while((cmd=canque_test_outslot(obj->qends, &qedge, &slot)) >= 0){
359                         if(cmd==0) {
360                                 canque_filter_msg2edges(obj->qends, &slot->msg);
361                                 DEBUGMSG("unican: direct delivery\n");
362                         }
363                         canque_free_outslot(obj->qends, qedge, slot);
364                 }
365     #ifndef CAN_WITH_RTL
366         } else {
367                 unican_schedule_next(obj);
368         }
369     #endif /*CAN_WITH_RTL*/
370
371         return 0;
372 }
373
374
375 /* * * unican Board Functionality * * */
376
377 /**
378  * unican_request_io: - reserve io or memory range for can board
379  * @candev: pointer to candevice/board which asks for io. Field @io_addr
380  *      of @candev is used in most cases to define start of the range
381  *
382  * Return Value: The function returns zero on success or %-ENODEV on failure
383  * File: src/unican.c
384  */
385 int unican_request_io(struct candevice_t *candev)
386 {
387         return 0;
388 }
389
390 /**
391  * unican_elease_io - free reserved io memory range
392  * @candev: pointer to candevice/board which releases io
393  *
394  * Return Value: The function always returns zero
395  * File: src/unican.c
396  */
397 int unican_release_io(struct candevice_t *candev)
398 {
399         return 0;
400 }
401
402 /**
403  * unican_reset - hardware reset routine
404  * @candev: Pointer to candevice/board structure
405  *
406  * Return Value: The function returns zero on success or %-ENODEV on failure
407  * File: src/unican.c
408  */
409 int unican_reset(struct candevice_t *candev)
410 {
411         return 0;
412 }
413
414 /**
415  * unican_init_hw_data - Initialize hardware cards
416  * @candev: Pointer to candevice/board structure
417  *
418  * Return Value: The function always returns zero
419  * File: src/unican.c
420  */
421 int unican_init_hw_data(struct candevice_t *candev) 
422 {
423         candev->res_addr=0;
424         candev->nr_82527_chips=0;
425         candev->nr_sja1000_chips=0;
426         candev->nr_all_chips=1;
427         candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
428
429         return 0;
430 }
431
432 #define CHIP_TYPE "unican"
433
434 /**
435  * unican_init_chip_data - Initialize chips
436  * @candev: Pointer to candevice/board structure
437  * @chipnr: Number of the CAN chip on the hardware card
438  *
439  * Return Value: The function always returns zero
440  * File: src/unican.c
441  */
442 int unican_init_chip_data(struct candevice_t *candev, int chipnr)
443 {
444         struct chip_t *chip = candev->chip[chipnr];
445         chip->chip_type = CHIP_TYPE;
446         chip->chip_base_addr = 0;
447         chip->clock = 10000000;
448         chip->int_clk_reg = 0x0;
449         chip->int_bus_reg = 0x0;
450         chip->max_objects = 1;
451
452         CANMSG("initializing unican chip operations\n");
453         chip->chipspecops->chip_config=unican_chip_config;
454         chip->chipspecops->baud_rate=unican_baud_rate;
455         chip->chipspecops->standard_mask=unican_standard_mask;
456         chip->chipspecops->extended_mask=unican_extended_mask;
457         chip->chipspecops->message15_mask=unican_extended_mask;
458         chip->chipspecops->clear_objects=unican_clear_objects;
459         chip->chipspecops->config_irqs=unican_config_irqs;
460         chip->chipspecops->pre_read_config=unican_pre_read_config;
461         chip->chipspecops->pre_write_config=unican_pre_write_config;
462         chip->chipspecops->send_msg=unican_send_msg;
463         chip->chipspecops->check_tx_stat=unican_check_tx_stat;
464         chip->chipspecops->wakeup_tx=unican_wakeup_tx;
465         chip->chipspecops->remote_request=unican_remote_request;
466         chip->chipspecops->enable_configuration=unican_enable_configuration;
467         chip->chipspecops->disable_configuration=unican_disable_configuration;
468         chip->chipspecops->set_btregs=unican_set_btregs;
469         chip->chipspecops->start_chip=unican_start_chip;
470         chip->chipspecops->stop_chip=unican_stop_chip;
471         chip->chipspecops->irq_handler=NULL;
472
473         return 0;
474 }
475
476 /**
477  * unican_init_obj_data - Initialize message buffers
478  * @chip: Pointer to chip specific structure
479  * @objnr: Number of the message buffer
480  *
481  * Return Value: The function always returns zero
482  * File: src/unican.c
483  */
484 int unican_init_obj_data(struct chip_t *chip, int objnr)
485 {
486         struct msgobj_t *obj=chip->msgobj[objnr];
487         obj->obj_base_addr=chip->chip_base_addr;
488         obj->tx_timeout.function=unican_do_tx_timeout;
489         obj->tx_timeout.data=(unsigned long)obj;
490         return 0;
491 }
492
493 /**
494  * unican_program_irq - program interrupts
495  * @candev: Pointer to candevice/board structure
496  *
497  * Return value: The function returns zero on success or %-ENODEV on failure
498  * File: src/unican.c
499  */
500 int unican_program_irq(struct candevice_t *candev)
501 {
502         return 0;
503 }
504
505 int unican_register(struct hwspecops_t *hwspecops)
506 {
507         hwspecops->request_io = unican_request_io;
508         hwspecops->release_io = unican_release_io;
509         hwspecops->reset = unican_reset;
510         hwspecops->init_hw_data = unican_init_hw_data;
511         hwspecops->init_chip_data = unican_init_chip_data;
512         hwspecops->init_obj_data = unican_init_obj_data;
513         hwspecops->write_register = NULL;
514         hwspecops->read_register = NULL;
515         hwspecops->program_irq = unican_program_irq;
516         return 0;
517 }