summaryrefslogtreecommitdiff
path: root/recipes-kernel/vizzini/vizzini-1.1/vizzini-1.1-rs485.patch
blob: 6833e5b92a36e33b32f8a15d40828fc89d44c24a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
Index: xr21v141x-lnx3.10-3.11/vizzini.c
===================================================================
--- xr21v141x-lnx3.10-3.11.orig/vizzini.c	2014-05-02 12:20:07.972225646 -0500
+++ xr21v141x-lnx3.10-3.11/vizzini.c	2014-05-07 13:53:08.125405483 -0500
@@ -892,6 +892,35 @@
         dev_dbg(&xr21v141x->control->dev, "vz_test_mode: selector=0x%02x\n", selector);
         return retval < 0 ? retval : 0;
 }
+static int xr21v141x_set_rs485(struct xr21v141x *xr21v141x, struct serial_rs485 *rs485conf) {
+	int block = xr21v141x->block;
+	int result = 0;
+	unsigned int gpio_mode, flow = 0;
+
+	xr21v141x->rs485 = *rs485conf;
+
+	if (xr21v141x->rs485.flags & SER_RS485_ENABLED) {
+		dev_info(&xr21v141x->control->dev, "Enabling RS485");
+
+		/* enable auto tranceiver enable on transmit, TX active high */
+		gpio_mode = UART_GPIO_MODE_SEL_XCVR_EN_ACT | UART_GPIO_MODE_XCVR_EN_POL;
+		result = vizzini_set_reg(xr21v141x, block, UART_GPIO_MODE, gpio_mode);
+		if (result < 0)
+			dev_err(&xr21v141x->control->dev, "Error setting auto trans enable");
+
+		/* half duplex rs485 */
+		flow = UART_FLOW_HALF_DUPLEX;
+		result = vizzini_set_reg(xr21v141x, block, UART_FLOW, flow);
+		if (result < 0)
+			dev_err(&xr21v141x->control->dev, "Error setting half duplex");
+	} else {
+		dev_info(&xr21v141x->control->dev, "Disabling RS485 - flow control off");
+		vizzini_set_reg(xr21v141x, block, UART_GPIO_MODE, UART_GPIO_MODE_SEL_GPIO);
+		vizzini_set_reg(xr21v141x, block, UART_FLOW, UART_FLOW_MODE_NONE);
+	}
+
+	return 0;
+}
 
 static int xr21v141x_tty_ioctl(struct tty_struct *tty,
 					unsigned int cmd, unsigned long arg)
@@ -902,6 +931,8 @@
 	unsigned int  block, reg, val, match, preciseflags, unicast, broadcast, flow, selector;
         char	*data;
 
+	struct serial_rs485 rs485conf;
+
 	switch (cmd) {
 	case TIOCGSERIAL: /* gets serial port data */
 		rv = get_serial_info(xr21v141x, (struct serial_struct __user *) arg);
@@ -910,6 +941,39 @@
 		rv = set_serial_info(xr21v141x, (struct serial_struct __user *) arg);
 		break;
 
+	case TIOCGRS485:
+		if (! arg) {
+			dev_err(&xr21v141x->control->dev, "%s - TIOCGRS485 arg invalid\n", __func__);
+			rv = -EFAULT;
+			break;
+		}
+
+		if (copy_to_user((struct serial_rs485 *) arg, &(xr21v141x->rs485), sizeof(struct serial_rs485))) {
+			dev_err(&xr21v141x->control->dev, "%s - TIOCGRS485 copy_to_user fail\n", __func__);
+			rv = -EFAULT;
+			break;
+		}
+		rv = 0;
+		break;
+
+	case TIOCSRS485:
+		if (! arg) {
+			dev_err(&xr21v141x->control->dev, "%s - TIOCSRS485 arg invalid\n", __func__);
+			rv = -EFAULT;
+			break;
+		}
+
+		if (copy_from_user(&rs485conf, (struct serial_rs485 *) arg, sizeof(rs485conf))) {
+			dev_err(&xr21v141x->control->dev, "%s - TIOCSRS485 copy_from_user failed\n", __func__);
+			rv = -EFAULT;
+			break;
+		}
+
+		vizzini_disable(xr21v141x);
+		rv = xr21v141x_set_rs485(xr21v141x, &rs485conf);
+		vizzini_enable(xr21v141x);
+		break;
+
         case VZIOC_GET_REG:
                 if (get_user(block, (int __user *)arg))
                         return -EFAULT;
Index: xr21v141x-lnx3.10-3.11/vizzini.h
===================================================================
--- xr21v141x-lnx3.10-3.11.orig/vizzini.h	2014-04-04 19:59:33.000000000 -0500
+++ xr21v141x-lnx3.10-3.11/vizzini.h	2014-05-02 12:20:08.028225647 -0500
@@ -282,7 +282,7 @@
 #ifdef VIZZINI_IWA
         int           iwa;
 #endif
-
+	struct serial_rs485 rs485;
 };
 
 #define CDC_DATA_INTERFACE_TYPE	0x0a