36
36
{ USB_DEVICE (0x2c42 , 0x1635 ) }, /* 8 port UART device */ \
37
37
{ USB_DEVICE (0x2c42 , 0x1636 ) } /* 12 port UART device */
38
38
39
+ #define F81534A_CTRL_ID \
40
+ { USB_DEVICE(0x2c42, 0x16f8) } /* Global control device */
41
+
39
42
static const struct usb_device_id f81232_id_table [] = {
40
43
F81232_ID ,
41
44
{ } /* Terminating entry */
@@ -46,9 +49,15 @@ static const struct usb_device_id f81534a_id_table[] = {
46
49
{ } /* Terminating entry */
47
50
};
48
51
52
+ static const struct usb_device_id f81534a_ctrl_id_table [] = {
53
+ F81534A_CTRL_ID ,
54
+ { } /* Terminating entry */
55
+ };
56
+
49
57
static const struct usb_device_id combined_id_table [] = {
50
58
F81232_ID ,
51
59
F81534A_SERIES_ID ,
60
+ F81534A_CTRL_ID ,
52
61
{ } /* Terminating entry */
53
62
};
54
63
MODULE_DEVICE_TABLE (usb , combined_id_table );
@@ -61,6 +70,7 @@ MODULE_DEVICE_TABLE(usb, combined_id_table);
61
70
#define F81232_REGISTER_REQUEST 0xa0
62
71
#define F81232_GET_REGISTER 0xc0
63
72
#define F81232_SET_REGISTER 0x40
73
+ #define F81534A_ACCESS_REG_RETRY 2
64
74
65
75
#define SERIAL_BASE_ADDRESS 0x0120
66
76
#define RECEIVE_BUFFER_REGISTER (0x00 + SERIAL_BASE_ADDRESS)
@@ -101,6 +111,8 @@ MODULE_DEVICE_TABLE(usb, combined_id_table);
101
111
#define F81534A_GPIO_MODE1_OUTPUT BIT(1)
102
112
#define F81534A_GPIO_MODE0_OUTPUT BIT(0)
103
113
114
+ #define F81534A_CTRL_CMD_ENABLE_PORT 0x116
115
+
104
116
struct f81232_private {
105
117
struct mutex lock ;
106
118
u8 modem_control ;
@@ -848,6 +860,93 @@ static void f81232_lsr_worker(struct work_struct *work)
848
860
dev_warn (& port -> dev , "read LSR failed: %d\n" , status );
849
861
}
850
862
863
+ static int f81534a_ctrl_set_register (struct usb_interface * intf , u16 reg ,
864
+ u16 size , void * val )
865
+ {
866
+ struct usb_device * dev = interface_to_usbdev (intf );
867
+ int retry = F81534A_ACCESS_REG_RETRY ;
868
+ int status ;
869
+ u8 * tmp ;
870
+
871
+ tmp = kmemdup (val , size , GFP_KERNEL );
872
+ if (!tmp )
873
+ return - ENOMEM ;
874
+
875
+ while (retry -- ) {
876
+ status = usb_control_msg (dev ,
877
+ usb_sndctrlpipe (dev , 0 ),
878
+ F81232_REGISTER_REQUEST ,
879
+ F81232_SET_REGISTER ,
880
+ reg ,
881
+ 0 ,
882
+ tmp ,
883
+ size ,
884
+ USB_CTRL_SET_TIMEOUT );
885
+ if (status < 0 ) {
886
+ status = usb_translate_errors (status );
887
+ if (status == - EIO )
888
+ continue ;
889
+ } else if (status != size ) {
890
+ /* Retry on short transfers */
891
+ status = - EIO ;
892
+ continue ;
893
+ } else {
894
+ status = 0 ;
895
+ }
896
+
897
+ break ;
898
+ }
899
+
900
+ if (status ) {
901
+ dev_err (& intf -> dev , "failed to set register 0x%x: %d\n" ,
902
+ reg , status );
903
+ }
904
+
905
+ kfree (tmp );
906
+ return status ;
907
+ }
908
+
909
+ static int f81534a_ctrl_enable_all_ports (struct usb_interface * intf , bool en )
910
+ {
911
+ unsigned char enable [2 ] = {0 };
912
+ int status ;
913
+
914
+ /*
915
+ * Enable all available serial ports, define as following:
916
+ * bit 15 : Reset behavior (when HUB got soft reset)
917
+ * 0: maintain all serial port enabled state.
918
+ * 1: disable all serial port.
919
+ * bit 0~11 : Serial port enable bit.
920
+ */
921
+ if (en ) {
922
+ enable [0 ] = 0xff ;
923
+ enable [1 ] = 0x8f ;
924
+ }
925
+
926
+ status = f81534a_ctrl_set_register (intf , F81534A_CTRL_CMD_ENABLE_PORT ,
927
+ sizeof (enable ), enable );
928
+ if (status )
929
+ dev_err (& intf -> dev , "failed to enable ports: %d\n" , status );
930
+
931
+ return status ;
932
+ }
933
+
934
+ static int f81534a_ctrl_probe (struct usb_interface * intf ,
935
+ const struct usb_device_id * id )
936
+ {
937
+ return f81534a_ctrl_enable_all_ports (intf , true);
938
+ }
939
+
940
+ static void f81534a_ctrl_disconnect (struct usb_interface * intf )
941
+ {
942
+ f81534a_ctrl_enable_all_ports (intf , false);
943
+ }
944
+
945
+ static int f81534a_ctrl_resume (struct usb_interface * intf )
946
+ {
947
+ return f81534a_ctrl_enable_all_ports (intf , true);
948
+ }
949
+
851
950
static int f81232_port_probe (struct usb_serial_port * port )
852
951
{
853
952
struct f81232_private * priv ;
@@ -975,7 +1074,41 @@ static struct usb_serial_driver * const serial_drivers[] = {
975
1074
NULL ,
976
1075
};
977
1076
978
- module_usb_serial_driver (serial_drivers , combined_id_table );
1077
+ static struct usb_driver f81534a_ctrl_driver = {
1078
+ .name = "f81534a_ctrl" ,
1079
+ .id_table = f81534a_ctrl_id_table ,
1080
+ .probe = f81534a_ctrl_probe ,
1081
+ .disconnect = f81534a_ctrl_disconnect ,
1082
+ .resume = f81534a_ctrl_resume ,
1083
+ };
1084
+
1085
+ static int __init f81232_init (void )
1086
+ {
1087
+ int status ;
1088
+
1089
+ status = usb_register_driver (& f81534a_ctrl_driver , THIS_MODULE ,
1090
+ KBUILD_MODNAME );
1091
+ if (status )
1092
+ return status ;
1093
+
1094
+ status = usb_serial_register_drivers (serial_drivers , KBUILD_MODNAME ,
1095
+ combined_id_table );
1096
+ if (status ) {
1097
+ usb_deregister (& f81534a_ctrl_driver );
1098
+ return status ;
1099
+ }
1100
+
1101
+ return 0 ;
1102
+ }
1103
+
1104
+ static void __exit f81232_exit (void )
1105
+ {
1106
+ usb_serial_deregister_drivers (serial_drivers );
1107
+ usb_deregister (& f81534a_ctrl_driver );
1108
+ }
1109
+
1110
+ module_init (f81232_init );
1111
+ module_exit (f81232_exit );
979
1112
980
1113
MODULE_DESCRIPTION ("Fintek F81232/532A/534A/535/536 USB to serial driver" );
981
1114
MODULE_AUTHOR (
"Greg Kroah-Hartman <[email protected] >" );
0 commit comments