diff options
| author | Paul Fulghum <paulkf@microgate.com> | 2010-10-27 15:34:22 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 18:03:14 -0700 | 
| commit | 9807224f1dce5fb746ee33fb67ea2e38dafe3e9c (patch) | |
| tree | d9a9bdb1ae4196dec24b9c98bdd753c7b72de4df | |
| parent | ed77ed6112f2d4b650f4be7dbaf14e06e1d393a5 (diff) | |
| download | olio-linux-3.10-9807224f1dce5fb746ee33fb67ea2e38dafe3e9c.tar.xz olio-linux-3.10-9807224f1dce5fb746ee33fb67ea2e38dafe3e9c.zip  | |
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>
| -rw-r--r-- | drivers/char/synclink_gt.c | 111 | ||||
| -rw-r--r-- | include/linux/synclink.h | 5 | 
2 files changed, 113 insertions, 3 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 9f7fc71474b..d01fffeac95 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -301,6 +301,8 @@ struct slgt_info {  	unsigned int rx_pio;  	unsigned int if_mode;  	unsigned int base_clock; +	unsigned int xsync; +	unsigned int xctrl;  	/* device status */ @@ -405,6 +407,8 @@ static MGSL_PARAMS default_params = {  #define TDCSR 0x94 /* tx DMA control/status */  #define RDDAR 0x98 /* rx DMA descriptor address */  #define TDDAR 0x9c /* tx DMA descriptor address */ +#define XSR   0x40 /* extended sync pattern */ +#define XCR   0x44 /* extended control */  #define RXIDLE      BIT14  #define RXBREAK     BIT14 @@ -517,6 +521,10 @@ static int  set_interface(struct slgt_info *info, int if_mode);  static int  set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);  static int  get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio);  static int  wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); +static int  get_xsync(struct slgt_info *info, int __user *if_mode); +static int  set_xsync(struct slgt_info *info, int if_mode); +static int  get_xctrl(struct slgt_info *info, int __user *if_mode); +static int  set_xctrl(struct slgt_info *info, int if_mode);  /*   * driver functions @@ -1056,6 +1064,14 @@ static int ioctl(struct tty_struct *tty, struct file *file,  		return get_gpio(info, argp);  	case MGSL_IOCWAITGPIO:  		return wait_gpio(info, argp); +	case MGSL_IOCGXSYNC: +		return get_xsync(info, argp); +	case MGSL_IOCSXSYNC: +		return set_xsync(info, (int)arg); +	case MGSL_IOCGXCTRL: +		return get_xctrl(info, argp); +	case MGSL_IOCSXCTRL: +		return set_xctrl(info, (int)arg);  	}  	mutex_lock(&info->port.mutex);  	switch (cmd) { @@ -1213,12 +1229,16 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file,  	case MGSL_IOCSGPIO:  	case MGSL_IOCGGPIO:  	case MGSL_IOCWAITGPIO: +	case MGSL_IOCGXSYNC: +	case MGSL_IOCGXCTRL:  	case MGSL_IOCSTXIDLE:  	case MGSL_IOCTXENABLE:  	case MGSL_IOCRXENABLE:  	case MGSL_IOCTXABORT:  	case TIOCMIWAIT:  	case MGSL_IOCSIF: +	case MGSL_IOCSXSYNC: +	case MGSL_IOCSXCTRL:  		rc = ioctl(tty, file, cmd, arg);  		break;  	} @@ -1961,6 +1981,7 @@ static void bh_handler(struct work_struct *work)  			case MGSL_MODE_RAW:  			case MGSL_MODE_MONOSYNC:  			case MGSL_MODE_BISYNC: +			case MGSL_MODE_XSYNC:  				while(rx_get_buf(info));  				break;  			} @@ -2889,6 +2910,69 @@ static int set_interface(struct slgt_info *info, int if_mode)  	return 0;  } +static int get_xsync(struct slgt_info *info, int __user *xsync) +{ +	DBGINFO(("%s get_xsync=%x\n", info->device_name, info->xsync)); +	if (put_user(info->xsync, xsync)) +		return -EFAULT; +	return 0; +} + +/* + * set extended sync pattern (1 to 4 bytes) for extended sync mode + * + * sync pattern is contained in least significant bytes of value + * most significant byte of sync pattern is oldest (1st sent/detected) + */ +static int set_xsync(struct slgt_info *info, int xsync) +{ +	unsigned long flags; + +	DBGINFO(("%s set_xsync=%x)\n", info->device_name, xsync)); +	spin_lock_irqsave(&info->lock, flags); +	info->xsync = xsync; +	wr_reg32(info, XSR, xsync); +	spin_unlock_irqrestore(&info->lock, flags); +	return 0; +} + +static int get_xctrl(struct slgt_info *info, int __user *xctrl) +{ +	DBGINFO(("%s get_xctrl=%x\n", info->device_name, info->xctrl)); +	if (put_user(info->xctrl, xctrl)) +		return -EFAULT; +	return 0; +} + +/* + * set extended control options + * + * xctrl[31:19] reserved, must be zero + * xctrl[18:17] extended sync pattern length in bytes + *              00 = 1 byte  in xsr[7:0] + *              01 = 2 bytes in xsr[15:0] + *              10 = 3 bytes in xsr[23:0] + *              11 = 4 bytes in xsr[31:0] + * xctrl[16]    1 = enable terminal count, 0=disabled + * xctrl[15:0]  receive terminal count for fixed length packets + *              value is count minus one (0 = 1 byte packet) + *              when terminal count is reached, receiver + *              automatically returns to hunt mode and receive + *              FIFO contents are flushed to DMA buffers with + *              end of frame (EOF) status + */ +static int set_xctrl(struct slgt_info *info, int xctrl) +{ +	unsigned long flags; + +	DBGINFO(("%s set_xctrl=%x)\n", info->device_name, xctrl)); +	spin_lock_irqsave(&info->lock, flags); +	info->xctrl = xctrl; +	wr_reg32(info, XCR, xctrl); +	spin_unlock_irqrestore(&info->lock, flags); +	return 0; +} +  /*   * set general purpose IO pin state and direction   * @@ -3768,7 +3852,9 @@ module_exit(slgt_exit);  #define CALC_REGADDR() \  	unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \  	if (addr >= 0x80) \ -		reg_addr += (info->port_num) * 32; +		reg_addr += (info->port_num) * 32; \ +	else if (addr >= 0x40)	\ +		reg_addr += (info->port_num) * 16;  static __u8 rd_reg8(struct slgt_info *info, unsigned int addr)  { @@ -4187,7 +4273,13 @@ static void sync_mode(struct slgt_info *info)  	/* TCR (tx control)  	 * -	 * 15..13  mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync +	 * 15..13  mode +	 *         000=HDLC/SDLC +	 *         001=raw bit synchronous +	 *         010=asynchronous/isochronous +	 *         011=monosync byte synchronous +	 *         100=bisync byte synchronous +	 *         101=xsync byte synchronous  	 * 12..10  encoding  	 * 09      CRC enable  	 * 08      CRC32 @@ -4202,6 +4294,9 @@ static void sync_mode(struct slgt_info *info)  	val = BIT2;  	switch(info->params.mode) { +	case MGSL_MODE_XSYNC: +		val |= BIT15 + BIT13; +		break;  	case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;  	case MGSL_MODE_BISYNC:   val |= BIT15; break;  	case MGSL_MODE_RAW:      val |= BIT13; break; @@ -4256,7 +4351,13 @@ static void sync_mode(struct slgt_info *info)  	/* RCR (rx control)  	 * -	 * 15..13  mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync +	 * 15..13  mode +	 *         000=HDLC/SDLC +	 *         001=raw bit synchronous +	 *         010=asynchronous/isochronous +	 *         011=monosync byte synchronous +	 *         100=bisync byte synchronous +	 *         101=xsync byte synchronous  	 * 12..10  encoding  	 * 09      CRC enable  	 * 08      CRC32 @@ -4268,6 +4369,9 @@ static void sync_mode(struct slgt_info *info)  	val = 0;  	switch(info->params.mode) { +	case MGSL_MODE_XSYNC: +		val |= BIT15 + BIT13; +		break;  	case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break;  	case MGSL_MODE_BISYNC:   val |= BIT15; break;  	case MGSL_MODE_RAW:      val |= BIT13; break; @@ -4684,6 +4788,7 @@ static bool rx_get_buf(struct slgt_info *info)  	switch(info->params.mode) {  	case MGSL_MODE_MONOSYNC:  	case MGSL_MODE_BISYNC: +	case MGSL_MODE_XSYNC:  		/* ignore residue in byte synchronous modes */  		if (desc_residue(info->rbufs[i]))  			count--; diff --git a/include/linux/synclink.h b/include/linux/synclink.h index 0ff2779c44d..2e7d81c4e5a 100644 --- a/include/linux/synclink.h +++ b/include/linux/synclink.h @@ -126,6 +126,7 @@  #define MGSL_MODE_BISYNC	4  #define MGSL_MODE_RAW		6  #define MGSL_MODE_BASE_CLOCK    7 +#define MGSL_MODE_XSYNC         8  #define MGSL_BUS_TYPE_ISA	1  #define MGSL_BUS_TYPE_EISA	2 @@ -290,6 +291,10 @@ struct gpio_desc {  #define MGSL_IOCSGPIO		_IOW(MGSL_MAGIC_IOC,16,struct gpio_desc)  #define MGSL_IOCGGPIO		_IOR(MGSL_MAGIC_IOC,17,struct gpio_desc)  #define MGSL_IOCWAITGPIO	_IOWR(MGSL_MAGIC_IOC,18,struct gpio_desc) +#define MGSL_IOCSXSYNC		_IO(MGSL_MAGIC_IOC, 19) +#define MGSL_IOCGXSYNC		_IO(MGSL_MAGIC_IOC, 20) +#define MGSL_IOCSXCTRL		_IO(MGSL_MAGIC_IOC, 21) +#define MGSL_IOCGXCTRL		_IO(MGSL_MAGIC_IOC, 22)  #ifdef __KERNEL__  /* provide 32 bit ioctl compatibility on 64 bit systems */  |