diff options
author | Paul Fulghum <paulkf@microgate.com> | 2009-04-02 19:58:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-02 22:05:01 -0400 |
commit | 1f80769ffd36e74357fe896dc43dddf1af1510f3 (patch) | |
tree | 633e513143c276b3bcee9e4743938902f906a919 /drivers/char | |
parent | a50b0aa4bd9a7d42112442a385f3dc0e775284dd (diff) |
synclink_gt: add clock options
Add support for x8 asynchronous sample rate and ability to specify base
clock frequency.
Signed-off-by: Paul Fulghum <paulkf@microgate.com>
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/synclink_gt.c | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 6ec6e13d47d7..5e256494686a 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -298,6 +298,7 @@ struct slgt_info { | |||
298 | 298 | ||
299 | unsigned int rbuf_fill_level; | 299 | unsigned int rbuf_fill_level; |
300 | unsigned int if_mode; | 300 | unsigned int if_mode; |
301 | unsigned int base_clock; | ||
301 | 302 | ||
302 | /* device status */ | 303 | /* device status */ |
303 | 304 | ||
@@ -1156,22 +1157,26 @@ static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *ne | |||
1156 | return -EFAULT; | 1157 | return -EFAULT; |
1157 | 1158 | ||
1158 | spin_lock(&info->lock); | 1159 | spin_lock(&info->lock); |
1159 | info->params.mode = tmp_params.mode; | 1160 | if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) { |
1160 | info->params.loopback = tmp_params.loopback; | 1161 | info->base_clock = tmp_params.clock_speed; |
1161 | info->params.flags = tmp_params.flags; | 1162 | } else { |
1162 | info->params.encoding = tmp_params.encoding; | 1163 | info->params.mode = tmp_params.mode; |
1163 | info->params.clock_speed = tmp_params.clock_speed; | 1164 | info->params.loopback = tmp_params.loopback; |
1164 | info->params.addr_filter = tmp_params.addr_filter; | 1165 | info->params.flags = tmp_params.flags; |
1165 | info->params.crc_type = tmp_params.crc_type; | 1166 | info->params.encoding = tmp_params.encoding; |
1166 | info->params.preamble_length = tmp_params.preamble_length; | 1167 | info->params.clock_speed = tmp_params.clock_speed; |
1167 | info->params.preamble = tmp_params.preamble; | 1168 | info->params.addr_filter = tmp_params.addr_filter; |
1168 | info->params.data_rate = tmp_params.data_rate; | 1169 | info->params.crc_type = tmp_params.crc_type; |
1169 | info->params.data_bits = tmp_params.data_bits; | 1170 | info->params.preamble_length = tmp_params.preamble_length; |
1170 | info->params.stop_bits = tmp_params.stop_bits; | 1171 | info->params.preamble = tmp_params.preamble; |
1171 | info->params.parity = tmp_params.parity; | 1172 | info->params.data_rate = tmp_params.data_rate; |
1173 | info->params.data_bits = tmp_params.data_bits; | ||
1174 | info->params.stop_bits = tmp_params.stop_bits; | ||
1175 | info->params.parity = tmp_params.parity; | ||
1176 | } | ||
1172 | spin_unlock(&info->lock); | 1177 | spin_unlock(&info->lock); |
1173 | 1178 | ||
1174 | change_params(info); | 1179 | program_hw(info); |
1175 | 1180 | ||
1176 | return 0; | 1181 | return 0; |
1177 | } | 1182 | } |
@@ -2559,10 +2564,13 @@ static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params) | |||
2559 | return -EFAULT; | 2564 | return -EFAULT; |
2560 | 2565 | ||
2561 | spin_lock_irqsave(&info->lock, flags); | 2566 | spin_lock_irqsave(&info->lock, flags); |
2562 | memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); | 2567 | if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) |
2568 | info->base_clock = tmp_params.clock_speed; | ||
2569 | else | ||
2570 | memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); | ||
2563 | spin_unlock_irqrestore(&info->lock, flags); | 2571 | spin_unlock_irqrestore(&info->lock, flags); |
2564 | 2572 | ||
2565 | change_params(info); | 2573 | program_hw(info); |
2566 | 2574 | ||
2567 | return 0; | 2575 | return 0; |
2568 | } | 2576 | } |
@@ -3432,6 +3440,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev | |||
3432 | info->magic = MGSL_MAGIC; | 3440 | info->magic = MGSL_MAGIC; |
3433 | INIT_WORK(&info->task, bh_handler); | 3441 | INIT_WORK(&info->task, bh_handler); |
3434 | info->max_frame_size = 4096; | 3442 | info->max_frame_size = 4096; |
3443 | info->base_clock = 14745600; | ||
3435 | info->rbuf_fill_level = DMABUFSIZE; | 3444 | info->rbuf_fill_level = DMABUFSIZE; |
3436 | info->port.close_delay = 5*HZ/10; | 3445 | info->port.close_delay = 5*HZ/10; |
3437 | info->port.closing_wait = 30*HZ; | 3446 | info->port.closing_wait = 30*HZ; |
@@ -3779,7 +3788,7 @@ static void enable_loopback(struct slgt_info *info) | |||
3779 | static void set_rate(struct slgt_info *info, u32 rate) | 3788 | static void set_rate(struct slgt_info *info, u32 rate) |
3780 | { | 3789 | { |
3781 | unsigned int div; | 3790 | unsigned int div; |
3782 | static unsigned int osc = 14745600; | 3791 | unsigned int osc = info->base_clock; |
3783 | 3792 | ||
3784 | /* div = osc/rate - 1 | 3793 | /* div = osc/rate - 1 |
3785 | * | 3794 | * |
@@ -4083,18 +4092,27 @@ static void async_mode(struct slgt_info *info) | |||
4083 | * 06 CTS IRQ enable | 4092 | * 06 CTS IRQ enable |
4084 | * 05 DCD IRQ enable | 4093 | * 05 DCD IRQ enable |
4085 | * 04 RI IRQ enable | 4094 | * 04 RI IRQ enable |
4086 | * 03 reserved, must be zero | 4095 | * 03 0=16x sampling, 1=8x sampling |
4087 | * 02 1=txd->rxd internal loopback enable | 4096 | * 02 1=txd->rxd internal loopback enable |
4088 | * 01 reserved, must be zero | 4097 | * 01 reserved, must be zero |
4089 | * 00 1=master IRQ enable | 4098 | * 00 1=master IRQ enable |
4090 | */ | 4099 | */ |
4091 | val = BIT15 + BIT14 + BIT0; | 4100 | val = BIT15 + BIT14 + BIT0; |
4101 | /* JCR[8] : 1 = x8 async mode feature available */ | ||
4102 | if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate && | ||
4103 | ((info->base_clock < (info->params.data_rate * 16)) || | ||
4104 | (info->base_clock % (info->params.data_rate * 16)))) { | ||
4105 | /* use 8x sampling */ | ||
4106 | val |= BIT3; | ||
4107 | set_rate(info, info->params.data_rate * 8); | ||
4108 | } else { | ||
4109 | /* use 16x sampling */ | ||
4110 | set_rate(info, info->params.data_rate * 16); | ||
4111 | } | ||
4092 | wr_reg16(info, SCR, val); | 4112 | wr_reg16(info, SCR, val); |
4093 | 4113 | ||
4094 | slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER); | 4114 | slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER); |
4095 | 4115 | ||
4096 | set_rate(info, info->params.data_rate * 16); | ||
4097 | |||
4098 | if (info->params.loopback) | 4116 | if (info->params.loopback) |
4099 | enable_loopback(info); | 4117 | enable_loopback(info); |
4100 | } | 4118 | } |