Warning, cross-references for /kernel/drivers/usb/pl2303.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <drivers/usb/usb.h>
0019 #include <drivers/usb/uhci.h>
0020 #include <drivers/usb/pl2303.h>
0021 #include <arch/i386.h>
0022 #include <util/printf.h>
0023 #include <kernel.h>
0024
0025 #define DEBUG_PL2303
0026
0027 #ifdef DEBUG_PL2303
0028 #define DLOG(fmt,...) DLOG_PREFIX("pl2303",fmt,##__VA_ARGS__)
0029 #else
0030 #define DLOG(fmt,...) ;
0031 #endif
0032
0033 static USB_DEVICE_INFO pl2303_dev;
0034 static uint8_t in_ept = 0, out_ept = 0;
0035
0036 int usb_pl2303_write (unsigned char *, uint32_t);
0037 void usb_pl2303_putc (char);
0038 int usb_pl2303_read (unsigned char *, uint32_t);
0039 char usb_pl2303_getc (void);
0040
0041
0042 static int
0043 pl2303_set_control (USB_DEVICE_INFO * dev, uint8_t on)
0044 {
0045 USB_DEV_REQ req;
0046 uint8_t control = 0;
0047
0048 if (on)
0049 control |= (USB_PL2303_CONTROL_DTR | USB_PL2303_CONTROL_RTS);
0050 else
0051 control &= ~(USB_PL2303_CONTROL_DTR | USB_PL2303_CONTROL_RTS);
0052
0053 req.bmRequestType = 0x21;
0054 req.bRequest = USB_PL2303_SET_CONTROL;
0055 req.wValue = control;
0056 req.wIndex = 0;
0057 req.wLength = 0;
0058
0059 return usb_control_transfer (dev, (addr_t) & req,
0060 sizeof (USB_DEV_REQ), 0, 0);
0061 }
0062
0063 static PL2303_CONFIG
0064 pl2303_get_line (USB_DEVICE_INFO * dev)
0065 {
0066 USB_DEV_REQ req;
0067 PL2303_CONFIG data;
0068 memset (&data, 0, sizeof (PL2303_CONFIG));
0069
0070 req.bmRequestType = 0xA1;
0071 req.bRequest = USB_PL2303_GET_LINE;
0072 req.wValue = 0;
0073 req.wIndex = 0;
0074 req.wLength = 7;
0075
0076 if (usb_control_transfer (dev, (addr_t) & req, sizeof (USB_DEV_REQ),
0077 (addr_t) & data, req.wLength)) {
0078 DLOG ("pl2303_get_line failed!");
0079 memset (&data, 0, sizeof (PL2303_CONFIG));
0080 }
0081
0082 return data;
0083 }
0084
0085 static int
0086 pl2303_set_line (
0087 USB_DEVICE_INFO * dev,
0088 uint32_t baud,
0089 uint8_t bits,
0090 uint8_t parity,
0091 uint8_t stb)
0092 {
0093 USB_DEV_REQ req;
0094 PL2303_CONFIG data;
0095 memset (&data, 0, sizeof (PL2303_CONFIG));
0096
0097 data = pl2303_get_line (dev);
0098
0099 if (data.baud_rate) {
0100 DLOG ("Current baud rate: %d", data.baud_rate);
0101 DLOG ("Current Stop Bits (0=1,1=1.5,2=2): %d", data.stop_bits);
0102 DLOG ("Current Parity (0=none,1=odd,2=even,3=mark,4=space): %d",
0103 data.parity);
0104 DLOG ("Current Data Bits: %d", data.data_bits);
0105 }
0106
0107 data.baud_rate = baud;
0108 data.stop_bits = stb;
0109 data.parity = parity;
0110 data.data_bits = bits;
0111
0112 req.bmRequestType = 0x21;
0113 req.bRequest = USB_PL2303_SET_LINE;
0114 req.wValue = 0;
0115 req.wIndex = 0;
0116 req.wLength = 7;
0117
0118 return usb_control_transfer (dev, (addr_t) & req,
0119 sizeof (USB_DEV_REQ), (addr_t) & data, req.wLength);
0120 }
0121
0122 static bool
0123 pl2303_init (USB_DEVICE_INFO *dev, USB_CFG_DESC *cfg, USB_IF_DESC *ifd)
0124 {
0125 uint8_t tmp[70];
0126 int i = 0;
0127 USB_EPT_DESC *pl2303ept;
0128 PL2303_CONFIG conf;
0129 memset (&conf, 0, sizeof (PL2303_CONFIG));
0130
0131 pl2303_dev = *(dev);
0132 memset (tmp, 0, 70);
0133
0134
0135 DLOG ("Parsing PL2303 chip endpoints ...");
0136 usb_get_descriptor (dev, USB_TYPE_CFG_DESC, 0, 0, cfg->wTotalLength,
0137 (addr_t)tmp);
0138 for (i = 0; i < cfg->wTotalLength; i += pl2303ept->bLength) {
0139 pl2303ept = (USB_EPT_DESC *) (tmp + i);
0140 if ((pl2303ept->bDescriptorType == USB_TYPE_EPT_DESC) &&
0141 ((pl2303ept->bmAttributes & 0x3) == 0x2)) {
0142 DLOG ("Found Bulk Endpoint");
0143 switch (pl2303ept->bEndpointAddress & 0x80) {
0144 case 0x80 :
0145 in_ept = pl2303ept->bEndpointAddress & 0xF;
0146 DLOG ("IN Endpoint. Address is: 0x%X", in_ept);
0147 break;
0148
0149 case 0x00 :
0150 out_ept = pl2303ept->bEndpointAddress & 0xF;
0151 DLOG ("OUT Endpoint. Address is: 0x%X", out_ept);
0152 break;
0153
0154 default :
0155 break;
0156 }
0157 }
0158 }
0159
0160
0161 DLOG ("Configuring serial interface (38400, 8N1)...");
0162 if (pl2303_set_line (dev, 38400, 8, 0, 0)) {
0163 DLOG ("Serial interface configuration failed");
0164 return FALSE;
0165 }
0166
0167 DLOG ("Checking configuration ...");
0168 conf = pl2303_get_line (dev);
0169
0170 DLOG ("Current baud rate: %d", conf.baud_rate);
0171 DLOG ("Current Stop Bits (0=1,1=1.5,2=2): %d", conf.stop_bits);
0172 DLOG ("Current Parity (0=none,1=odd,2=even,3=mark,4=space): %d",
0173 conf.parity);
0174 DLOG ("Current Data Bits: %d", conf.data_bits);
0175
0176 #if 1
0177
0178 DLOG ("Setting flow control ...");
0179 if (pl2303_set_control (dev, 1)) {
0180 DLOG ("Setting flow control failed");
0181 return FALSE;
0182 }
0183 #endif
0184
0185 return TRUE;
0186 }
0187
0188 static void
0189 test ()
0190 {
0191 DLOG ("PL2303 Test\n");
0192 #if 1
0193 char c = 0;
0194 while (c != 0xD) {
0195 c = usb_pl2303_getc ();
0196 DLOG ("Got character : %c", c);
0197 usb_pl2303_putc (c);
0198 }
0199 #else
0200 usb_pl2303_putc ('Q');
0201 usb_pl2303_putc ('u');
0202 usb_pl2303_putc ('e');
0203 usb_pl2303_putc ('s');
0204 usb_pl2303_putc ('t');
0205 #endif
0206 }
0207
0208 static bool
0209 pl2303_probe (USB_DEVICE_INFO *dev, USB_CFG_DESC *cfg, USB_IF_DESC *ifd)
0210 {
0211 if (dev->devd.idVendor == 0x067B) {
0212 DLOG ("Prolific Technology, Inc. device is detected");
0213
0214 if (dev->devd.idProduct != 0x2303) {
0215 DLOG ("Device attached is not PL2303. Product ID is: 0x%X",
0216 dev->devd.idProduct);
0217 return FALSE;
0218 }
0219 } else {
0220 return FALSE;
0221 }
0222
0223 if (!pl2303_init(dev, cfg, ifd)) {
0224 DLOG("Initialization failed!");
0225 return FALSE;
0226 }
0227
0228 DLOG ("PL2303 Serial Converter configured");
0229
0230 test();
0231
0232 return TRUE;
0233 }
0234
0235 void
0236 usb_pl2303_putc (char c)
0237 {
0238 unsigned char buf[1];
0239 int count = 0;
0240
0241 buf[0] = c;
0242
0243 if ((count = usb_pl2303_write (buf, 1)) != 1)
0244 DLOG ("usb_pl2303_putc failed, %d bytes sent", count);
0245 else
0246 DLOG ("usb_pl2303_putc done, %d bytes sent", count);
0247 }
0248
0249 int
0250 usb_pl2303_write (unsigned char * buf, uint32_t len)
0251 {
0252 uint32_t act_len = 0;
0253 int status = 0;
0254
0255 if ((status = usb_bulk_transfer (&pl2303_dev, out_ept, (addr_t) buf,
0256 len, 64, DIR_OUT, &act_len)))
0257 DLOG ("Bulk write failed. Error Code: 0x%X", status);
0258
0259 return act_len;
0260 }
0261
0262 char
0263 usb_pl2303_getc (void)
0264 {
0265 unsigned char buf[3];
0266 int act_len = 0;
0267
0268 if ((act_len = usb_pl2303_read (buf, 1)) != 1) {
0269 DLOG ("usb_ftdi_read () failed. %d bytes returned.", act_len);
0270 return '\0';
0271 }
0272
0273 return buf[0];
0274 }
0275
0276 int
0277 usb_pl2303_read (unsigned char * buf, uint32_t len)
0278 {
0279 uint32_t act_len = 0;
0280 int status = 0;
0281
0282 if ((status = usb_bulk_transfer (&pl2303_dev, in_ept, (addr_t) buf,
0283 len, 64, DIR_IN, &act_len)))
0284 DLOG ("Bulk read failed. Error Code: 0x%X", status);
0285
0286 return act_len;
0287 }
0288
0289 static USB_DRIVER pl2303_driver = {
0290 .probe = pl2303_probe
0291 };
0292
0293 bool
0294 usb_pl2303_driver_init (void)
0295 {
0296 return usb_register_driver (&pl2303_driver);
0297 }
0298
0299 #include "module/header.h"
0300
0301 static const struct module_ops mod_ops = {
0302 .init = usb_pl2303_driver_init
0303 };
0304
0305 DEF_MODULE (usb___pl2303, "USB pl2303 serial port driver", &mod_ops, {"usb"});
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316