This should support KLSI KL5KUSB105D based adapters, like that usb-to-serial Palm (for use with serial craddle) I got here.
If I understood the linux driver correctly it should work but it seems I didn't yet :) For now it only lights the Terminal Ready light on my modem, doesn't get any data sent. Is it me or the semantics with the on_write() hook is broken ? (it's made to add headers/footers to buffers, but then header size is counted as written data, while it's not data as sent to the driver...) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21522 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -12,6 +12,7 @@ KernelAddon usb_serial :
|
|||||||
acm.c
|
acm.c
|
||||||
prolific.c
|
prolific.c
|
||||||
ftdi.c
|
ftdi.c
|
||||||
|
klsi.c
|
||||||
;
|
;
|
||||||
|
|
||||||
AddResources usb_serial : usb_serial.rdef ;
|
AddResources usb_serial : usb_serial.rdef ;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "acm.h"
|
#include "acm.h"
|
||||||
#include "prolific.h"
|
#include "prolific.h"
|
||||||
#include "ftdi.h"
|
#include "ftdi.h"
|
||||||
|
#include "klsi.h"
|
||||||
|
|
||||||
/* driver callbacks forward declarations */
|
/* driver callbacks forward declarations */
|
||||||
static status_t usb_serial_open (const char *name, uint32 flags, void** cookie);
|
static status_t usb_serial_open (const char *name, uint32 flags, void** cookie);
|
||||||
@@ -132,6 +133,18 @@ usb_serial_hw usb_serial_hw_devices[] = {
|
|||||||
set_line_coding_ftdi, set_control_line_state_ftdi,
|
set_line_coding_ftdi, set_control_line_state_ftdi,
|
||||||
on_read_ftdi, on_write_ftdi, on_close_ftdi,
|
on_read_ftdi, on_write_ftdi, on_close_ftdi,
|
||||||
"FTDI 8U232AM serial converter"},
|
"FTDI 8U232AM serial converter"},
|
||||||
|
|
||||||
|
{VND_PALM, PROD_PALM_CONNECT,
|
||||||
|
add_klsi_device, reset_klsi_device,
|
||||||
|
set_line_coding_klsi, set_control_line_state_klsi,
|
||||||
|
on_read_klsi, on_write_klsi, on_close_klsi,
|
||||||
|
"PalmConnect RS232"},
|
||||||
|
{VND_KLSI, PROD_KLSI_KL5KUSB105D,
|
||||||
|
add_klsi_device, reset_klsi_device,
|
||||||
|
set_line_coding_klsi, set_control_line_state_klsi,
|
||||||
|
on_read_klsi, on_write_klsi, on_close_klsi,
|
||||||
|
"KLSI KL5KUSB105D"},
|
||||||
|
|
||||||
};
|
};
|
||||||
/* supported devices*/
|
/* supported devices*/
|
||||||
usb_support_descriptor *supported_devices;
|
usb_support_descriptor *supported_devices;
|
||||||
|
|||||||
@@ -144,6 +144,8 @@ struct _s_usb_serial_device{
|
|||||||
uint8 status_msr;
|
uint8 status_msr;
|
||||||
uint8 status_lsr;
|
uint8 status_lsr;
|
||||||
}ftdi;
|
}ftdi;
|
||||||
|
struct _spec_klsi{ /* KLSI/PalmConnect */
|
||||||
|
}klsi;
|
||||||
}spec;
|
}spec;
|
||||||
}; /*already typedef-ed - see comment above! */
|
}; /*already typedef-ed - see comment above! */
|
||||||
/* high-level of abstraction of the device*/
|
/* high-level of abstraction of the device*/
|
||||||
|
|||||||
@@ -0,0 +1,173 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003 by Siarzhuk Zharski <imker@gmx.li>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ByteOrder.h>
|
||||||
|
#include <KernelExport.h>
|
||||||
|
#include <Drivers.h>
|
||||||
|
#include <USB.h>
|
||||||
|
#include <ttylayer.h>
|
||||||
|
|
||||||
|
#include "driver.h"
|
||||||
|
#include "klsi.h"
|
||||||
|
|
||||||
|
status_t add_klsi_device(usb_serial_device *usd,
|
||||||
|
const usb_configuration_info *uci)
|
||||||
|
{
|
||||||
|
struct usb_endpoint_info *comm_epi = NULL;
|
||||||
|
struct usb_endpoint_info *data_out_epi = NULL;
|
||||||
|
struct usb_endpoint_info *data_in_epi = NULL;
|
||||||
|
const usb_device_descriptor *ddesc;
|
||||||
|
status_t status = ENODEV;
|
||||||
|
uint32 i = 0;
|
||||||
|
|
||||||
|
TRACE_FUNCALLS("> add_klsi_device(%08x, %08x)\n", usd, uci);
|
||||||
|
|
||||||
|
if(uci->interface_count){
|
||||||
|
struct usb_interface_info *uii = uci->interface[0].active;
|
||||||
|
for(i = 0; i < uii->endpoint_count; i++){
|
||||||
|
if(uii->endpoint[i].descr->attributes == USB_EP_ATTR_INTERRUPT){
|
||||||
|
if((uii->endpoint[i].descr->endpoint_address & USB_EP_ADDR_DIR_IN)
|
||||||
|
== USB_EP_ADDR_DIR_IN /*USB_EP_ADDR_DIR_OUT = 0x0*/){
|
||||||
|
TRACE("add_klsi_device:comm endpoint at %d\n", i);
|
||||||
|
comm_epi = &uii->endpoint[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < uii->endpoint_count; i++){
|
||||||
|
if(uii->endpoint[i].descr->attributes == USB_EP_ATTR_BULK){
|
||||||
|
if((uii->endpoint[i].descr->endpoint_address & USB_EP_ADDR_DIR_IN)
|
||||||
|
== USB_EP_ADDR_DIR_IN){
|
||||||
|
TRACE("add_klsi_device:in endpoint at %d\n", i);
|
||||||
|
data_in_epi = &uii->endpoint[i];
|
||||||
|
// usd->read_buffer_size = uii->endpoint[i].descr->max_packet_size;
|
||||||
|
}else{
|
||||||
|
if((uii->endpoint[i].descr->endpoint_address & USB_EP_ADDR_DIR_IN)
|
||||||
|
== USB_EP_ADDR_DIR_OUT){
|
||||||
|
TRACE("add_klsi_device:out endpoint at %d\n", i);
|
||||||
|
data_out_epi = &uii->endpoint[i];
|
||||||
|
// usd->write_buffer_size = uii->endpoint[i].descr->max_packet_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(comm_epi && data_in_epi && data_out_epi){
|
||||||
|
usd->read_buffer_size =
|
||||||
|
usd->write_buffer_size =
|
||||||
|
usd->interrupt_buffer_size = ROUNDUP(KLSI_BUF_SIZE, 16);
|
||||||
|
status = add_device(usd, uci, comm_epi, data_out_epi, data_in_epi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE_FUNCRET("< add_klsi_device returns:%08x\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t reset_klsi_device(usb_serial_device *usd){
|
||||||
|
status_t status;
|
||||||
|
size_t len = 0;
|
||||||
|
TRACE_FUNCALLS("> reset_klsi_device(%08x)\n", usd);
|
||||||
|
|
||||||
|
status = (*usb_m->send_request)(usd->dev,
|
||||||
|
USB_REQTYPE_VENDOR | USB_REQTYPE_INTERFACE_OUT,
|
||||||
|
KLSI_CONF_REQUEST,
|
||||||
|
KLSI_CONF_REQUEST_READ_ON, 0, 0,
|
||||||
|
0, 0, &len);
|
||||||
|
TRACE_FUNCRET("< reset_klsi_device returns:%08x\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t set_line_coding_klsi(usb_serial_device *usd,
|
||||||
|
usb_serial_line_coding *line_coding){
|
||||||
|
status_t status = B_OK;
|
||||||
|
uint8 rate;
|
||||||
|
size_t len1 = 0, len2 = 0;
|
||||||
|
uint8 coding_packet[5];
|
||||||
|
TRACE_FUNCALLS("> set_line_coding_klsi(%08x, {%d, %02x, %02x, %02x})\n",
|
||||||
|
usd, line_coding->speed,
|
||||||
|
line_coding->stopbits,
|
||||||
|
line_coding->parity,
|
||||||
|
line_coding->databits);
|
||||||
|
|
||||||
|
coding_packet[0] = 5; /* size */
|
||||||
|
switch (line_coding->speed){
|
||||||
|
case 300: rate = klsi_sio_b300; break;
|
||||||
|
case 600: rate = klsi_sio_b600; break;
|
||||||
|
case 1200: rate = klsi_sio_b1200; break;
|
||||||
|
case 2400: rate = klsi_sio_b2400; break;
|
||||||
|
case 4800: rate = klsi_sio_b4800; break;
|
||||||
|
case 9600: rate = klsi_sio_b9600; break;
|
||||||
|
case 19200: rate = klsi_sio_b19200; break;
|
||||||
|
case 38400: rate = klsi_sio_b38400; break;
|
||||||
|
case 57600: rate = klsi_sio_b57600; break;
|
||||||
|
case 115200: rate = klsi_sio_b115200; break;
|
||||||
|
default:
|
||||||
|
rate = klsi_sio_b19200;
|
||||||
|
TRACE_ALWAYS("= set_line_coding_klsi: Datarate:%d is not supported "
|
||||||
|
"by this hardware. Defaulted to %d\n",
|
||||||
|
line_coding->speed, rate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
coding_packet[1] = rate;
|
||||||
|
/* only 7,8 */
|
||||||
|
coding_packet[2] = line_coding->databits;
|
||||||
|
/* unknown */
|
||||||
|
coding_packet[3] = 0;
|
||||||
|
coding_packet[4] = 1;
|
||||||
|
|
||||||
|
status = (*usb_m->send_request)(usd->dev,
|
||||||
|
USB_REQTYPE_VENDOR | USB_REQTYPE_INTERFACE_OUT,
|
||||||
|
KLSI_SET_REQUEST, 0, 0, 0,
|
||||||
|
coding_packet, sizeof(coding_packet), &len1);
|
||||||
|
if(status != B_OK)
|
||||||
|
TRACE_ALWAYS("= set_line_coding_ftdi: datarate set request failed:%08x",
|
||||||
|
status);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t set_control_line_state_klsi(usb_serial_device *usd, uint16 state){
|
||||||
|
status_t status = B_OK;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void on_read_klsi(usb_serial_device *usd, char **buf, size_t *num_bytes){
|
||||||
|
size_t num;
|
||||||
|
if (*num_bytes <= 2) {
|
||||||
|
*num_bytes = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
num = B_LENDIAN_TO_HOST_INT16(*(uint16*)(*buf));
|
||||||
|
*num_bytes = MIN(num, (*num_bytes - 2));
|
||||||
|
*buf += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_write_klsi(usb_serial_device *usd, const char *buf, size_t *num_bytes){
|
||||||
|
if(*num_bytes > usd->write_buffer_size)
|
||||||
|
*num_bytes = usd->write_buffer_size;
|
||||||
|
if(*num_bytes > 62)
|
||||||
|
*num_bytes = 62;
|
||||||
|
*num_bytes = 6;
|
||||||
|
*((uint16*)usd->write_buffer) = B_HOST_TO_LENDIAN_INT16(*num_bytes);
|
||||||
|
memcpy(usd->write_buffer+2, buf, *num_bytes);
|
||||||
|
memcpy(usd->write_buffer+2, "ATDT0\n", 6);
|
||||||
|
*num_bytes = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_close_klsi(usb_serial_device *usd){
|
||||||
|
status_t status;
|
||||||
|
size_t len = 0;
|
||||||
|
TRACE_FUNCALLS("> on_close_klsi(%08x)\n", usd);
|
||||||
|
status = (*usb_m->send_request)(usd->dev,
|
||||||
|
USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
|
||||||
|
KLSI_CONF_REQUEST,
|
||||||
|
KLSI_CONF_REQUEST_READ_OFF, 0, 0,
|
||||||
|
0, 0, &len);
|
||||||
|
(*usb_m->cancel_queued_transfers)(usd->pipe_read);
|
||||||
|
(*usb_m->cancel_queued_transfers)(usd->pipe_write);
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2004 by Siarzhuk Zharski <imker@gmx.li>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _USB_KLSI_H_
|
||||||
|
#define _USB_KLSI_H_
|
||||||
|
|
||||||
|
#define VND_PALM 0x0830
|
||||||
|
#define VND_KLSI 0x05e9
|
||||||
|
|
||||||
|
#define PROD_PALM_CONNECT 0x0080
|
||||||
|
#define PROD_KLSI_KL5KUSB105D 0x00c0
|
||||||
|
|
||||||
|
#define KLSI_SET_REQUEST 0x01
|
||||||
|
#define KLSI_POLL_REQUEST 0x02
|
||||||
|
#define KLSI_CONF_REQUEST 0x03
|
||||||
|
#define KLSI_CONF_REQUEST_READ_ON 0x03
|
||||||
|
#define KLSI_CONF_REQUEST_READ_OFF 0x02
|
||||||
|
|
||||||
|
// not sure
|
||||||
|
#define KLSI_BUF_SIZE 64
|
||||||
|
|
||||||
|
enum {
|
||||||
|
klsi_sio_b115200 = 0,
|
||||||
|
klsi_sio_b57600 = 1,
|
||||||
|
klsi_sio_b38400 = 2,
|
||||||
|
klsi_sio_b19200 = 4,
|
||||||
|
klsi_sio_b9600 = 6,
|
||||||
|
/* unchecked */
|
||||||
|
klsi_sio_b4800 = 8,
|
||||||
|
klsi_sio_b2400 = 9,
|
||||||
|
klsi_sio_b1200 = 10,
|
||||||
|
klsi_sio_b600 = 11,
|
||||||
|
klsi_sio_b300 = 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
status_t add_klsi_device(usb_serial_device *usd,
|
||||||
|
const usb_configuration_info *uci);
|
||||||
|
status_t reset_klsi_device(usb_serial_device *usd);
|
||||||
|
status_t set_line_coding_klsi(usb_serial_device *usd,
|
||||||
|
usb_serial_line_coding *line_coding);
|
||||||
|
|
||||||
|
status_t set_control_line_state_klsi(usb_serial_device *usd, uint16 state);
|
||||||
|
void on_read_klsi(usb_serial_device *usd, char **buf, size_t *num_bytes);
|
||||||
|
void on_write_klsi(usb_serial_device *usd, const char *buf, size_t *num_bytes);
|
||||||
|
void on_close_klsi(usb_serial_device *usd);
|
||||||
|
|
||||||
|
#endif //_USB_PROLIFIC_H_
|
||||||
Reference in New Issue
Block a user