revert between 56095 -> 55830 in arch
[AROS.git] / arch / i386-pc / drivers / parallel.hidd / ParallelUnitClass.c
blob65743f8118f6fed9141165643c6e818719fa3cbc
1 /*
2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Parallel Unit hidd class implementation.
6 Lang: english
7 */
9 #define __OOP_NOATTRBASES__
11 /* the rest are Amiga includes */
12 #include <proto/exec.h>
13 #include <proto/utility.h>
14 #include <proto/oop.h>
15 #include <proto/alib.h>
16 #include <exec/libraries.h>
17 #include <exec/ports.h>
18 #include <exec/memory.h>
19 #include <exec/interrupts.h>
20 #include <exec/lists.h>
21 #include <aros/symbolsets.h>
23 #include <utility/tagitem.h>
24 #include <hidd/parallel.h>
25 #include <hidd/unixio.h>
27 #include "parallel_intern.h"
29 #include LC_LIBDEFS_FILE
31 #undef SDEBUG
32 #undef DEBUG
33 #define SDEBUG 0
34 #define DEBUG 0
35 #include <aros/debug.h>
37 void parallelunit_receive_data();
38 void parallelunit_write_more_data();
40 static inline unsigned char inb(unsigned short port)
43 unsigned char _v;
45 __asm__ __volatile__
46 ("inb %w1,%0"
47 : "=a" (_v)
48 : "Nd" (port)
51 return _v;
54 static inline void outb(unsigned char value, unsigned short port)
56 __asm__ __volatile__
57 ("outb %b0,%w1"
59 : "a" (value), "Nd" (port)
63 #define parallel_usleep(x) __asm__ __volatile__("\noutb %al,$0x80\n")
65 static inline void parallel_out(struct HIDDParallelUnitData * data,
66 int offset,
67 int value)
69 outb(value, data->baseaddr+offset);
72 static inline unsigned int parallel_in(struct HIDDParallelUnitData * data,
73 int offset)
75 return inb(data->baseaddr+offset);
78 /*************************** Classes *****************************/
80 /* IO bases for every Parallel port */
82 static ULONG bases[] = { 0x378, 0x278, 0x3bc};
84 static OOP_AttrBase HiddParallelUnitAB;
86 static struct OOP_ABDescr attrbases[] =
88 { IID_Hidd_ParallelUnit, &HiddParallelUnitAB },
89 { NULL, NULL }
92 /******* ParallelUnit::New() ***********************************/
93 OOP_Object *PCParUnit__Root__New(OOP_Class *cl, OOP_Object *obj, struct pRoot_New *msg)
95 struct HIDDParallelUnitData * data;
96 // static const struct TagItem tags[] = {{ TAG_END, 0}};
97 struct TagItem *tag, *tstate;
98 ULONG unitnum = 0;
100 EnterFunc(bug("ParallelUnit::New()\n"));
102 tstate = msg->attrList;
103 while ((tag = NextTagItem(&tstate))) {
104 ULONG idx;
106 if (IS_HIDDPARALLELUNIT_ATTR(tag->ti_Tag, idx)) {
107 switch (idx) {
108 case aoHidd_ParallelUnit_Unit:
109 unitnum = (ULONG)tag->ti_Data;
110 break;
114 } /* while (tags to process) */
116 D(bug("!!!!Request for unit number %d\n",unitnum));
118 obj = (OOP_Object *)OOP_DoSuperMethod(cl, obj, (OOP_Msg)msg);
120 if (obj) {
121 data = OOP_INST_DATA(cl, obj);
123 data->baseaddr = bases[unitnum];
124 data->unitnum = unitnum;
126 #if 0
128 * Enable the interrupt
130 parallel_outp(data, UART_PCP, UART_PCP_IRQ_EN);
131 #endif
133 /* Reset? */
135 parallel_out(data, PAR_PCP, PAR_PCP_SLCT_IN);
136 parallel_usleep(60);
137 parallel_out(data, PAR_PCP, PAR_PCP_SLCT_IN | PAR_PCP_INIT);
139 /* Reset ? */
141 } /* if (obj) */
143 D(bug("%s - an error occurred!\n",__FUNCTION__));
145 ReturnPtr("ParallelUnit::New()", OOP_Object *, obj);
148 /******* ParallelUnit::Dispose() ***********************************/
149 OOP_Object *PCParUnit__Root__Dispose(OOP_Class *cl, OOP_Object *obj, OOP_Msg msg)
151 #if 0
152 struct HIDDParallelUnitData * data;
153 #endif
154 EnterFunc(bug("ParallelUnit::Dispose()\n"));
156 #if 0
157 data = OOP_INST_DATA(cl, obj);
159 /* stop all interrupts */
160 serial_outp(data, UART_PCP, 0);
161 #endif
163 OOP_DoSuperMethod(cl, obj, (OOP_Msg)msg);
164 ReturnPtr("ParallelUnit::Dispose()", OOP_Object *, obj);
169 /******* ParallelUnit::Init() **********************************/
170 BOOL PCParUnit__Hidd_ParallelUnit__Init(OOP_Class *cl, OOP_Object *o, struct pHidd_ParallelUnit_Init *msg)
172 struct HIDDParallelUnitData * data = OOP_INST_DATA(cl, o);
174 EnterFunc(bug("ParallelUnit::Init()\n"));
175 data->DataReceivedCallBack = msg->DataReceived;
176 data->DataReceivedUserData = msg->DataReceivedUserData;
177 data->DataWriteCallBack = msg->WriteData;
178 data->DataWriteUserData = msg->WriteDataUserData;
180 ReturnBool("ParallelUnit::Init()", TRUE);
183 /******* ParallelUnit::Write() **********************************/
184 ULONG PCParUnit__Hidd_ParallelUnit__Write(OOP_Class *cl, OOP_Object *o, struct pHidd_ParallelUnit_Write *msg)
186 struct HIDDParallelUnitData * data = OOP_INST_DATA(cl, o);
187 ULONG len = msg->Length, count;
188 // ULONG error;
189 // unsigned char status;
191 EnterFunc(bug("ParallelUnit::Write()\n"));
193 * If the output is currently stopped just don't do anything here.
195 if (TRUE == data->stopped)
196 return 0;
198 parallel_usleep(1);
200 for(count = 0; count < len; count++)
202 parallel_out(data, PAR_DATA, msg->Outbuffer[count]);
204 while((parallel_in(data, PAR_SP) & (PAR_SP_BUSY | PAR_SP_ERROR)) !=
205 (PAR_SP_BUSY | PAR_SP_ERROR))
207 parallel_usleep(1);
210 parallel_usleep(1);
211 parallel_out(data, PAR_PCP, PAR_PCP_SLCT_IN | PAR_PCP_INIT | PAR_PCP_STROBE);
212 parallel_usleep(1);
213 parallel_out(data, PAR_PCP, PAR_PCP_SLCT_IN | PAR_PCP_INIT);
214 parallel_usleep(1);
217 ReturnInt("ParallelUnit::Write()",ULONG, count);
220 /******* ParallelUnit::Start() **********************************/
221 VOID PCParUnit__Hidd_ParallelUnit__Start(OOP_Class *cl, OOP_Object *o, struct pHidd_ParallelUnit_Start *msg)
223 struct HIDDParallelUnitData * data = OOP_INST_DATA(cl, o);
226 * Allow or start feeding the UART with data. Get the data
227 * from upper layer.
229 if (TRUE == data->stopped) {
230 if (NULL != data->DataWriteCallBack)
231 data->DataWriteCallBack(data->unitnum, data->DataWriteUserData);
233 * Also mark the stopped flag as FALSE.
235 data->stopped = FALSE;
239 /******* ParallelUnit::Stop() **********************************/
240 VOID PCParUnit__Hidd_ParallelUnit__Stop(OOP_Class *cl, OOP_Object *o, struct pHidd_ParallelUnit_Stop *msg)
242 struct HIDDParallelUnitData * data = OOP_INST_DATA(cl, o);
245 * The next time the interrupt comes along and asks for
246 * more data we just don't do anything...
248 data->stopped = TRUE;
251 /****** ParallelUnit::GetStatus ********************************/
252 UWORD PCParUnit__Hidd_ParallelUnit__GetStatus(OOP_Class *cl, OOP_Object *o, struct pHidd_ParallelUnit_GetStatus *msg)
254 struct HIDDParallelUnitData * data = OOP_INST_DATA(cl, o);
256 BYTE status;
257 UWORD rc = 0;
259 status = parallel_in(data, PAR_SP);
261 if (status & PAR_SP_BUSY)
262 rc |= (1 << 0);
263 if (status & PAR_SP_PE)
264 rc |= (1 << 1);
265 if (status & PAR_SP_SLCT)
266 rc |= (1 << 2);
268 return rc;
272 #if 0 /* !! STUFF BELOW DESABLED !! */
274 /************* The software interrupt handler that gets data from PORT *****/
277 #define READBUFFER_SIZE 513
279 AROS_UFH3(void, parallelunit_receive_data,
280 AROS_UFHA(APTR, iD, A1),
281 AROS_UFHA(APTR, iC, A5),
282 AROS_UFHA(struct ExecBase *, SysBase, A6))
284 AROS_USERFUNC_INIT
286 struct HIDDSerialUnitData * data = iD;
287 int len = 0;
288 UBYTE buffer[READBUFFER_SIZE];
290 buffer[len++] = parallel_inp(data, PAR_DATA);
292 ** ... and deliver them to whoever is interested.
295 if (NULL != data->DataReceivedCallBack)
296 data->DataReceivedCallBack(buffer, len, data->unitnum, data->DataReceivedUserData);
298 AROS_USERFUNC_EXIT
301 AROS_UFH3(void, parallelunit_write_more_data,
302 AROS_UFHA(APTR, iD, A1),
303 AROS_UFHA(APTR, iC, A5),
304 AROS_UFHA(struct ExecBase *, SysBase, A6))
306 AROS_USERFUNC_INIT
308 struct HIDDParallelUnitData * data = iD;
309 struct Message * msg;
312 ** Get the unixio message from my port and free it
314 msg = GetMsg(data->replyport_read);
315 FreeMem(msg, sizeof(struct uioMessage));
318 ** Ask for more data be written to the unit
320 D(bug("Asking for more data to be written to unit %d\n",data->unitnum));
322 if (NULL != data->DataWriteCallBack)
323 data->DataWriteCallBack(data->unitnum, data->DataWriteUserData);
325 AROS_USERFUNC_EXIT
328 #endif /* !! END DISABLED STUFF !! */
330 /******* init_parallelunitclass ********************************/
332 static int PCParUnit_Init(LIBBASETYPEPTR LIBBASE)
334 ReturnInt("PCParUnit_Init", ULONG, OOP_ObtainAttrBases(attrbases));
338 static int PCParUnit_Expunge(LIBBASETYPEPTR LIBBASE)
340 OOP_ReleaseAttrBases(attrbases);
341 ReturnInt("PCParUnit_Expunge", int, TRUE);
344 ADD2INITLIB(PCParUnit_Init, 0)
345 ADD2EXPUNGELIB(PCParUnit_Expunge, 0)