aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPaul Fulghum <paulkf@microgate.com>2006-06-25 08:49:20 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-25 13:01:24 -0400
commit643f3319b9132c768081ce94f938a29139a16de9 (patch)
tree741484abe1b7ae934555772276db391d4eff017c /drivers
parented6a209024c23dbb39bfaa7361eb0b9c3fcc2b93 (diff)
[PATCH] add synclink_gt custom hdlc idle
Add custom HDLC idle pattern feature. It allows the user to specify an arbitrary 8 or 16 bit repeating pattern on the transmit data pin between HDLC frames. In most cases the idle pattern is continuous ones or flags as supported by off the shelf synchronous controllers and defined in the ISO3309 standard. Some applications (radio/satellite modems, connections to legacy military hardware) require non-standard patterns. Signed-off-by: Paul Fulghum <paulkf@microgate.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/synclink_gt.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index b4f1a5a435aa..6f93a0149fbf 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -2515,7 +2515,8 @@ static int set_txidle(struct slgt_info *info, int idle_mode)
2515 DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode)); 2515 DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode));
2516 spin_lock_irqsave(&info->lock,flags); 2516 spin_lock_irqsave(&info->lock,flags);
2517 info->idle_mode = idle_mode; 2517 info->idle_mode = idle_mode;
2518 tx_set_idle(info); 2518 if (info->params.mode != MGSL_MODE_ASYNC)
2519 tx_set_idle(info);
2519 spin_unlock_irqrestore(&info->lock,flags); 2520 spin_unlock_irqrestore(&info->lock,flags);
2520 return 0; 2521 return 0;
2521} 2522}
@@ -3940,8 +3941,6 @@ static void async_mode(struct slgt_info *info)
3940 3941
3941 msc_set_vcr(info); 3942 msc_set_vcr(info);
3942 3943
3943 tx_set_idle(info);
3944
3945 /* SCR (serial control) 3944 /* SCR (serial control)
3946 * 3945 *
3947 * 15 1=tx req on FIFO half empty 3946 * 15 1=tx req on FIFO half empty
@@ -4175,17 +4174,38 @@ static void hdlc_mode(struct slgt_info *info)
4175 */ 4174 */
4176static void tx_set_idle(struct slgt_info *info) 4175static void tx_set_idle(struct slgt_info *info)
4177{ 4176{
4178 unsigned char val = 0xff; 4177 unsigned char val;
4178 unsigned short tcr;
4179 4179
4180 switch(info->idle_mode) 4180 /* if preamble enabled (tcr[6] == 1) then tx idle size = 8 bits
4181 { 4181 * else tcr[5:4] = tx idle size: 00 = 8 bits, 01 = 16 bits
4182 case HDLC_TXIDLE_FLAGS: val = 0x7e; break; 4182 */
4183 case HDLC_TXIDLE_ALT_ZEROS_ONES: val = 0xaa; break; 4183 tcr = rd_reg16(info, TCR);
4184 case HDLC_TXIDLE_ZEROS: val = 0x00; break; 4184 if (info->idle_mode & HDLC_TXIDLE_CUSTOM_16) {
4185 case HDLC_TXIDLE_ONES: val = 0xff; break; 4185 /* disable preamble, set idle size to 16 bits */
4186 case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break; 4186 tcr = (tcr & ~(BIT6 + BIT5)) | BIT4;
4187 case HDLC_TXIDLE_SPACE: val = 0x00; break; 4187 /* MSB of 16 bit idle specified in tx preamble register (TPR) */
4188 case HDLC_TXIDLE_MARK: val = 0xff; break; 4188 wr_reg8(info, TPR, (unsigned char)((info->idle_mode >> 8) & 0xff));
4189 } else if (!(tcr & BIT6)) {
4190 /* preamble is disabled, set idle size to 8 bits */
4191 tcr &= ~(BIT5 + BIT4);
4192 }
4193 wr_reg16(info, TCR, tcr);
4194
4195 if (info->idle_mode & (HDLC_TXIDLE_CUSTOM_8 | HDLC_TXIDLE_CUSTOM_16)) {
4196 /* LSB of custom tx idle specified in tx idle register */
4197 val = (unsigned char)(info->idle_mode & 0xff);
4198 } else {
4199 /* standard 8 bit idle patterns */
4200 switch(info->idle_mode)
4201 {
4202 case HDLC_TXIDLE_FLAGS: val = 0x7e; break;
4203 case HDLC_TXIDLE_ALT_ZEROS_ONES:
4204 case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break;
4205 case HDLC_TXIDLE_ZEROS:
4206 case HDLC_TXIDLE_SPACE: val = 0x00; break;
4207 default: val = 0xff;
4208 }
4189 } 4209 }
4190 4210
4191 wr_reg8(info, TIR, val); 4211 wr_reg8(info, TIR, val);