diff options
Diffstat (limited to 'drivers/net/can/usb')
-rw-r--r-- | drivers/net/can/usb/kvaser_usb.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 2b994bbf85ca..9742e32d5cd5 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -31,7 +31,10 @@ #define USB_SEND_TIMEOUT 1000 /* msecs */ #define USB_RECV_TIMEOUT 1000 /* msecs */ #define RX_BUFFER_SIZE 3072 -#define CAN_USB_CLOCK 8000000 +#define KVASER_USB_CAN_CLOCK_8MHZ 8000000 +#define KVASER_USB_CAN_CLOCK_16MHZ 16000000 +#define KVASER_USB_CAN_CLOCK_24MHZ 24000000 +#define KVASER_USB_CAN_CLOCK_32MHZ 32000000 #define MAX_NET_DEVICES 3 #define MAX_USBCAN_NET_DEVICES 2 @@ -142,6 +145,12 @@ static inline bool kvaser_is_usbcan(const struct usb_device_id *id) #define CMD_LEAF_USB_THROTTLE 77 #define CMD_LEAF_LOG_MESSAGE 106 +/* Leaf frequency options */ +#define KVASER_USB_LEAF_SWOPTION_FREQ_MASK 0x60 +#define KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK 0 +#define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5) +#define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6) + /* error factors */ #define M16C_EF_ACKE BIT(0) #define M16C_EF_CRCE BIT(1) @@ -472,6 +481,8 @@ struct kvaser_usb { bool rxinitdone; void *rxbuf[MAX_RX_URBS]; dma_addr_t rxbuf_dma[MAX_RX_URBS]; + + struct can_clock clock; }; struct kvaser_usb_net_priv { @@ -652,6 +663,27 @@ static int kvaser_usb_send_simple_msg(const struct kvaser_usb *dev, return rc; } +static void kvaser_usb_get_software_info_leaf(struct kvaser_usb *dev, + const struct leaf_msg_softinfo *softinfo) +{ + u32 sw_options = le32_to_cpu(softinfo->sw_options); + + dev->fw_version = le32_to_cpu(softinfo->fw_version); + dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx); + + switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { + case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: + dev->clock.freq = KVASER_USB_CAN_CLOCK_16MHZ; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: + dev->clock.freq = KVASER_USB_CAN_CLOCK_24MHZ; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: + dev->clock.freq = KVASER_USB_CAN_CLOCK_32MHZ; + break; + } +} + static int kvaser_usb_get_software_info(struct kvaser_usb *dev) { struct kvaser_msg msg; @@ -667,14 +699,13 @@ static int kvaser_usb_get_software_info(struct kvaser_usb *dev) switch (dev->family) { case KVASER_LEAF: - dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version); - dev->max_tx_urbs = - le16_to_cpu(msg.u.leaf.softinfo.max_outstanding_tx); + kvaser_usb_get_software_info_leaf(dev, &msg.u.leaf.softinfo); break; case KVASER_USBCAN: dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version); dev->max_tx_urbs = le16_to_cpu(msg.u.usbcan.softinfo.max_outstanding_tx); + dev->clock.freq = KVASER_USB_CAN_CLOCK_8MHZ; break; } @@ -1926,7 +1957,7 @@ static int kvaser_usb_init_one(struct usb_interface *intf, kvaser_usb_reset_tx_urb_contexts(priv); priv->can.state = CAN_STATE_STOPPED; - priv->can.clock.freq = CAN_USB_CLOCK; + priv->can.clock.freq = dev->clock.freq; priv->can.bittiming_const = &kvaser_usb_bittiming_const; priv->can.do_set_bittiming = kvaser_usb_set_bittiming; priv->can.do_set_mode = kvaser_usb_set_mode; |