aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclink_gt.c
diff options
context:
space:
mode:
authorPaul Fulghum <paulkf@microgate.com>2010-10-27 18:34:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-27 21:03:14 -0400
commit9807224f1dce5fb746ee33fb67ea2e38dafe3e9c (patch)
treed9a9bdb1ae4196dec24b9c98bdd753c7b72de4df /drivers/char/synclink_gt.c
parented77ed6112f2d4b650f4be7dbaf14e06e1d393a5 (diff)
drivers/char/synclink_gt.c: add extended sync feature
Add support for extended byte synchronous mode feature of hardware. Signed-off-by: Paul Fulghum <paulkf@microgate.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/synclink_gt.c')
-rw-r--r--drivers/char/synclink_gt.c111
1 files changed, 108 insertions, 3 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 9f7fc71474b4..d01fffeac951 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -301,6 +301,8 @@ struct slgt_info {
301 unsigned int rx_pio; 301 unsigned int rx_pio;
302 unsigned int if_mode; 302 unsigned int if_mode;
303 unsigned int base_clock; 303 unsigned int base_clock;
304 unsigned int xsync;
305 unsigned int xctrl;
304 306
305 /* device status */ 307 /* device status */
306 308
@@ -405,6 +407,8 @@ static MGSL_PARAMS default_params = {
405#define TDCSR 0x94 /* tx DMA control/status */ 407#define TDCSR 0x94 /* tx DMA control/status */
406#define RDDAR 0x98 /* rx DMA descriptor address */ 408#define RDDAR 0x98 /* rx DMA descriptor address */
407#define TDDAR 0x9c /* tx DMA descriptor address */ 409#define TDDAR 0x9c /* tx DMA descriptor address */
410#define XSR 0x40 /* extended sync pattern */
411#define XCR 0x44 /* extended control */
408 412
409#define RXIDLE BIT14 413#define RXIDLE BIT14
410#define RXBREAK BIT14 414#define RXBREAK BIT14
@@ -517,6 +521,10 @@ static int set_interface(struct slgt_info *info, int if_mode);
517static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); 521static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
518static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); 522static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
519static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); 523static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);
524static int get_xsync(struct slgt_info *info, int __user *if_mode);
525static int set_xsync(struct slgt_info *info, int if_mode);
526static int get_xctrl(struct slgt_info *info, int __user *if_mode);
527static int set_xctrl(struct slgt_info *info, int if_mode);
520 528
521/* 529/*
522 * driver functions 530 * driver functions
@@ -1056,6 +1064,14 @@ static int ioctl(struct tty_struct *tty, struct file *file,
1056 return get_gpio(info, argp); 1064 return get_gpio(info, argp);
1057 case MGSL_IOCWAITGPIO: 1065 case MGSL_IOCWAITGPIO:
1058 return wait_gpio(info, argp); 1066 return wait_gpio(info, argp);
1067 case MGSL_IOCGXSYNC:
1068 return get_xsync(info, argp);
1069 case MGSL_IOCSXSYNC:
1070 return set_xsync(info, (int)arg);
1071 case MGSL_IOCGXCTRL:
1072 return get_xctrl(info, argp);
1073 case MGSL_IOCSXCTRL:
1074 return set_xctrl(info, (int)arg);
1059 } 1075 }
1060 mutex_lock(&info->port.mutex); 1076 mutex_lock(&info->port.mutex);
1061 switch (cmd) { 1077 switch (cmd) {
@@ -1213,12 +1229,16 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file,
1213 case MGSL_IOCSGPIO: 1229 case MGSL_IOCSGPIO:
1214 case MGSL_IOCGGPIO: 1230 case MGSL_IOCGGPIO:
1215 case MGSL_IOCWAITGPIO: 1231 case MGSL_IOCWAITGPIO:
1232 case MGSL_IOCGXSYNC:
1233 case MGSL_IOCGXCTRL:
1216 case MGSL_IOCSTXIDLE: 1234 case MGSL_IOCSTXIDLE:
1217 case MGSL_IOCTXENABLE: 1235 case MGSL_IOCTXENABLE:
1218 case MGSL_IOCRXENABLE: 1236 case MGSL_IOCRXENABLE:
1219 case MGSL_IOCTXABORT: 1237 case MGSL_IOCTXABORT:
1220 case TIOCMIWAIT: 1238 case TIOCMIWAIT:
1221 case MGSL_IOCSIF: 1239 case MGSL_IOCSIF:
1240 case MGSL_IOCSXSYNC:
1241 case MGSL_IOCSXCTRL:
1222 rc = ioctl(tty, file, cmd, arg); 1242 rc = ioctl(tty, file, cmd, arg);
1223 break; 1243 break;
1224 } 1244 }
@@ -1961,6 +1981,7 @@ static void bh_handler(struct work_struct *work)
1961 case MGSL_MODE_RAW: 1981 case MGSL_MODE_RAW:
1962 case MGSL_MODE_MONOSYNC: 1982 case MGSL_MODE_MONOSYNC:
1963 case MGSL_MODE_BISYNC: 1983 case MGSL_MODE_BISYNC:
1984 case MGSL_MODE_XSYNC:
1964 while(rx_get_buf(info)); 1985 while(rx_get_buf(info));
1965 break; 1986 break;
1966 } 1987 }
@@ -2889,6 +2910,69 @@ static int set_interface(struct slgt_info *info, int if_mode)
2889 return 0; 2910 return 0;
2890} 2911}
2891 2912
2913static int get_xsync(struct slgt_info *info, int __user *xsync)
2914{
2915 DBGINFO(("%s get_xsync=%x\n", info->device_name, info->xsync));
2916 if (put_user(info->xsync, xsync))
2917 return -EFAULT;
2918 return 0;
2919}
2920
2921/*
2922 * set extended sync pattern (1 to 4 bytes) for extended sync mode
2923 *
2924 * sync pattern is contained in least significant bytes of value
2925 * most significant byte of sync pattern is oldest (1st sent/detected)
2926 */
2927static int set_xsync(struct slgt_info *info, int xsync)
2928{
2929 unsigned long flags;
2930
2931 DBGINFO(("%s set_xsync=%x)\n", info->device_name, xsync));
2932 spin_lock_irqsave(&info->lock, flags);
2933 info->xsync = xsync;
2934 wr_reg32(info, XSR, xsync);
2935 spin_unlock_irqrestore(&info->lock, flags);
2936 return 0;
2937}
2938
2939static int get_xctrl(struct slgt_info *info, int __user *xctrl)
2940{
2941 DBGINFO(("%s get_xctrl=%x\n", info->device_name, info->xctrl));
2942 if (put_user(info->xctrl, xctrl))
2943 return -EFAULT;
2944 return 0;
2945}
2946
2947/*
2948 * set extended control options
2949 *
2950 * xctrl[31:19] reserved, must be zero
2951 * xctrl[18:17] extended sync pattern length in bytes
2952 * 00 = 1 byte in xsr[7:0]
2953 * 01 = 2 bytes in xsr[15:0]
2954 * 10 = 3 bytes in xsr[23:0]
2955 * 11 = 4 bytes in xsr[31:0]
2956 * xctrl[16] 1 = enable terminal count, 0=disabled
2957 * xctrl[15:0] receive terminal count for fixed length packets
2958 * value is count minus one (0 = 1 byte packet)
2959 * when terminal count is reached, receiver
2960 * automatically returns to hunt mode and receive
2961 * FIFO contents are flushed to DMA buffers with
2962 * end of frame (EOF) status
2963 */
2964static int set_xctrl(struct slgt_info *info, int xctrl)
2965{
2966 unsigned long flags;
2967
2968 DBGINFO(("%s set_xctrl=%x)\n", info->device_name, xctrl));
2969 spin_lock_irqsave(&info->lock, flags);
2970 info->xctrl = xctrl;
2971 wr_reg32(info, XCR, xctrl);
2972 spin_unlock_irqrestore(&info->lock, flags);
2973 return 0;
2974}
2975
2892/* 2976/*
2893 * set general purpose IO pin state and direction 2977 * set general purpose IO pin state and direction
2894 * 2978 *
@@ -3768,7 +3852,9 @@ module_exit(slgt_exit);
3768#define CALC_REGADDR() \ 3852#define CALC_REGADDR() \
3769 unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ 3853 unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \
3770 if (addr >= 0x80) \ 3854 if (addr >= 0x80) \
3771 reg_addr += (info->port_num) * 32; 3855 reg_addr += (info->port_num) * 32; \
3856 else if (addr >= 0x40) \
3857 reg_addr += (info->port_num) * 16;
3772 3858
3773static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) 3859static __u8 rd_reg8(struct slgt_info *info, unsigned int addr)
3774{ 3860{
@@ -4187,7 +4273,13 @@ static void sync_mode(struct slgt_info *info)
4187 4273
4188 /* TCR (tx control) 4274 /* TCR (tx control)
4189 * 4275 *
4190 * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync 4276 * 15..13 mode
4277 * 000=HDLC/SDLC
4278 * 001=raw bit synchronous
4279 * 010=asynchronous/isochronous
4280 * 011=monosync byte synchronous
4281 * 100=bisync byte synchronous
4282 * 101=xsync byte synchronous
4191 * 12..10 encoding 4283 * 12..10 encoding
4192 * 09 CRC enable 4284 * 09 CRC enable
4193 * 08 CRC32 4285 * 08 CRC32
@@ -4202,6 +4294,9 @@ static void sync_mode(struct slgt_info *info)
4202 val = BIT2; 4294 val = BIT2;
4203 4295
4204 switch(info->params.mode) { 4296 switch(info->params.mode) {
4297 case MGSL_MODE_XSYNC:
4298 val |= BIT15 + BIT13;
4299 break;
4205 case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; 4300 case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
4206 case MGSL_MODE_BISYNC: val |= BIT15; break; 4301 case MGSL_MODE_BISYNC: val |= BIT15; break;
4207 case MGSL_MODE_RAW: val |= BIT13; break; 4302 case MGSL_MODE_RAW: val |= BIT13; break;
@@ -4256,7 +4351,13 @@ static void sync_mode(struct slgt_info *info)
4256 4351
4257 /* RCR (rx control) 4352 /* RCR (rx control)
4258 * 4353 *
4259 * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync 4354 * 15..13 mode
4355 * 000=HDLC/SDLC
4356 * 001=raw bit synchronous
4357 * 010=asynchronous/isochronous
4358 * 011=monosync byte synchronous
4359 * 100=bisync byte synchronous
4360 * 101=xsync byte synchronous
4260 * 12..10 encoding 4361 * 12..10 encoding
4261 * 09 CRC enable 4362 * 09 CRC enable
4262 * 08 CRC32 4363 * 08 CRC32
@@ -4268,6 +4369,9 @@ static void sync_mode(struct slgt_info *info)
4268 val = 0; 4369 val = 0;
4269 4370
4270 switch(info->params.mode) { 4371 switch(info->params.mode) {
4372 case MGSL_MODE_XSYNC:
4373 val |= BIT15 + BIT13;
4374 break;
4271 case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; 4375 case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;
4272 case MGSL_MODE_BISYNC: val |= BIT15; break; 4376 case MGSL_MODE_BISYNC: val |= BIT15; break;
4273 case MGSL_MODE_RAW: val |= BIT13; break; 4377 case MGSL_MODE_RAW: val |= BIT13; break;
@@ -4684,6 +4788,7 @@ static bool rx_get_buf(struct slgt_info *info)
4684 switch(info->params.mode) { 4788 switch(info->params.mode) {
4685 case MGSL_MODE_MONOSYNC: 4789 case MGSL_MODE_MONOSYNC:
4686 case MGSL_MODE_BISYNC: 4790 case MGSL_MODE_BISYNC:
4791 case MGSL_MODE_XSYNC:
4687 /* ignore residue in byte synchronous modes */ 4792 /* ignore residue in byte synchronous modes */
4688 if (desc_residue(info->rbufs[i])) 4793 if (desc_residue(info->rbufs[i]))
4689 count--; 4794 count--;