Commit 9807224f1dce5fb746ee33fb67ea2e38dafe3e9c
Committed by
Linus Torvalds
1 parent
ed77ed6112
Exists in
master
and in
39 other branches
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>
Showing 2 changed files with 113 additions and 3 deletions Side-by-side Diff
drivers/char/synclink_gt.c
... | ... | @@ -301,6 +301,8 @@ |
301 | 301 | unsigned int rx_pio; |
302 | 302 | unsigned int if_mode; |
303 | 303 | unsigned int base_clock; |
304 | + unsigned int xsync; | |
305 | + unsigned int xctrl; | |
304 | 306 | |
305 | 307 | /* device status */ |
306 | 308 | |
... | ... | @@ -405,6 +407,8 @@ |
405 | 407 | #define TDCSR 0x94 /* tx DMA control/status */ |
406 | 408 | #define RDDAR 0x98 /* rx DMA descriptor address */ |
407 | 409 | #define TDDAR 0x9c /* tx DMA descriptor address */ |
410 | +#define XSR 0x40 /* extended sync pattern */ | |
411 | +#define XCR 0x44 /* extended control */ | |
408 | 412 | |
409 | 413 | #define RXIDLE BIT14 |
410 | 414 | #define RXBREAK BIT14 |
... | ... | @@ -517,6 +521,10 @@ |
517 | 521 | static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
518 | 522 | static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
519 | 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 | 530 | * driver functions |
... | ... | @@ -1056,6 +1064,14 @@ |
1056 | 1064 | return get_gpio(info, argp); |
1057 | 1065 | case MGSL_IOCWAITGPIO: |
1058 | 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 | 1076 | mutex_lock(&info->port.mutex); |
1061 | 1077 | switch (cmd) { |
1062 | 1078 | |
... | ... | @@ -1213,12 +1229,16 @@ |
1213 | 1229 | case MGSL_IOCSGPIO: |
1214 | 1230 | case MGSL_IOCGGPIO: |
1215 | 1231 | case MGSL_IOCWAITGPIO: |
1232 | + case MGSL_IOCGXSYNC: | |
1233 | + case MGSL_IOCGXCTRL: | |
1216 | 1234 | case MGSL_IOCSTXIDLE: |
1217 | 1235 | case MGSL_IOCTXENABLE: |
1218 | 1236 | case MGSL_IOCRXENABLE: |
1219 | 1237 | case MGSL_IOCTXABORT: |
1220 | 1238 | case TIOCMIWAIT: |
1221 | 1239 | case MGSL_IOCSIF: |
1240 | + case MGSL_IOCSXSYNC: | |
1241 | + case MGSL_IOCSXCTRL: | |
1222 | 1242 | rc = ioctl(tty, file, cmd, arg); |
1223 | 1243 | break; |
1224 | 1244 | } |
... | ... | @@ -1961,6 +1981,7 @@ |
1961 | 1981 | case MGSL_MODE_RAW: |
1962 | 1982 | case MGSL_MODE_MONOSYNC: |
1963 | 1983 | case MGSL_MODE_BISYNC: |
1984 | + case MGSL_MODE_XSYNC: | |
1964 | 1985 | while(rx_get_buf(info)); |
1965 | 1986 | break; |
1966 | 1987 | } |
1967 | 1988 | |
... | ... | @@ -2889,7 +2910,70 @@ |
2889 | 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 | + | |
2892 | 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 | + | |
2976 | +/* | |
2893 | 2977 | * set general purpose IO pin state and direction |
2894 | 2978 | * |
2895 | 2979 | * user_gpio fields: |
... | ... | @@ -3768,7 +3852,9 @@ |
3768 | 3852 | #define CALC_REGADDR() \ |
3769 | 3853 | unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ |
3770 | 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 | 3859 | static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) |
3774 | 3860 | { |
... | ... | @@ -4187,7 +4273,13 @@ |
4187 | 4273 | |
4188 | 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 | 4283 | * 12..10 encoding |
4192 | 4284 | * 09 CRC enable |
4193 | 4285 | * 08 CRC32 |
... | ... | @@ -4202,6 +4294,9 @@ |
4202 | 4294 | val = BIT2; |
4203 | 4295 | |
4204 | 4296 | switch(info->params.mode) { |
4297 | + case MGSL_MODE_XSYNC: | |
4298 | + val |= BIT15 + BIT13; | |
4299 | + break; | |
4205 | 4300 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4206 | 4301 | case MGSL_MODE_BISYNC: val |= BIT15; break; |
4207 | 4302 | case MGSL_MODE_RAW: val |= BIT13; break; |
... | ... | @@ -4256,7 +4351,13 @@ |
4256 | 4351 | |
4257 | 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 | 4361 | * 12..10 encoding |
4261 | 4362 | * 09 CRC enable |
4262 | 4363 | * 08 CRC32 |
... | ... | @@ -4268,6 +4369,9 @@ |
4268 | 4369 | val = 0; |
4269 | 4370 | |
4270 | 4371 | switch(info->params.mode) { |
4372 | + case MGSL_MODE_XSYNC: | |
4373 | + val |= BIT15 + BIT13; | |
4374 | + break; | |
4271 | 4375 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4272 | 4376 | case MGSL_MODE_BISYNC: val |= BIT15; break; |
4273 | 4377 | case MGSL_MODE_RAW: val |= BIT13; break; |
... | ... | @@ -4684,6 +4788,7 @@ |
4684 | 4788 | switch(info->params.mode) { |
4685 | 4789 | case MGSL_MODE_MONOSYNC: |
4686 | 4790 | case MGSL_MODE_BISYNC: |
4791 | + case MGSL_MODE_XSYNC: | |
4687 | 4792 | /* ignore residue in byte synchronous modes */ |
4688 | 4793 | if (desc_residue(info->rbufs[i])) |
4689 | 4794 | count--; |
include/linux/synclink.h
... | ... | @@ -126,6 +126,7 @@ |
126 | 126 | #define MGSL_MODE_BISYNC 4 |
127 | 127 | #define MGSL_MODE_RAW 6 |
128 | 128 | #define MGSL_MODE_BASE_CLOCK 7 |
129 | +#define MGSL_MODE_XSYNC 8 | |
129 | 130 | |
130 | 131 | #define MGSL_BUS_TYPE_ISA 1 |
131 | 132 | #define MGSL_BUS_TYPE_EISA 2 |
... | ... | @@ -290,6 +291,10 @@ |
290 | 291 | #define MGSL_IOCSGPIO _IOW(MGSL_MAGIC_IOC,16,struct gpio_desc) |
291 | 292 | #define MGSL_IOCGGPIO _IOR(MGSL_MAGIC_IOC,17,struct gpio_desc) |
292 | 293 | #define MGSL_IOCWAITGPIO _IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc) |
294 | +#define MGSL_IOCSXSYNC _IO(MGSL_MAGIC_IOC, 19) | |
295 | +#define MGSL_IOCGXSYNC _IO(MGSL_MAGIC_IOC, 20) | |
296 | +#define MGSL_IOCSXCTRL _IO(MGSL_MAGIC_IOC, 21) | |
297 | +#define MGSL_IOCGXCTRL _IO(MGSL_MAGIC_IOC, 22) | |
293 | 298 | |
294 | 299 | #ifdef __KERNEL__ |
295 | 300 | /* provide 32 bit ioctl compatibility on 64 bit systems */ |