diff options
author | Paul Fulghum <paulkf@microgate.com> | 2010-10-27 18:34:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 21:03:14 -0400 |
commit | 9807224f1dce5fb746ee33fb67ea2e38dafe3e9c (patch) | |
tree | d9a9bdb1ae4196dec24b9c98bdd753c7b72de4df /drivers/char/synclink_gt.c | |
parent | ed77ed6112f2d4b650f4be7dbaf14e06e1d393a5 (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.c | 111 |
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); | |||
517 | static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 521 | static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
518 | static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 522 | static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
519 | static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 523 | static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
524 | static int get_xsync(struct slgt_info *info, int __user *if_mode); | ||
525 | static int set_xsync(struct slgt_info *info, int if_mode); | ||
526 | static int get_xctrl(struct slgt_info *info, int __user *if_mode); | ||
527 | static 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 | ||
2913 | static 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 | */ | ||
2927 | static 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 | |||
2939 | static 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 | */ | ||
2964 | static 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 | ||
3773 | static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) | 3859 | static __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--; |