1/********************************************************************* 2 * 3 * Filename: girbil.c 4 * Version: 1.2 5 * Description: Implementation for the Greenwich GIrBIL dongle 6 * Status: Experimental. 7 * Author: Dag Brattli <dagb@cs.uit.no> 8 * Created at: Sat Feb 6 21:02:33 1999 9 * Modified at: Fri Dec 17 09:13:20 1999 10 * Modified by: Dag Brattli <dagb@cs.uit.no> 11 * 12 * Copyright (c) 1999 Dag Brattli, All Rights Reserved. 13 * 14 * This program is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU General Public License as 16 * published by the Free Software Foundation; either version 2 of 17 * the License, or (at your option) any later version. 18 * 19 * Neither Dag Brattli nor University of Troms� admit liability nor 20 * provide warranty for any of this software. This material is 21 * provided "AS-IS" and at no charge. 22 * 23 ********************************************************************/ 24 25#include <linux/module.h> 26#include <linux/delay.h> 27#include <linux/init.h> 28 29#include <net/irda/irda.h> 30 31#include "sir-dev.h" 32 33static int girbil_reset(struct sir_dev *dev); 34static int girbil_open(struct sir_dev *dev); 35static int girbil_close(struct sir_dev *dev); 36static int girbil_change_speed(struct sir_dev *dev, unsigned speed); 37 38/* Control register 1 */ 39#define GIRBIL_TXEN 0x01 /* Enable transmitter */ 40#define GIRBIL_RXEN 0x02 /* Enable receiver */ 41#define GIRBIL_ECAN 0x04 /* Cancel self emmited data */ 42#define GIRBIL_ECHO 0x08 /* Echo control characters */ 43 44/* LED Current Register (0x2) */ 45#define GIRBIL_HIGH 0x20 46#define GIRBIL_MEDIUM 0x21 47#define GIRBIL_LOW 0x22 48 49/* Baud register (0x3) */ 50#define GIRBIL_2400 0x30 51#define GIRBIL_4800 0x31 52#define GIRBIL_9600 0x32 53#define GIRBIL_19200 0x33 54#define GIRBIL_38400 0x34 55#define GIRBIL_57600 0x35 56#define GIRBIL_115200 0x36 57 58/* Mode register (0x4) */ 59#define GIRBIL_IRDA 0x40 60#define GIRBIL_ASK 0x41 61 62/* Control register 2 (0x5) */ 63#define GIRBIL_LOAD 0x51 /* Load the new baud rate value */ 64 65static struct dongle_driver girbil = { 66 .owner = THIS_MODULE, 67 .driver_name = "Greenwich GIrBIL", 68 .type = IRDA_GIRBIL_DONGLE, 69 .open = girbil_open, 70 .close = girbil_close, 71 .reset = girbil_reset, 72 .set_speed = girbil_change_speed, 73}; 74 75static int __init girbil_sir_init(void) 76{ 77 return irda_register_dongle(&girbil); 78} 79 80static void __exit girbil_sir_cleanup(void) 81{ 82 irda_unregister_dongle(&girbil); 83} 84 85static int girbil_open(struct sir_dev *dev) 86{ 87 struct qos_info *qos = &dev->qos; 88 89 IRDA_DEBUG(2, "%s()\n", __FUNCTION__); 90 91 /* Power on dongle */ 92 sirdev_set_dtr_rts(dev, TRUE, TRUE); 93 94 qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; 95 qos->min_turn_time.bits = 0x03; 96 irda_qos_bits_to_value(qos); 97 98 /* irda thread waits 50 msec for power settling */ 99 100 return 0; 101} 102 103static int girbil_close(struct sir_dev *dev) 104{ 105 IRDA_DEBUG(2, "%s()\n", __FUNCTION__); 106 107 /* Power off dongle */ 108 sirdev_set_dtr_rts(dev, FALSE, FALSE); 109 110 return 0; 111} 112 113/* 114 * Function girbil_change_speed (dev, speed) 115 * 116 * Set the speed for the Girbil type dongle. 117 * 118 */ 119 120#define GIRBIL_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED + 1) 121 122static int girbil_change_speed(struct sir_dev *dev, unsigned speed) 123{ 124 unsigned state = dev->fsm.substate; 125 unsigned delay = 0; 126 u8 control[2]; 127 static int ret = 0; 128 129 IRDA_DEBUG(2, "%s()\n", __FUNCTION__); 130 131 /* dongle alread reset - port and dongle at default speed */ 132 133 switch(state) { 134 135 case SIRDEV_STATE_DONGLE_SPEED: 136 137 /* Set DTR and Clear RTS to enter command mode */ 138 sirdev_set_dtr_rts(dev, FALSE, TRUE); 139 140 udelay(25); /* better wait a little while */ 141 142 ret = 0; 143 switch (speed) { 144 default: 145 ret = -EINVAL; 146 /* fall through */ 147 case 9600: 148 control[0] = GIRBIL_9600; 149 break; 150 case 19200: 151 control[0] = GIRBIL_19200; 152 break; 153 case 34800: 154 control[0] = GIRBIL_38400; 155 break; 156 case 57600: 157 control[0] = GIRBIL_57600; 158 break; 159 case 115200: 160 control[0] = GIRBIL_115200; 161 break; 162 } 163 control[1] = GIRBIL_LOAD; 164 165 /* Write control bytes */ 166 sirdev_raw_write(dev, control, 2); 167 168 dev->speed = speed; 169 170 state = GIRBIL_STATE_WAIT_SPEED; 171 delay = 100; 172 break; 173 174 case GIRBIL_STATE_WAIT_SPEED: 175 /* Go back to normal mode */ 176 sirdev_set_dtr_rts(dev, TRUE, TRUE); 177 178 udelay(25); /* better wait a little while */ 179 break; 180 181 default: 182 IRDA_ERROR("%s - undefined state %d\n", __FUNCTION__, state); 183 ret = -EINVAL; 184 break; 185 } 186 dev->fsm.substate = state; 187 return (delay > 0) ? delay : ret; 188} 189 190/* 191 * Function girbil_reset (driver) 192 * 193 * This function resets the girbil dongle. 194 * 195 * Algorithm: 196 * 0. set RTS, and wait at least 5 ms 197 * 1. clear RTS 198 */ 199 200 201#define GIRBIL_STATE_WAIT1_RESET (SIRDEV_STATE_DONGLE_RESET + 1) 202#define GIRBIL_STATE_WAIT2_RESET (SIRDEV_STATE_DONGLE_RESET + 2) 203#define GIRBIL_STATE_WAIT3_RESET (SIRDEV_STATE_DONGLE_RESET + 3) 204 205static int girbil_reset(struct sir_dev *dev) 206{ 207 unsigned state = dev->fsm.substate; 208 unsigned delay = 0; 209 u8 control = GIRBIL_TXEN | GIRBIL_RXEN; 210 int ret = 0; 211 212 IRDA_DEBUG(2, "%s()\n", __FUNCTION__); 213 214 switch (state) { 215 case SIRDEV_STATE_DONGLE_RESET: 216 /* Reset dongle */ 217 sirdev_set_dtr_rts(dev, TRUE, FALSE); 218 /* Sleep at least 5 ms */ 219 delay = 20; 220 state = GIRBIL_STATE_WAIT1_RESET; 221 break; 222 223 case GIRBIL_STATE_WAIT1_RESET: 224 /* Set DTR and clear RTS to enter command mode */ 225 sirdev_set_dtr_rts(dev, FALSE, TRUE); 226 delay = 20; 227 state = GIRBIL_STATE_WAIT2_RESET; 228 break; 229 230 case GIRBIL_STATE_WAIT2_RESET: 231 /* Write control byte */ 232 sirdev_raw_write(dev, &control, 1); 233 delay = 20; 234 state = GIRBIL_STATE_WAIT3_RESET; 235 break; 236 237 case GIRBIL_STATE_WAIT3_RESET: 238 /* Go back to normal mode */ 239 sirdev_set_dtr_rts(dev, TRUE, TRUE); 240 dev->speed = 9600; 241 break; 242 243 default: 244 IRDA_ERROR("%s(), undefined state %d\n", __FUNCTION__, state); 245 ret = -1; 246 break; 247 } 248 dev->fsm.substate = state; 249 return (delay > 0) ? delay : ret; 250} 251 252MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); 253MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver"); 254MODULE_LICENSE("GPL"); 255MODULE_ALIAS("irda-dongle-4"); /* IRDA_GIRBIL_DONGLE */ 256 257module_init(girbil_sir_init); 258module_exit(girbil_sir_cleanup); 259