#define F81232_REGISTER_REQUEST 0xa0
#define F81232_GET_REGISTER 0xc0
#define F81232_SET_REGISTER 0x40
-#define F81534A_ACCESS_REG_RETRY 2
#define SERIAL_BASE_ADDRESS 0x0120
#define RECEIVE_BUFFER_REGISTER (0x00 + SERIAL_BASE_ADDRESS)
static int f81534a_ctrl_set_register(struct usb_interface *intf, u16 reg,
u16 size, void *val)
{
- struct usb_device *dev = interface_to_usbdev(intf);
- int retry = F81534A_ACCESS_REG_RETRY;
- int status;
-
- while (retry--) {
- status = usb_control_msg_send(dev,
- 0,
- F81232_REGISTER_REQUEST,
- F81232_SET_REGISTER,
- reg,
- 0,
- val,
- size,
- USB_CTRL_SET_TIMEOUT,
- GFP_KERNEL);
- if (status) {
- status = usb_translate_errors(status);
- if (status == -EIO)
- continue;
- }
-
- break;
- }
-
- if (status) {
- dev_err(&intf->dev, "failed to set register 0x%x: %d\n",
- reg, status);
- }
+ return usb_control_msg_send(interface_to_usbdev(intf),
+ 0,
+ F81232_REGISTER_REQUEST,
+ F81232_SET_REGISTER,
+ reg,
+ 0,
+ val,
+ size,
+ USB_CTRL_SET_TIMEOUT,
+ GFP_KERNEL);
+}
- return status;
+static int f81534a_ctrl_get_register(struct usb_interface *intf, u16 reg,
+ u16 size, void *val)
+{
+ return usb_control_msg_recv(interface_to_usbdev(intf),
+ 0,
+ F81232_REGISTER_REQUEST,
+ F81232_GET_REGISTER,
+ reg,
+ 0,
+ val,
+ size,
+ USB_CTRL_GET_TIMEOUT,
+ GFP_KERNEL);
}
static int f81534a_ctrl_enable_all_ports(struct usb_interface *intf, bool en)
* bit 0~11 : Serial port enable bit.
*/
if (en) {
+ /*
+ * The Fintek F81532A/534A/535/536 family relies on the
+ * F81534A_CTRL_CMD_ENABLE_PORT (116h) register during
+ * initialization to both determine serial port status and
+ * control port creation.
+ *
+ * If the driver experiences fast load/unload cycles, the
+ * device state may becomes unstable, resulting in the
+ * incomplete generation of serial ports.
+ *
+ * Performing a dummy read operation on the register prior
+ * to the initial write command resolves the issue.
+ *
+ * This clears the device's stale internal state. Subsequent
+ * write operations will correctly generate all serial ports.
+ */
+ status = f81534a_ctrl_get_register(intf,
+ F81534A_CTRL_CMD_ENABLE_PORT,
+ sizeof(enable),
+ enable);
+ if (status)
+ return status;
+
enable[0] = 0xff;
enable[1] = 0x8f;
}