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