1 /*
2  * $Id$
3  *
4  * Cable driver interface
5  * Copyright (C) 2003 ETC s.r.o.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20  * 02111-1307, USA.
21  *
22  * Written by Marcel Telka <marcel@telka.sk>, 2003.
23  *
24  */
25 
26 #ifndef URJ_CABLE_H
27 #define URJ_CABLE_H
28 
29 #include <stdint.h>
30 
31 #include "types.h"
32 #include "params.h"
33 
34 #include "parport.h"
35 #include "pod.h"
36 
37 typedef struct URJ_CABLE_DRIVER urj_cable_driver_t;
38 
39 typedef enum URJ_CABLE_FLUSH_AMOUNT
40 {
41     URJ_TAP_CABLE_OPTIONALLY,
42     URJ_TAP_CABLE_TO_OUTPUT,
43     URJ_TAP_CABLE_COMPLETELY
44 }
45 urj_cable_flush_amount_t;
46 
47 typedef enum URJ_CABLE_DEVICE_TYPE
48 {
49     URJ_CABLE_DEVICE_PARPORT,
50     URJ_CABLE_DEVICE_USB,
51     URJ_CABLE_DEVICE_OTHER,
52 }
53 urj_cable_device_type_t;
54 
55 typedef enum URJ_CABLE_PARAM_KEY
56 {
57     URJ_CABLE_PARAM_KEY_PID,            /* lu           generic_usbconn */
58     URJ_CABLE_PARAM_KEY_VID,            /* lu           generic_usbconn */
59     URJ_CABLE_PARAM_KEY_DESC,           /* string       generic_usbconn */
60     URJ_CABLE_PARAM_KEY_DRIVER,         /* string       generic_usbconn */
61     URJ_CABLE_PARAM_KEY_BITMAP,         /* string       wiggler */
62     URJ_CABLE_PARAM_KEY_TDI,            /* lu           gpio used as TDI */
63     URJ_CABLE_PARAM_KEY_TDO,            /* lu           gpio used as TDO */
64     URJ_CABLE_PARAM_KEY_TMS,            /* lu           gpio used as TMS */
65     URJ_CABLE_PARAM_KEY_TCK,            /* lu           gpio used as TCK */
66     URJ_CABLE_PARAM_KEY_INTERFACE,      /* lu           ftdi */
67     URJ_CABLE_PARAM_KEY_FIRMWARE,       /* string       ice100 */
68     URJ_CABLE_PARAM_KEY_INDEX,          /* lu           ftdi */
69     URJ_CABLE_PARAM_KEY_TRST,           /* lu           ft4232_generic */
70     URJ_CABLE_PARAM_KEY_RESET,          /* lu           ft4232_generic */
71 }
72 urj_cable_param_key_t;
73 
74 /* Random cable-specific quirks; a bitfield */
75 #define URJ_CABLE_QUIRK_ONESHOT 0x1
76 
77 struct URJ_CABLE_DRIVER
78 {
79     const char *name;
80     const char *description;
81     /** tag for the following union */
82     urj_cable_device_type_t device_type;
83     /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure */
84     union {
85         int (*parport) (urj_cable_t *cable, urj_cable_parport_devtype_t devtype,
86                         const char *devname, const urj_param_t *params[]);
87         int (*usb) (urj_cable_t *cable, const urj_param_t *params[]);
88         int (*other) (urj_cable_t *cable, const urj_param_t *params[]);
89     } connect;
90     void (*disconnect) (urj_cable_t *cable);
91     void (*cable_free) (urj_cable_t *cable);
92     /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure */
93     int (*init) (urj_cable_t *);
94     void (*done) (urj_cable_t *);
95     void (*set_frequency) (urj_cable_t *, uint32_t freq);
96     void (*clock) (urj_cable_t *, int, int, int);
97     /** @return 0 or 1 on success; -1 on failure */
98     int (*get_tdo) (urj_cable_t *);
99     /** @return nonnegative number, or the number of transferred bits on
100      * success; -1 on failure */
101     int (*transfer) (urj_cable_t *, int, const char *, char *);
102     /** @return 0 or 1 on success; -1 on failure */
103     int (*set_signal) (urj_cable_t *, int, int);
104     /** @return 0 or 1 on success; -1 on failure */
105     int (*get_signal) (urj_cable_t *, urj_pod_sigsel_t);
106     void (*flush) (urj_cable_t *, urj_cable_flush_amount_t);
107     void (*help) (urj_log_level_t ll, const char *);
108     /* A bitfield of quirks */
109     uint32_t quirks;
110 };
111 
112 typedef struct URJ_CABLE_QUEUE urj_cable_queue_t;
113 
114 struct URJ_CABLE_QUEUE
115 {
116     enum
117     {
118         URJ_TAP_CABLE_CLOCK,
119         URJ_TAP_CABLE_CLOCK_COMPACT,
120         URJ_TAP_CABLE_GET_TDO,
121         URJ_TAP_CABLE_TRANSFER,
122         URJ_TAP_CABLE_SET_SIGNAL,
123         URJ_TAP_CABLE_GET_SIGNAL
124     } action;
125     union
126     {
127         struct
128         {
129             int tms;
130             int tdi;
131             int n;
132         } clock;
133         struct
134         {
135             urj_pod_sigsel_t sig;
136             int mask;
137             int val;
138         } value;
139         struct
140         {
141             int len;
142             char *in;
143             char *out;
144         } transfer;
145         struct
146         {
147             int len;
148             int res;
149             char *out;
150         } xferred;
151     } arg;
152 };
153 
154 typedef struct URJ_CABLE_QUEUE_INFO urj_cable_queue_info_t;
155 
156 struct URJ_CABLE_QUEUE_INFO
157 {
158     urj_cable_queue_t *data;
159     int max_items;
160     int num_items;
161     int next_item;
162     int next_free;
163 };
164 
165 struct URJ_CABLE
166 {
167     const urj_cable_driver_t *driver;
168     union
169     {
170         urj_usbconn_t *usb;
171         urj_parport_t *port;
172         void *other;
173     } link;
174     void *params;
175     urj_chain_t *chain;
176     urj_cable_queue_info_t todo;
177     urj_cable_queue_info_t done;
178     uint32_t delay;
179     uint32_t frequency;
180 };
181 
182 void urj_tap_cable_free (urj_cable_t *cable);
183 /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure */
184 int urj_tap_cable_init (urj_cable_t *cable);
185 /** @return cable named by @cname; NULL on failure */
186 const urj_cable_driver_t *urj_tap_cable_find (const char *cname);
187 void urj_tap_cable_done (urj_cable_t *cable);
188 void urj_tap_cable_flush (urj_cable_t *cable,
189                           urj_cable_flush_amount_t);
190 /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure */
191 void urj_tap_cable_clock (urj_cable_t *cable, int tms, int tdi, int n);
192 int urj_tap_cable_defer_clock (urj_cable_t *cable, int tms, int tdi, int n);
193 /** @return 0 or 1 on success; -1 on failure */
194 int urj_tap_cable_get_tdo (urj_cable_t *cable);
195 /** @return 0 or 1 on success; -1 on failure */
196 int urj_tap_cable_get_tdo_late (urj_cable_t *cable);
197 /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure */
198 int urj_tap_cable_defer_get_tdo (urj_cable_t *cable);
199 /** @return 0 or 1 on success; -1 on failure */
200 int urj_tap_cable_set_signal (urj_cable_t *cable, int mask, int val);
201 /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure */
202 int urj_tap_cable_defer_set_signal (urj_cable_t *cable, int mask, int val);
203 /** @return 0 or 1 on success; -1 on failure */
204 int urj_tap_cable_get_signal (urj_cable_t *cable, urj_pod_sigsel_t sig);
205 /** @return 0 or 1 on success; -1 on failure */
206 int urj_tap_cable_get_signal_late (urj_cable_t *cable, urj_pod_sigsel_t sig);
207 /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure */
208 int urj_tap_cable_defer_get_signal (urj_cable_t *cable, urj_pod_sigsel_t sig);
209 /** @return the number of transferred bits on success; -1 on failure */
210 int urj_tap_cable_transfer (urj_cable_t *cable, int len, char *in, char *out);
211 /** @return the number of transferred bits on success; -1 on failure */
212 int urj_tap_cable_transfer_late (urj_cable_t *cable, char *out);
213 /** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure */
214 int urj_tap_cable_defer_transfer (urj_cable_t *cable, int len, char *in,
215                                   char *out);
216 
217 void urj_tap_cable_set_frequency (urj_cable_t *cable, uint32_t frequency);
218 uint32_t urj_tap_cable_get_frequency (urj_cable_t *cable);
219 void urj_tap_cable_wait (urj_cable_t *cable);
220 void urj_tap_cable_purge_queue (urj_cable_queue_info_t *q, int io);
221 /** @return queue item number on success; -1 on failure */
222 int urj_tap_cable_add_queue_item (urj_cable_t *cable,
223                                   urj_cable_queue_info_t *q);
224 /** @return queue item number on success; -1 on failure */
225 int urj_tap_cable_get_queue_item (urj_cable_t *cable,
226                                   urj_cable_queue_info_t *q);
227 
228 /**
229  * API function to connect to a parport cable
230  *
231  * @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure
232  */
233 urj_cable_t *urj_tap_cable_parport_connect (urj_chain_t *chain,
234                                             const urj_cable_driver_t *driver,
235                                             urj_cable_parport_devtype_t devtype,
236                                             const char *devname,
237                                             const urj_param_t *params[]);
238 /**
239  * API function to connect to a USB cable
240  *
241  * @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure
242  */
243 urj_cable_t *urj_tap_cable_usb_connect (urj_chain_t *chain,
244                                         const urj_cable_driver_t *driver,
245                                         const urj_param_t *params[]);
246 int urj_tap_cable_usb_probe (char *params[]);
247 
248 /**
249  * API function to connect to a type-other cable
250  *
251  * @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on failure
252  */
253 urj_cable_t *urj_tap_cable_other_connect (urj_chain_t *chain,
254                                           const urj_cable_driver_t *driver,
255                                           const urj_param_t *params[]);
256 
257 extern const urj_cable_driver_t * const urj_tap_cable_drivers[];
258 
259 /** The list of recognized parameters */
260 extern const urj_param_list_t urj_cable_param_list;
261 
262 #endif /* URJ_CABLE_H */
263