10ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden/********************************************************************* 20ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 30ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Filename: toim3232-sir.c 40ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Version: 1.0 50ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Description: Implementation of dongles based on the Vishay/Temic 60ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * TOIM3232 SIR Endec chipset. Currently only the 70ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * IRWave IR320ST-2 is tested, although it should work 80ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * with any TOIM3232 or TOIM4232 chipset based RS232 90ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * dongle with minimal modification. 100ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Based heavily on the Tekram driver (tekram.c), 110ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * with thanks to Dag Brattli and Martin Diehl. 120ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Status: Experimental. 130ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Author: David Basden <davidb-irda@rcpt.to> 140ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Created at: Thu Feb 09 23:47:32 2006 150ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 160ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Copyright (c) 2006 David Basden. 170ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Copyright (c) 1998-1999 Dag Brattli, 180ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Copyright (c) 2002 Martin Diehl, 190ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * All Rights Reserved. 200ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 210ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * This program is free software; you can redistribute it and/or 220ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * modify it under the terms of the GNU General Public License as 230ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * published by the Free Software Foundation; either version 2 of 240ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * the License, or (at your option) any later version. 250ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 260ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Neither Dag Brattli nor University of Tromsø admit liability nor 270ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * provide warranty for any of this software. This material is 280ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * provided "AS-IS" and at no charge. 290ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 300ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden ********************************************************************/ 310ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 320ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden/* 330ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * This driver has currently only been tested on the IRWave IR320ST-2 340ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 350ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * PROTOCOL: 360ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 370ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * The protocol for talking to the TOIM3232 is quite easy, and is 380ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * designed to interface with RS232 with only level convertors. The 390ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * BR/~D line on the chip is brought high to signal 'command mode', 400ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * where a command byte is sent to select the baudrate of the RS232 410ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * interface and the pulse length of the IRDA output. When BR/~D 420ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * is brought low, the dongle then changes to the selected baudrate, 430ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * and the RS232 interface is used for data until BR/~D is brought 440ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * high again. The initial speed for the TOIMx323 after RESET is 450ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 9600 baud. The baudrate for command-mode is the last selected 460ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * baud-rate, or 9600 after a RESET. 470ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 480ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * The dongle I have (below) adds some extra hardware on the front end, 490ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * but this is mostly directed towards pariasitic power from the RS232 500ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * line rather than changing very much about how to communicate with 510ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * the TOIM3232. 520ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 530ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * The protocol to talk to the TOIM4232 chipset seems to be almost 540ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * identical to the TOIM3232 (and the 4232 datasheet is more detailed) 550ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * so this code will probably work on that as well, although I haven't 560ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * tested it on that hardware. 570ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 580ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Target dongle variations that might be common: 590ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 600ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * DTR and RTS function: 610ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * The data sheet for the 4232 has a sample implementation that hooks the 620ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * DTR and RTS lines to the RESET and BaudRate/~Data lines of the 630ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * chip (through line-converters). Given both DTR and RTS would have to 640ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * be held low in normal operation, and the TOIMx232 requires +5V to 650ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * signal ground, most dongle designers would almost certainly choose 660ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * an implementation that kept at least one of DTR or RTS high in 670ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * normal operation to provide power to the dongle, but will likely 680ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * vary between designs. 690ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 700ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * User specified command bits: 710ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * There are two user-controllable output lines from the TOIMx232 that 720ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * can be set low or high by setting the appropriate bits in the 730ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * high-nibble of the command byte (when setting speed and pulse length). 740ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * These might be used to switch on and off added hardware or extra 750ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * dongle features. 760ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 770ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 780ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Target hardware: IRWave IR320ST-2 790ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 800ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * The IRWave IR320ST-2 is a simple dongle based on the Vishay/Temic 817c9d440e90c09c6c7b5c477217e491484d044353Joe Perches * TOIM3232 SIR Endec and the Vishay/Temic TFDS4500 SIR IRDA transceiver. 820ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * It uses a hex inverter and some discrete components to buffer and 830ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * line convert the RS232 down to 5V. 840ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 850ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * The dongle is powered through a voltage regulator, fed by a large 860ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * capacitor. To switch the dongle on, DTR is brought high to charge 870ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * the capacitor and drive the voltage regulator. DTR isn't associated 880ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * with any control lines on the TOIM3232. Parisitic power is also taken 890ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * from the RTS, TD and RD lines when brought high, but through resistors. 900ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * When DTR is low, the circuit might lose power even with RTS high. 910ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 920ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * RTS is inverted and attached to the BR/~D input pin. When RTS 930ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * is high, BR/~D is low, and the TOIM3232 is in the normal 'data' mode. 940ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * RTS is brought low, BR/~D is high, and the TOIM3232 is in 'command 950ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * mode'. 960ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 970ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * For some unknown reason, the RESET line isn't actually connected 980ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * to anything. This means to reset the dongle to get it to a known 990ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * state (9600 baud) you must drop DTR and RTS low, wait for the power 1000ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * capacitor to discharge, and then bring DTR (and RTS for data mode) 1010ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * high again, and wait for the capacitor to charge, the power supply 1020ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * to stabilise, and the oscillator clock to stabilise. 1030ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 1040ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Fortunately, if the current baudrate is known, the chipset can 1050ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * easily change speed by entering command mode without having to 1060ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * reset the dongle first. 1070ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 1080ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Major Components: 1090ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 1100ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * - Vishay/Temic TOIM3232 SIR Endec to change RS232 pulse timings 1110ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * to IRDA pulse timings 1120ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * - 3.6864MHz crystal to drive TOIM3232 clock oscillator 1130ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * - DM74lS04M Inverting Hex line buffer for RS232 input buffering 1140ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * and level conversion 1150ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * - PJ2951AC 150mA voltage regulator 1160ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * - Vishay/Temic TFDS4500 SIR IRDA front-end transceiver 1170ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 1180ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden */ 1190ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1200ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#include <linux/module.h> 1210ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#include <linux/delay.h> 1220ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#include <linux/init.h> 123d43c36dc6b357fa1806800f18aa30123c747a6d1Alexey Dobriyan#include <linux/sched.h> 1240ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1250ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#include <net/irda/irda.h> 1260ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1270ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#include "sir-dev.h" 1280ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1290ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232delay = 150; /* default is 150 ms */ 13073a6c6306876c83ed992f1b15069a0ee9b3fa73bAndrew Mortonmodule_param(toim3232delay, int, 0); 13173a6c6306876c83ed992f1b15069a0ee9b3fa73bAndrew MortonMODULE_PARM_DESC(toim3232delay, "toim3232 dongle write complete delay"); 1320ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1330ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#if 0 1340ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232flipdtr = 0; /* default is DTR high to reset */ 13573a6c6306876c83ed992f1b15069a0ee9b3fa73bAndrew Mortonmodule_param(toim3232flipdtr, int, 0); 13673a6c6306876c83ed992f1b15069a0ee9b3fa73bAndrew MortonMODULE_PARM_DESC(toim3232flipdtr, "toim3232 dongle invert DTR (Reset)"); 1370ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1380ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232fliprts = 0; /* default is RTS high for baud change */ 13973a6c6306876c83ed992f1b15069a0ee9b3fa73bAndrew Mortonmodule_param(toim3232fliptrs, int, 0); 14073a6c6306876c83ed992f1b15069a0ee9b3fa73bAndrew MortonMODULE_PARM_DESC(toim3232fliprts, "toim3232 dongle invert RTS (BR/D)"); 1410ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#endif 1420ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1430ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232_open(struct sir_dev *); 1440ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232_close(struct sir_dev *); 1450ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232_change_speed(struct sir_dev *, unsigned); 1460ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232_reset(struct sir_dev *); 1470ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1480ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#define TOIM3232_115200 0x00 1490ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#define TOIM3232_57600 0x01 1500ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#define TOIM3232_38400 0x02 1510ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#define TOIM3232_19200 0x03 1520ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#define TOIM3232_9600 0x06 1530ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#define TOIM3232_2400 0x0A 1540ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1550ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#define TOIM3232_PW 0x10 /* Pulse select bit */ 1560ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1570ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic struct dongle_driver toim3232 = { 1580ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden .owner = THIS_MODULE, 1590ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden .driver_name = "Vishay TOIM3232", 1600ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden .type = IRDA_TOIM3232_DONGLE, 1610ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden .open = toim3232_open, 1620ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden .close = toim3232_close, 1630ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden .reset = toim3232_reset, 1640ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden .set_speed = toim3232_change_speed, 1650ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden}; 1660ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1670ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int __init toim3232_sir_init(void) 1680ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden{ 1690ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden if (toim3232delay < 1 || toim3232delay > 500) 1700ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden toim3232delay = 200; 1710ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden IRDA_DEBUG(1, "%s - using %d ms delay\n", 1720ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden toim3232.driver_name, toim3232delay); 1730ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden return irda_register_dongle(&toim3232); 1740ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden} 1750ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1760ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic void __exit toim3232_sir_cleanup(void) 1770ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden{ 1780ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden irda_unregister_dongle(&toim3232); 1790ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden} 1800ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1810ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232_open(struct sir_dev *dev) 1820ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden{ 1830ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden struct qos_info *qos = &dev->qos; 1840ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 185a97a6f10771b90235b33c13a6db9279237a08422Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 1860ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1870ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Pull the lines high to start with. 1880ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 1890ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * For the IR320ST-2, we need to charge the main supply capacitor to 1900ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * switch the device on. We keep DTR high throughout to do this. 1910ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * When RTS, TD and RD are high, they will also trickle-charge the 1920ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * cap. RTS is high for data transmission, and low for baud rate select. 1930ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * -- DGB 1940ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden */ 1950ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden sirdev_set_dtr_rts(dev, TRUE, TRUE); 1960ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 1970ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* The TOI3232 supports many speeds between 1200bps and 115000bps. 1980ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * We really only care about those supported by the IRDA spec, but 1990ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 38400 seems to be implemented in many places */ 2000ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden qos->baud_rate.bits &= IR_2400|IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; 2010ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2020ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* From the tekram driver. Not sure what a reasonable value is -- DGB */ 2030ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */ 2040ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden irda_qos_bits_to_value(qos); 2050ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2060ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* irda thread waits 50 msec for power settling */ 2070ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2080ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden return 0; 2090ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden} 2100ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2110ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232_close(struct sir_dev *dev) 2120ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden{ 213a97a6f10771b90235b33c13a6db9279237a08422Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 2140ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2150ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Power off dongle */ 2160ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden sirdev_set_dtr_rts(dev, FALSE, FALSE); 2170ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2180ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden return 0; 2190ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden} 2200ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2210ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden/* 2220ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Function toim3232change_speed (dev, state, speed) 2230ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 2240ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Set the speed for the TOIM3232 based dongle. Warning, this 2250ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * function must be called with a process context! 2260ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 2270ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Algorithm 2280ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 1. keep DTR high but clear RTS to bring into baud programming mode 2290ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 2. wait at least 7us to enter programming mode 2300ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 3. send control word to set baud rate and timing 2310ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 4. wait at least 1us 2320ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 5. bring RTS high to enter DATA mode (RS232 is passed through to transceiver) 2330ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 6. should take effect immediately (although probably worth waiting) 2340ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden */ 2350ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2360ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden#define TOIM3232_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED + 1) 2370ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2380ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232_change_speed(struct sir_dev *dev, unsigned speed) 2390ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden{ 2400ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden unsigned state = dev->fsm.substate; 2410ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden unsigned delay = 0; 2420ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden u8 byte; 2430ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden static int ret = 0; 2440ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 245a97a6f10771b90235b33c13a6db9279237a08422Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 2460ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2470ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden switch(state) { 2480ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden case SIRDEV_STATE_DONGLE_SPEED: 2490ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2500ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Figure out what we are going to send as a control byte */ 2510ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden switch (speed) { 2520ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden case 2400: 2530ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden byte = TOIM3232_PW|TOIM3232_2400; 2540ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden break; 2550ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden default: 2560ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden speed = 9600; 2570ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden ret = -EINVAL; 2580ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* fall thru */ 2590ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden case 9600: 2600ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden byte = TOIM3232_PW|TOIM3232_9600; 2610ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden break; 2620ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden case 19200: 2630ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden byte = TOIM3232_PW|TOIM3232_19200; 2640ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden break; 2650ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden case 38400: 2660ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden byte = TOIM3232_PW|TOIM3232_38400; 2670ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden break; 2680ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden case 57600: 2690ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden byte = TOIM3232_PW|TOIM3232_57600; 2700ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden break; 2710ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden case 115200: 2720ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden byte = TOIM3232_115200; 2730ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden break; 2740ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden } 2750ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2760ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Set DTR, Clear RTS: Go into baud programming mode */ 2770ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden sirdev_set_dtr_rts(dev, TRUE, FALSE); 2780ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2790ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Wait at least 7us */ 2800ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden udelay(14); 2810ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2820ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Write control byte */ 2830ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden sirdev_raw_write(dev, &byte, 1); 2840ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2850ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden dev->speed = speed; 2860ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2870ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden state = TOIM3232_STATE_WAIT_SPEED; 2880ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden delay = toim3232delay; 2890ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden break; 2900ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2910ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden case TOIM3232_STATE_WAIT_SPEED: 2920ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Have transmitted control byte * Wait for 'at least 1us' */ 2930ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden udelay(14); 2940ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2950ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Set DTR, Set RTS: Go into normal data mode */ 2960ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden sirdev_set_dtr_rts(dev, TRUE, TRUE); 2970ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 2980ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Wait (TODO: check this is needed) */ 2990ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden udelay(50); 3000ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden break; 3010ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3020ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden default: 303a97a6f10771b90235b33c13a6db9279237a08422Harvey Harrison printk(KERN_ERR "%s - undefined state %d\n", __func__, state); 3040ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden ret = -EINVAL; 3050ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden break; 3060ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden } 3070ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3080ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden dev->fsm.substate = state; 3090ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden return (delay > 0) ? delay : ret; 3100ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden} 3110ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3120ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden/* 3130ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Function toim3232reset (driver) 3140ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 3150ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * This function resets the toim3232 dongle. Warning, this function 3160ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * must be called with a process context!! 3170ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 3180ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * What we should do is: 3190ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 0. Pull RESET high 3200ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 1. Wait for at least 7us 3210ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 2. Pull RESET low 3220ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 3. Wait for at least 7us 3230ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 4. Pull BR/~D high 3240ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 5. Wait for at least 7us 3250ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 6. Send control byte to set baud rate 3260ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 7. Wait at least 1us after stop bit 3270ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 8. Pull BR/~D low 3280ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 9. Should then be in data mode 3290ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 3300ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * Because the IR320ST-2 doesn't have the RESET line connected for some reason, 3310ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * we'll have to do something else. 3320ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 3330ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * The default speed after a RESET is 9600, so lets try just bringing it up in 3340ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * data mode after switching it off, waiting for the supply capacitor to 3350ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * discharge, and then switch it back on. This isn't actually pulling RESET 3360ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * high, but it seems to have the same effect. 3370ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 3380ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * This behaviour will probably work on dongles that have the RESET line connected, 3390ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * but if not, add a flag for the IR320ST-2, and implment the above-listed proper 3400ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * behaviour. 3410ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * 3420ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * RTS is inverted and then fed to BR/~D, so to put it in programming mode, we 3430ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden * need to have pull RTS low 3440ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden */ 3450ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3460ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenstatic int toim3232_reset(struct sir_dev *dev) 3470ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden{ 348a97a6f10771b90235b33c13a6db9279237a08422Harvey Harrison IRDA_DEBUG(2, "%s()\n", __func__); 3490ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3500ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Switch off both DTR and RTS to switch off dongle */ 3510ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden sirdev_set_dtr_rts(dev, FALSE, FALSE); 3520ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3530ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Should sleep a while. This might be evil doing it this way.*/ 3540ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden set_current_state(TASK_UNINTERRUPTIBLE); 3550ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden schedule_timeout(msecs_to_jiffies(50)); 3560ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3570ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Set DTR, Set RTS (data mode) */ 3580ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden sirdev_set_dtr_rts(dev, TRUE, TRUE); 3590ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3600ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Wait at least 10 ms for power to stabilize again */ 3610ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden set_current_state(TASK_UNINTERRUPTIBLE); 3620ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden schedule_timeout(msecs_to_jiffies(10)); 3630ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3640ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden /* Speed should now be 9600 */ 3650ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden dev->speed = 9600; 3660ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3670ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden return 0; 3680ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden} 3690ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3700ac81ae34ec8898e7eb1388fe21e3cee7b626a88David BasdenMODULE_AUTHOR("David Basden <davidb-linux@rcpt.to>"); 3710ac81ae34ec8898e7eb1388fe21e3cee7b626a88David BasdenMODULE_DESCRIPTION("Vishay/Temic TOIM3232 based dongle driver"); 3720ac81ae34ec8898e7eb1388fe21e3cee7b626a88David BasdenMODULE_LICENSE("GPL"); 3730ac81ae34ec8898e7eb1388fe21e3cee7b626a88David BasdenMODULE_ALIAS("irda-dongle-12"); /* IRDA_TOIM3232_DONGLE */ 3740ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basden 3750ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenmodule_init(toim3232_sir_init); 3760ac81ae34ec8898e7eb1388fe21e3cee7b626a88David Basdenmodule_exit(toim3232_sir_cleanup); 377