1/*
2 * Copyright 2009-2010, Fran��ois Revol, <revol@free.fr>.
3 * Sponsored by TuneTracker Systems.
4 * Based on the Haiku usb_serial driver which is:
5 *
6 * Copyright (c) 2007-2008 by Michael Lotz
7 * Heavily based on the original usb_serial driver which is:
8 *
9 * Copyright (c) 2003 by Siarzhuk Zharski <imker@gmx.li>
10 * Distributed under the terms of the MIT License.
11 */
12#ifndef _SERIAL_DEVICE_H_
13#define _SERIAL_DEVICE_H_
14
15#include "Driver.h"
16
17class SerialDevice {
18public:
19								SerialDevice(const struct serial_support_descriptor
20									*device, uint32 ioBase, uint32 irq, const SerialDevice *master=NULL);
21virtual							~SerialDevice();
22
23		bool					Probe();
24
25static	SerialDevice *			MakeDevice(struct serial_config_descriptor
26									*device);
27
28		status_t				Init();
29
30		const struct serial_support_descriptor	*SupportDescriptor() const
31									{ return fSupportDescriptor; };
32		struct serial_config_descriptor	*ConfigDescriptor() const
33									{ return fDevice; };
34		//uint16					ProductID() const { return fProductID; };
35		//uint16					VendorID() const { return fVendorID; };
36		const char *			Description() const { return fDescription; };
37
38		const SerialDevice *	Master() const { return fMaster ? fMaster : this; };
39
40		char *					ReadBuffer() { return fReadBuffer; };
41
42		char *					WriteBuffer() { return fWriteBuffer; };
43
44		void					SetModes(struct termios *tios);
45
46		bool					Service(struct tty *tty, uint32 op,
47									void *buffer, size_t length);
48
49		bool					IsInterruptPending();
50		int32					InterruptHandler();
51
52		status_t				Open(uint32 flags);
53		status_t				Read(char *buffer, size_t *numBytes);
54		status_t				Write(const char *buffer, size_t *numBytes);
55		status_t				Control(uint32 op, void *arg, size_t length);
56		status_t				Select(uint8 event, uint32 ref, selectsync *sync);
57		status_t				DeSelect(uint8 event, selectsync *sync);
58		status_t				Close();
59		status_t				Free();
60
61		bool					IsOpen() { return fDeviceOpen; };
62		void					Removed();
63		bool					IsRemoved() { return fDeviceRemoved; };
64
65		/* virtual interface to be overriden as necessary */
66virtual	status_t				AddDevice(const struct serial_config_descriptor *device);
67
68virtual	status_t				ResetDevice();
69
70//virtual	status_t				SetLineCoding(usb_serial_line_coding *coding);
71//virtual	status_t				SetControlLineState(uint16 state);
72virtual	status_t				SignalControlLineState(int line, bool enable);
73
74virtual	void					OnRead(char **buffer, size_t *numBytes);
75virtual	void					OnWrite(const char *buffer, size_t *numBytes,
76									size_t *packetBytes);
77virtual	void					OnClose();
78
79		uint32					IOBase() const { return fIOBase; };
80		uint32					IRQ() const { return fIRQ; };
81
82private:
83static	int32					_DeviceThread(void *data);
84		status_t				_WriteToDevice();
85
86static	void					ReadCallbackFunction(void *cookie,
87									int32 status, void *data,
88									uint32 actualLength);
89static	void					WriteCallbackFunction(void *cookie,
90									int32 status, void *data,
91									uint32 actualLength);
92static	void					InterruptCallbackFunction(void *cookie,
93									int32 status, void *data,
94									uint32 actualLength);
95
96		uint8					ReadReg8(int reg);
97		void					WriteReg8(int reg, uint8 value);
98		void					OrReg8(int reg, uint8 value);
99		void					AndReg8(int reg, uint8 value);
100		void					MaskReg8(int reg, uint8 value);
101
102		const struct serial_support_descriptor	*fSupportDescriptor;
103		struct serial_config_descriptor		*fDevice;		// USB device handle
104		const char *			fDescription;	// informational description
105		bool					fDeviceOpen;
106		bool					fDeviceRemoved;
107
108		bus_type				fBus;
109		uint32					fIOBase;
110		uint32					fIRQ;
111		const SerialDevice *	fMaster;
112
113		/* line coding */
114		//usb_serial_line_coding	fLineCoding;
115
116		/* deferred interrupt */
117		uint8					fCachedIER;	// last value written to IER
118		uint8					fCachedIIR;	// cached IRQ condition
119		int32					fPendingDPC; // some IRQ still
120
121		/* data buffers */
122		char					fReadBuffer[DEF_BUFFER_SIZE];
123		int32					fReadBufferAvail;
124		uint32					fReadBufferIn;
125		uint32					fReadBufferOut;
126		sem_id					fReadBufferSem;
127		char					fWriteBuffer[DEF_BUFFER_SIZE];
128		int32					fWriteBufferAvail;
129		uint32					fWriteBufferIn;
130		uint32					fWriteBufferOut;
131		sem_id					fWriteBufferSem;
132
133		/* variables used in callback functionality */
134		size_t					fActualLengthRead;
135		uint32					fStatusRead;
136		size_t					fActualLengthWrite;
137		uint32					fStatusWrite;
138		size_t					fActualLengthInterrupt;
139		uint32					fStatusInterrupt;
140
141		/* semaphores used in callbacks */
142		sem_id					fDoneRead;
143		sem_id					fDoneWrite;
144
145		uint16					fControlOut;
146		bool					fInputStopped;
147
148		struct tty *			fMasterTTY;
149		struct tty *			fSlaveTTY;
150		struct tty_cookie *		fSystemTTYCookie;
151		struct tty_cookie *		fDeviceTTYCookie;
152		struct termios			fTTYConfig;
153
154		/* device thread management */
155		thread_id				fDeviceThread;
156		bool					fStopDeviceThread;
157};
158
159#endif // _SERIAL_DEVICE_H_
160