Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*********************************************************************
  2  *                
  3  * Filename:      tekram.c
  4  * Version:       1.3
  5  * Description:   Implementation of the Tekram IrMate IR-210B dongle
  6  * Status:        Experimental.
  7  * Author:        Dag Brattli <dagb@cs.uit.no>
  8  * Created at:    Wed Oct 21 20:02:35 1998
  9  * Modified at:   Sun Oct 27 22:02:38 2002
 10  * Modified by:   Martin Diehl <mad@mdiehl.de>
 11  * 
 12  *     Copyright (c) 1998-1999 Dag Brattli,
 13  *     Copyright (c) 2002 Martin Diehl,
 14  *     All Rights Reserved.
 15  *      
 16  *     This program is free software; you can redistribute it and/or 
 17  *     modify it under the terms of the GNU General Public License as 
 18  *     published by the Free Software Foundation; either version 2 of 
 19  *     the License, or (at your option) any later version.
 20  *  
 21  *     Neither Dag Brattli nor University of Tromsų admit liability nor
 22  *     provide warranty for any of this software. This material is 
 23  *     provided "AS-IS" and at no charge.
 24  *     
 25  ********************************************************************/
 26 
 27 #include <linux/module.h>
 28 #include <linux/delay.h>
 29 #include <linux/init.h>
 30 
 31 #include <net/irda/irda.h>
 32 
 33 #include "sir-dev.h"
 34 
 35 static int tekram_delay = 150;          /* default is 150 ms */
 36 module_param(tekram_delay, int, 0);
 37 MODULE_PARM_DESC(tekram_delay, "tekram dongle write complete delay");
 38 
 39 static int tekram_open(struct sir_dev *);
 40 static int tekram_close(struct sir_dev *);
 41 static int tekram_change_speed(struct sir_dev *, unsigned);
 42 static int tekram_reset(struct sir_dev *);
 43 
 44 #define TEKRAM_115200 0x00
 45 #define TEKRAM_57600  0x01
 46 #define TEKRAM_38400  0x02
 47 #define TEKRAM_19200  0x03
 48 #define TEKRAM_9600   0x04
 49 
 50 #define TEKRAM_PW     0x10 /* Pulse select bit */
 51 
 52 static struct dongle_driver tekram = {
 53         .owner          = THIS_MODULE,
 54         .driver_name    = "Tekram IR-210B",
 55         .type           = IRDA_TEKRAM_DONGLE,
 56         .open           = tekram_open,
 57         .close          = tekram_close,
 58         .reset          = tekram_reset,
 59         .set_speed      = tekram_change_speed,
 60 };
 61 
 62 static int __init tekram_sir_init(void)
 63 {
 64         if (tekram_delay < 1  ||  tekram_delay > 500)
 65                 tekram_delay = 200;
 66         IRDA_DEBUG(1, "%s - using %d ms delay\n",
 67                 tekram.driver_name, tekram_delay);
 68         return irda_register_dongle(&tekram);
 69 }
 70 
 71 static void __exit tekram_sir_cleanup(void)
 72 {
 73         irda_unregister_dongle(&tekram);
 74 }
 75 
 76 static int tekram_open(struct sir_dev *dev)
 77 {
 78         struct qos_info *qos = &dev->qos;
 79 
 80         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 81 
 82         sirdev_set_dtr_rts(dev, TRUE, TRUE);
 83 
 84         qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
 85         qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */      
 86         irda_qos_bits_to_value(qos);
 87 
 88         /* irda thread waits 50 msec for power settling */
 89 
 90         return 0;
 91 }
 92 
 93 static int tekram_close(struct sir_dev *dev)
 94 {
 95         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 96 
 97         /* Power off dongle */
 98         sirdev_set_dtr_rts(dev, FALSE, FALSE);
 99 
100         return 0;
101 }
102 
103 /*
104  * Function tekram_change_speed (dev, state, speed)
105  *
106  *    Set the speed for the Tekram IRMate 210 type dongle. Warning, this 
107  *    function must be called with a process context!
108  *
109  *    Algorithm
110  *    1. clear DTR 
111  *    2. set RTS, and wait at least 7 us
112  *    3. send Control Byte to the IR-210 through TXD to set new baud rate
113  *       wait until the stop bit of Control Byte is sent (for 9600 baud rate, 
114  *       it takes about 100 msec)
115  *
116  *      [oops, why 100 msec? sending 1 byte (10 bits) takes 1.05 msec
117  *       - is this probably to compensate for delays in tty layer?]
118  *
119  *    5. clear RTS (return to NORMAL Operation)
120  *    6. wait at least 50 us, new setting (baud rate, etc) takes effect here 
121  *       after
122  */
123 
124 #define TEKRAM_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED + 1)
125 
126 static int tekram_change_speed(struct sir_dev *dev, unsigned speed)
127 {
128         unsigned state = dev->fsm.substate;
129         unsigned delay = 0;
130         u8 byte;
131         static int ret = 0;
132         
133         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
134 
135         switch(state) {
136         case SIRDEV_STATE_DONGLE_SPEED:
137 
138                 switch (speed) {
139                 default:
140                         speed = 9600;
141                         ret = -EINVAL;
142                         /* fall thru */
143                 case 9600:
144                         byte = TEKRAM_PW|TEKRAM_9600;
145                         break;
146                 case 19200:
147                         byte = TEKRAM_PW|TEKRAM_19200;
148                         break;
149                 case 38400:
150                         byte = TEKRAM_PW|TEKRAM_38400;
151                         break;
152                 case 57600:
153                         byte = TEKRAM_PW|TEKRAM_57600;
154                         break;
155                 case 115200:
156                         byte = TEKRAM_115200;
157                         break;
158                 }
159 
160                 /* Set DTR, Clear RTS */
161                 sirdev_set_dtr_rts(dev, TRUE, FALSE);
162         
163                 /* Wait at least 7us */
164                 udelay(14);
165 
166                 /* Write control byte */
167                 sirdev_raw_write(dev, &byte, 1);
168                 
169                 dev->speed = speed;
170 
171                 state = TEKRAM_STATE_WAIT_SPEED;
172                 delay = tekram_delay;
173                 break;
174 
175         case TEKRAM_STATE_WAIT_SPEED:
176                 /* Set DTR, Set RTS */
177                 sirdev_set_dtr_rts(dev, TRUE, TRUE);
178                 udelay(50);
179                 break;
180 
181         default:
182                 ERROR("%s - undefined state %d\n", __FUNCTION__, state);
183                 ret = -EINVAL;
184                 break;
185         }
186 
187         dev->fsm.substate = state;
188         return (delay > 0) ? delay : ret;
189 }
190 
191 /*
192  * Function tekram_reset (driver)
193  *
194  *      This function resets the tekram dongle. Warning, this function 
195  *      must be called with a process context!! 
196  *
197  *      Algorithm:
198  *        0. Clear RTS and DTR, and wait 50 ms (power off the IR-210 )
199  *        1. clear RTS 
200  *        2. set DTR, and wait at least 1 ms 
201  *        3. clear DTR to SPACE state, wait at least 50 us for further 
202  *         operation
203  */
204 
205 static int tekram_reset(struct sir_dev *dev)
206 {
207         IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
208 
209         /* Clear DTR, Set RTS */
210         sirdev_set_dtr_rts(dev, FALSE, TRUE); 
211 
212         /* Should sleep 1 ms */
213         set_current_state(TASK_UNINTERRUPTIBLE);
214         schedule_timeout(msecs_to_jiffies(1));
215 
216         /* Set DTR, Set RTS */
217         sirdev_set_dtr_rts(dev, TRUE, TRUE);
218         
219         /* Wait at least 50 us */
220         udelay(75);
221 
222         dev->speed = 9600;
223 
224         return 0;
225 }
226 
227 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
228 MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver");
229 MODULE_LICENSE("GPL");
230 MODULE_ALIAS("irda-dongle-0"); /* IRDA_TEKRAM_DONGLE */
231                 
232 module_init(tekram_sir_init);
233 module_exit(tekram_sir_cleanup);
234 
  This page was automatically generated by the LXR engine.