diff options
author | Alois Schlögl <alois.schloegl@ist.ac.at> | 2012-09-17 19:22:52 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-09-17 19:45:28 -0700 |
commit | 2eae6bdc12f4e49b7f94f032b82d664dcf3881bc (patch) | |
tree | 15158b8c45927f10f964b11b538725bcf8e1a695 /drivers/staging/ced1401/usb1401.h | |
parent | 57991b6bfc2b0faafb7d42edbd1673903d76b853 (diff) | |
download | kernel_goldelico_gta04-2eae6bdc12f4e49b7f94f032b82d664dcf3881bc.zip kernel_goldelico_gta04-2eae6bdc12f4e49b7f94f032b82d664dcf3881bc.tar.gz kernel_goldelico_gta04-2eae6bdc12f4e49b7f94f032b82d664dcf3881bc.tar.bz2 |
Staging: add ced1401 USB driver
This was imported from the
http://pub.ist.ac.at/~schloegl/src/ced1401/.git git repo at the request
of Alois. The driver originally came from Cambridge Electronic Design
Ltd and was authored by Greg P Smith and others, but Alois did the
maintance work to get it into a semi-building state and pushed to get it
into the main kernel tree here.
Cc: Alois Schlögl <alois.schloegl@ist.ac.at>
Cc: Greg P. Smith <greg@ced.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/ced1401/usb1401.h')
-rw-r--r-- | drivers/staging/ced1401/usb1401.h | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/drivers/staging/ced1401/usb1401.h b/drivers/staging/ced1401/usb1401.h new file mode 100644 index 0000000..331ca98 --- /dev/null +++ b/drivers/staging/ced1401/usb1401.h @@ -0,0 +1,249 @@ +/* usb1401.h + Header file for the CED 1401 USB device driver for Linux + Copyright (C) 2010 Cambridge Electronic Design Ltd + Author Greg P Smith (greg@ced.co.uk) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#ifndef __USB1401_H__ +#define __USB1401_H__ +#include "use1401.h" +#include "ced_ioctl.h" + +#ifndef UINT +#define UINT unsigned int +#endif + +/// Device type codes, but these don't need to be extended - a succession is assumed +/// These are set for usb from the bcdDevice field (suitably mangled). Future devices +/// will be added in order of device creation to the list, so the names here are just +/// to help use remember which device is which. The U14ERR_... values follow the same +/// pattern for modern devices. +#define TYPEUNKNOWN -1 // dont know +#define TYPE1401 0 // standard 1401 +#define TYPEPLUS 1 // 1401 plus +#define TYPEU1401 2 // u1401 +#define TYPEPOWER 3 // Power1401 +#define TYPEU14012 4 // u1401 mkII +#define TYPEPOWER2 5 // Power1401 mk II +#define TYPEMICRO3 6 // Micro1401-3 +#define TYPEPOWER3 7 // Power1401-3 + +/// Some useful defines of constants. DONT FORGET to change the version in the +/// resources whenever you change it here!. +#define DRIVERMAJREV 2 // driver revision level major (match windows) +#define DRIVERMINREV 0 // driver revision level minor + +/// Definitions of the various block transfer command codes +#define TM_EXTTOHOST 8 // extended tohost +#define TM_EXTTO1401 9 // extended to1401 + +/// Definitions of values in usbReqtype. Used in sorting out setup actions +#define H_TO_D 0x00 +#define D_TO_H 0x80 +#define VENDOR 0x40 +#define DEVREQ 0x00 +#define INTREQ 0x01 +#define ENDREQ 0x02 + +/// Definition of values in usbRequest, again used to sort out setup +#define GET_STATUS 0x00 +#define CLEAR_FEATURE 0x01 +#define SET_FEATURE 0x03 +#define SET_ADDRESS 0x05 +#define GET_DESC 0x06 +#define SET_DESC 0x07 +#define GET_CONF 0x08 +#define SET_CONF 0x09 +#define GET_INTERFACE 0x0a +#define SET_INTERFACE 0x0b +#define SYNCH_FRAME 0x0c + +/// Definitions of the various debug command codes understood by the 1401. These +/// are used in various vendor-specific commands to achieve the desired effect +#define DB_GRAB 0x50 /* Grab is a NOP for USB */ +#define DB_FREE 0x51 /* Free is a NOP for the USB */ +#define DB_SETADD 0x52 /* Set debug address (double) */ +#define DB_SELFTEST 0x53 /* Start self test */ +#define DB_SETMASK 0x54 /* Set enable mask (double) */ +#define DB_SETDEF 0x55 /* Set default mask (double) */ +#define DB_PEEK 0x56 /* Peek address, save result */ +#define DB_POKE 0x57 /* Poke address with data (double) */ +#define DB_RAMPD 0x58 /* Ramp data at debug address */ +#define DB_RAMPA 0x59 /* Ramp address bus */ +#define DB_REPEATS 0x5A /* Set repeats for operations (double) */ +#define DB_WIDTH 0x5B /* Set width for operations (byte) */ +#define DB_DATA 0x5C /* Get 4-byte data read by PEEK */ +#define DB_CHARS 0x5D /* Send chars via EP0 control write */ + +#define CR_CHAR 0x0D /* The carriage return character */ +#define CR_CHAR_80 0x8d /* and with bit 7 set */ + +/// A structure holding information about a block of memory for use in circular transfers +typedef struct circBlk +{ + volatile UINT dwOffset; /* Offset within area of block start */ + volatile UINT dwSize; /* Size of the block, in bytes (0 = unused) */ +} CIRCBLK; + +/// A structure holding all of the information about a transfer area - an area of +/// memory set up for use either as a source or destination in DMA transfers. +typedef struct transarea +{ + void* lpvBuff; // User address of xfer area saved for completeness + UINT dwBaseOffset; // offset to start of xfer area in first page + UINT dwLength; // Length of xfer area, in bytes + struct page **pPages; // Points at array of locked down pages + int nPages; // number of pages that are locked down + bool bUsed; // Is this structure in use? + bool bCircular; // Is this area for circular transfers? + bool bCircToHost; // Flag for direction of circular transfer + bool bEventToHost; // Set event on transfer to host? + int iWakeUp; // Set 1 on event, cleared by TestEvent() + UINT dwEventSt; // Defines section within xfer area for... + UINT dwEventSz; // ...notification by the event SZ is 0 if unset + CIRCBLK aBlocks[2]; // Info on a pair of circular blocks + wait_queue_head_t wqEvent; // The wait queue for events in this area MUST BE LAST +} TRANSAREA; + +/// The DMADESC structure is used to hold information on the transfer in progress. It +/// is set up by ReadDMAInfo, using information sent by the 1401 in an escape sequence. +typedef struct dmadesc +{ + unsigned short wTransType; /* transfer type as TM_xxx above */ + unsigned short wIdent; /* identifier word */ + unsigned int dwSize; /* bytes to transfer */ + unsigned int dwOffset; /* offset into transfer area for trans */ + bool bOutWard; /* true when data is going TO 1401 */ +} DMADESC; + +#define INBUF_SZ 256 /* input buffer size */ +#define OUTBUF_SZ 256 /* output buffer size */ +#define STAGED_SZ 0x10000 // size of coherent buffer for staged transfers + +/// Structure to hold all of our device specific stuff. We are making this as similar as we +/// can to the Windows driver to help in our understanding of what is going on. +typedef struct _DEVICE_EXTENSION +{ + char inputBuffer[INBUF_SZ]; /* The two buffers */ + char outputBuffer[OUTBUF_SZ]; /* accessed by the host functions */ + volatile unsigned int dwNumInput; /* num of chars in input buffer */ + volatile unsigned int dwInBuffGet; /* where to get from input buffer */ + volatile unsigned int dwInBuffPut; /* where to put into input buffer */ + volatile unsigned int dwNumOutput; /* num of chars in output buffer */ + volatile unsigned int dwOutBuffGet; /* where to get from output buffer*/ + volatile unsigned int dwOutBuffPut; /* where to put into output buffer*/ + + volatile bool bSendCharsPending; /* Flag to indicate sendchar active */ + volatile bool bReadCharsPending; /* Flag to indicate a read is primed */ + char* pCoherCharOut; /* special aligned buffer for chars to 1401 */ + struct urb* pUrbCharOut; /* urb used for chars to 1401 */ + char* pCoherCharIn; /* special aligned buffer for chars to host */ + struct urb* pUrbCharIn; /* urb used for chars to host */ + + spinlock_t charOutLock; /* to protect the outputBuffer and outputting */ + spinlock_t charInLock; /* to protect the inputBuffer and char reads */ + __u8 bInterval; /* Interrupt end point interval */ + + volatile unsigned int dwDMAFlag; /* state of DMA */ + TRANSAREA rTransDef[MAX_TRANSAREAS];/* transfer area info */ + volatile DMADESC rDMAInfo; // info on current DMA transfer + volatile bool bXFerWaiting; // Flag set if DMA transfer stalled + volatile bool bInDrawDown; // Flag that we want to halt transfers + + // Parameters relating to a block read\write that is in progress. Some of these values + // are equivalent to values in rDMAInfo. The values here are those in use, while those + // in rDMAInfo are those recieved from the 1401 via an escape sequence. If another + // escape sequence arrives before the previous xfer ends, rDMAInfo values are updated while these + // are used to finish off the current transfer. + volatile short StagedId; // The transfer area id for this transfer + volatile bool StagedRead; // Flag TRUE for read from 1401, FALSE for write + volatile unsigned int StagedLength; // Total length of this transfer + volatile unsigned int StagedOffset; // Offset within memory area for transfer start + volatile unsigned int StagedDone; // Bytes transferred so far + volatile bool bStagedUrbPending; // Flag to indicate active + char* pCoherStagedIO; // buffer used for block transfers + struct urb* pStagedUrb; // The URB to use + spinlock_t stagedLock; // protects ReadWriteMem() and circular buffer stuff + + short s1401Type; // type of 1401 attached + short sCurrentState; // current error state + bool bIsUSB2; // type of the interface we connect to + bool bForceReset; // Flag to make sure we get a real reset + __u32 statBuf[2]; // buffer for 1401 state info + + unsigned long ulSelfTestTime; // used to timeout self test + + int nPipes; // Should be 3 or 4 depending on 1401 usb chip + int bPipeError[4]; // set non-zero if an error on one of the pipe + __u8 epAddr[4]; // addresses of the 3/4 end points + + struct usb_device *udev; // the usb device for this device + struct usb_interface *interface; // the interface for this device, NULL if removed + struct usb_anchor submitted; // in case we need to retract our submissions + struct mutex io_mutex; // synchronize I/O with disconnect, one user-mode caller at a time + + int errors; // the last request tanked + int open_count; // count the number of openers + spinlock_t err_lock; // lock for errors + struct kref kref; +}DEVICE_EXTENSION, *PDEVICE_EXTENSION; +#define to_DEVICE_EXTENSION(d) container_of(d, DEVICE_EXTENSION, kref) + +/// Definitions of routimes used between compilation object files +// in usb1401.c +extern int Allowi(DEVICE_EXTENSION* pdx, bool bInCallback); +extern int SendChars(DEVICE_EXTENSION* pdx); +extern void ced_draw_down(DEVICE_EXTENSION *pdx); +extern int ReadWriteMem(DEVICE_EXTENSION *pdx, bool Read, unsigned short wIdent, + unsigned int dwOffs, unsigned int dwLen); + +// in ced_ioc.c +extern int ClearArea(DEVICE_EXTENSION *pdx, int nArea); +extern int SendString(DEVICE_EXTENSION* pdx, const char __user* pData, unsigned int n); +extern int SendChar(DEVICE_EXTENSION *pdx, char c); +extern int Get1401State(DEVICE_EXTENSION* pdx, __u32* state, __u32* error); +extern int ReadWrite_Cancel(DEVICE_EXTENSION *pdx); +extern bool Is1401(DEVICE_EXTENSION* pdx); +extern bool QuickCheck(DEVICE_EXTENSION* pdx, bool bTestBuff, bool bCanReset); +extern int Reset1401(DEVICE_EXTENSION *pdx); +extern int GetChar(DEVICE_EXTENSION *pdx); +extern int GetString(DEVICE_EXTENSION *pdx, char __user* pUser, int n); +extern int SetTransfer(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD); +extern int UnsetTransfer(DEVICE_EXTENSION *pdx, int nArea); +extern int SetEvent(DEVICE_EXTENSION *pdx, TRANSFEREVENT __user*pTE); +extern int Stat1401(DEVICE_EXTENSION *pdx); +extern int LineCount(DEVICE_EXTENSION *pdx); +extern int GetOutBufSpace(DEVICE_EXTENSION *pdx); +extern int GetTransfer(DEVICE_EXTENSION *pdx, TGET_TX_BLOCK __user *pGTB); +extern int KillIO1401(DEVICE_EXTENSION *pdx); +extern int BlkTransState(DEVICE_EXTENSION *pdx); +extern int StateOf1401(DEVICE_EXTENSION *pdx); +extern int StartSelfTest(DEVICE_EXTENSION *pdx); +extern int CheckSelfTest(DEVICE_EXTENSION *pdx, TGET_SELFTEST __user *pGST); +extern int TypeOf1401(DEVICE_EXTENSION *pdx); +extern int TransferFlags(DEVICE_EXTENSION *pdx); +extern int DbgPeek(DEVICE_EXTENSION *pdx, TDBGBLOCK __user* pDB); +extern int DbgPoke(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); +extern int DbgRampData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); +extern int DbgRampAddr(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); +extern int DbgGetData(DEVICE_EXTENSION *pdx, TDBGBLOCK __user *pDB); +extern int DbgStopLoop(DEVICE_EXTENSION *pdx); +extern int SetCircular(DEVICE_EXTENSION *pdx, TRANSFERDESC __user *pTD); +extern int GetCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB); +extern int FreeCircBlock(DEVICE_EXTENSION *pdx, TCIRCBLOCK __user* pCB); +extern int WaitEvent(DEVICE_EXTENSION *pdx, int nArea, int msTimeOut); +extern int TestEvent(DEVICE_EXTENSION *pdx, int nArea); +#endif |