diff mbox

[X/Y/Z,2/2] UBUNTU: SAUCE: xr-usb-serial: interface for switching modes

Message ID 1480411435-2427-3-git-send-email-jesse.sung@canonical.com
State New
Headers show

Commit Message

Wen-chien Jesse Sung Nov. 29, 2016, 9:23 a.m. UTC
From: Darren Wu <darren.wu@canonical.com>

BugLink: https://launchpad.net/bugs/1645591

Add an interface for mode switching between RS232 and RS422/485.

Signed-off-by: Darren Wu <darren.wu@canonical.com>
Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com>
---
 ubuntu/xr-usb-serial/xr_usb_serial_common.c | 55 +++++++++++++++++++++++++++--
 ubuntu/xr-usb-serial/xr_usb_serial_common.h |  1 +
 ubuntu/xr-usb-serial/xr_usb_serial_hal.c    | 23 +++++++++---
 3 files changed, 71 insertions(+), 8 deletions(-)
diff mbox

Patch

diff --git a/ubuntu/xr-usb-serial/xr_usb_serial_common.c b/ubuntu/xr-usb-serial/xr_usb_serial_common.c
index e53839c..cae45c2 100644
--- a/ubuntu/xr-usb-serial/xr_usb_serial_common.c
+++ b/ubuntu/xr-usb-serial/xr_usb_serial_common.c
@@ -251,6 +251,45 @@  static ssize_t show_country_rel_date
 }
 
 static DEVICE_ATTR(iCountryCodeRelDate, S_IRUGO, show_country_rel_date, NULL);
+
+static ssize_t set_rs485_422_en(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct xr_usb_serial *xr_usb_serial = usb_get_intfdata(intf);
+	int error, value = 0;
+
+	error = kstrtoint(buf, 0, &value);
+	if (error)
+		return error;
+
+	if (value == 0) {
+		xr_usb_serial->rs485_422_en = false;
+	} else if (value == 1) {
+		// RS485,RS422 HD/FD mode
+		xr_usb_serial->rs485_422_en = true;
+	}
+
+	return count;
+}
+
+static ssize_t show_rs485_422_en
+    (struct device *dev, struct device_attribute *attr, char *buf) {
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct xr_usb_serial *xr_usb_serial = usb_get_intfdata(intf);
+
+	if (xr_usb_serial->rs485_422_en == false) {
+		return sprintf(buf, "0");
+	} else if (xr_usb_serial->rs485_422_en == true) {
+		// RS485,RS422 HD/FD mode
+		return sprintf(buf, "1");
+	}
+	return 0;
+}
+
+static DEVICE_ATTR(bRS485_422_en, 0644, show_rs485_422_en, set_rs485_422_en);
+
 /*
  * Interrupt handlers for various XR_USB_SERIAL device responses
  */
@@ -1448,10 +1487,15 @@  made_compressed_probe:
 
 	usb_set_intfdata(intf, xr_usb_serial);
 
-	i = device_create_file(&intf->dev, &dev_attr_bmCapabilities);
+	xr_usb_serial->rs485_422_en = false;	//default enable rs232
+	i = device_create_file(&intf->dev, &dev_attr_bRS485_422_en);
 	if (i < 0)
 		goto alloc_fail7;
 
+	i = device_create_file(&intf->dev, &dev_attr_bmCapabilities);
+	if (i < 0)
+		goto alloc_fail8;
+
 	if (cfd) {		/* export the country data */
 		xr_usb_serial->country_codes =
 		    kmalloc(cfd->bLength - 4, GFP_KERNEL);
@@ -1517,12 +1561,12 @@  skip_countries:
 				     &control_interface->dev);
 	if (IS_ERR(tty_dev)) {
 		rv = PTR_ERR(tty_dev);
-		goto alloc_fail8;
+		goto alloc_fail9;
 	}
 #endif
 
 	return 0;
-alloc_fail8:
+alloc_fail9:
 	if (xr_usb_serial->country_codes) {
 		device_remove_file(&xr_usb_serial->control->dev,
 				   &dev_attr_wCountryCodes);
@@ -1531,6 +1575,9 @@  alloc_fail8:
 	}
 	device_remove_file(&xr_usb_serial->control->dev,
 			   &dev_attr_bmCapabilities);
+alloc_fail8:
+	device_remove_file(&xr_usb_serial->control->dev,
+			   &dev_attr_bRS485_422_en);
 alloc_fail7:
 	usb_set_intfdata(intf, NULL);
 	for (i = 0; i < XR_USB_SERIAL_NW; i++)
@@ -1590,6 +1637,8 @@  static void xr_usb_serial_disconnect(struct usb_interface *intf)
 	}
 	device_remove_file(&xr_usb_serial->control->dev,
 			   &dev_attr_bmCapabilities);
+	device_remove_file(&xr_usb_serial->control->dev,
+			   &dev_attr_bRS485_422_en);
 	usb_set_intfdata(xr_usb_serial->control, NULL);
 	usb_set_intfdata(xr_usb_serial->data, NULL);
 	mutex_unlock(&xr_usb_serial->mutex);
diff --git a/ubuntu/xr-usb-serial/xr_usb_serial_common.h b/ubuntu/xr-usb-serial/xr_usb_serial_common.h
index 207f8d0..841a81d 100644
--- a/ubuntu/xr-usb-serial/xr_usb_serial_common.h
+++ b/ubuntu/xr-usb-serial/xr_usb_serial_common.h
@@ -147,6 +147,7 @@  struct xr_usb_serial {
 	unsigned short DeviceVendor;
 	unsigned short DeviceProduct;
 	struct reg_addr_map reg_map;
+	bool rs485_422_en;
 };
 
 #define CDC_DATA_INTERFACE_TYPE	0x0a
diff --git a/ubuntu/xr-usb-serial/xr_usb_serial_hal.c b/ubuntu/xr-usb-serial/xr_usb_serial_hal.c
index 8ec1c79..2aa3ded 100644
--- a/ubuntu/xr-usb-serial/xr_usb_serial_hal.c
+++ b/ubuntu/xr-usb-serial/xr_usb_serial_hal.c
@@ -479,11 +479,24 @@  int xr_usb_serial_set_flow_mode(struct xr_usb_serial *xr_usb_serial,
 		flow = UART_FLOW_MODE_NONE;
 		gpio_mode = UART_GPIO_MODE_SEL_GPIO;
 	}
-	xr_usb_serial_set_reg(xr_usb_serial,
-			      xr_usb_serial->reg_map.uart_flow_addr, flow);
-	xr_usb_serial_set_reg(xr_usb_serial,
-			      xr_usb_serial->reg_map.uart_gpio_mode_addr,
-			      gpio_mode);
+
+	// rs485,rs422 FD/HD mode
+	if (xr_usb_serial->rs485_422_en) {
+		xr_usb_serial_set_reg(xr_usb_serial,
+				      xr_usb_serial->reg_map.uart_flow_addr,
+				      0x00);
+		xr_usb_serial_set_reg(xr_usb_serial,
+				      xr_usb_serial->reg_map.
+				      uart_gpio_mode_addr, 0x0B);
+	} else			//rs232, default mode
+	{
+		xr_usb_serial_set_reg(xr_usb_serial,
+				      xr_usb_serial->reg_map.uart_flow_addr,
+				      flow);
+		xr_usb_serial_set_reg(xr_usb_serial,
+				      xr_usb_serial->reg_map.
+				      uart_gpio_mode_addr, gpio_mode);
+	}
 	return 0;
 
 }