]> rtime.felk.cvut.cz Git - socketcan-devel.git/commitdiff
Getting a bit timing constants from device has been done.
authorJiri Vanek <vanekjir@fel.cvut.cz>
Fri, 13 Apr 2012 10:50:42 +0000 (12:50 +0200)
committerJiri Vanek <vanekjir@fel.cvut.cz>
Fri, 13 Apr 2012 10:50:42 +0000 (12:50 +0200)
kernel/2.6/drivers/net/can/usb/ctu_usbcan.c

index 000018fa6c0961aabcc25d6ba5c9bcd7b4a92b6c..0543bc6440510b99da27e0bbc50a840c82e3213b 100644 (file)
 
 // lpc17xx debug
 #define USBCAN_VENDOR_SET_CANBTR       (9)
-#define CTU_USBCAN_CAN_CLOCK   18000000
+#define USBCAN_VENDOR_GET_BITTIMING_CONST      (10)
 // lpc17xx debug - end
 
 #define CTU_USBCAN_VENDOR_ID   0x1669
 #define CTU_USBCAN_PRODUCT_ID  0x1011
 
-#define USBCAN_TOT_RX_URBS 8
-#define USBCAN_TOT_TX_URBS 8
+#define USBCAN_TOT_RX_URBS     8
+#define USBCAN_TOT_TX_URBS     8
 
-#define USBCAN_TRANSFER_SIZE 16
+#define USBCAN_TRANSFER_SIZE   16
+#define USBCAN_BITTIMING_SIZE  16
+#define USBCAN_BITTIMING_CONST_SIZE    36
 
-#define CAN_MSG_LENGTH 8
+#define CAN_MSG_LENGTH 8
 
-#define MSG_RTR   (1<<0)
+#define MSG_RTR          (1<<0)
 #define MSG_OVR   (1<<1)
 #define MSG_EXT   (1<<2)
 #define MSG_LOCAL (1<<3)
 
-
 #define USBCAN_DATA_OK (1)
 #define USBCAN_TX_PENDING      (2)
+#define USBCAN_BITTIMING_CONST_SET     (3)
+
 
 MODULE_LICENSE("GPL");
 
@@ -72,12 +75,14 @@ Structure of byte array msg in struct usbcan_message that represents CAN message
 
 */
 
-
 /* Structure to hold all of our device specific stuff */
 struct ctu_usbcan_usb {
 
        struct can_priv can; /* must be the first member */
 
+       struct can_bittiming_const cbc;
+       u32 can_clock;
+
        struct usb_device *udev;                        /* the usb device for this device */
        struct net_device *netdev;
 
@@ -112,6 +117,115 @@ static void usbcan_usb_message_move_list(struct ctu_usbcan_usb *dev,
 }
 
 
+static int get_bittiming_constants(struct ctu_usbcan_usb *dev)
+{
+
+       int retval;
+       u8 *usbbuf;
+       u32 * ptr;
+
+       usbbuf = kzalloc(sizeof(u8)*USBCAN_BITTIMING_CONST_SIZE, GFP_KERNEL);
+
+       if(!usbbuf){
+               err("Error allocating receive buffer for bittiming constants\n");
+               return 1;
+       }
+       
+       retval = usb_control_msg(dev->udev,
+               usb_rcvctrlpipe(dev->udev, 0),
+               USBCAN_VENDOR_GET_BITTIMING_CONST,
+               USB_TYPE_VENDOR,
+               cpu_to_le16(0), cpu_to_le16(0),
+               usbbuf, USBCAN_BITTIMING_CONST_SIZE,
+               1000);
+
+       if(retval<0)
+               goto exit;
+
+       ptr = (u32*) usbbuf;
+
+       dev->can_clock = le32_to_cpu(*(ptr++));
+       dev->cbc.tseg1_min = le32_to_cpu(*(ptr++));
+       dev->cbc.tseg1_max = le32_to_cpu(*(ptr++));
+       dev->cbc.tseg2_min = le32_to_cpu(*(ptr++));
+       dev->cbc.tseg2_max = le32_to_cpu(*(ptr++));
+       dev->cbc.sjw_max = le32_to_cpu(*(ptr++));
+       dev->cbc.brp_min = le32_to_cpu(*(ptr++));
+       dev->cbc.brp_max = le32_to_cpu(*(ptr++));
+       dev->cbc.brp_inc = le32_to_cpu(*(ptr));
+
+       set_bit(USBCAN_BITTIMING_CONST_SET,&dev->flags);
+
+
+exit:
+
+       kfree(usbbuf);
+       if(retval<0)
+               return retval;
+
+       return 0;
+
+}
+
+static int ctu_usbcan_set_mode(struct net_device *netdev, enum can_mode mode)
+{
+       
+       printk("SET MODE\n");
+
+       return 0;
+}
+
+static int ctu_usbcan_set_bittiming(struct net_device *netdev)
+{
+       struct ctu_usbcan_usb *dev = netdev_priv(netdev);
+       struct can_bittiming *bt = &dev->can.bittiming;
+       u8 *usbbuf;     
+       u32 * ptr;
+       int retval;
+       
+
+       if (!dev)
+               return -ENODEV;
+
+
+       usbbuf = kzalloc(sizeof(u8)*USBCAN_BITTIMING_SIZE, GFP_KERNEL);
+
+       if(!usbbuf){
+               err("Error allocating transmit buffer for set bittiming\n");
+               return 1;
+       }       
+       
+       ptr = (u32*) usbbuf;
+
+       *(ptr++)=cpu_to_le32(bt->brp);          // baudrate prescaler
+       *(ptr++)=cpu_to_le32(bt->sjw);  // sjw
+       *(ptr++)=cpu_to_le32(bt->prop_seg + bt->phase_seg1);    // TSEG1
+       *(ptr)=cpu_to_le32(bt->phase_seg2);     // TSEG2
+
+
+       retval = usb_control_msg(dev->udev,
+                               usb_sndctrlpipe(dev->udev, 0),
+                               USBCAN_VENDOR_SET_CANBTR,
+                               USB_TYPE_VENDOR,
+                               cpu_to_le16(0), cpu_to_le16(0),
+                               usbbuf, USBCAN_BITTIMING_SIZE,
+                               1000);
+
+       kfree(usbbuf);
+
+       if(retval){
+               printk("BITRATE %d, BRP: %d, SJW: %d, TSEG1: %d, TSEG2: %d \n", bt->bitrate, bt->brp, bt->sjw,\
+                               (bt->prop_seg + bt->phase_seg1), bt->phase_seg2);       
+               return 0;
+       }
+       else{
+               err("Could not set bittiming\n");
+               return retval;
+       }
+
+}
+
+
 static void ctu_usbcan_tx_callback(struct urb *urb){
 
        struct usbcan_message *m = urb->context;
@@ -491,7 +605,7 @@ int usbcan_kthread(void *data)
 
 exit:
        usbcan_kthread_free_urbs(dev);
-       printk("CTU USBCAN: usbcan thread finished!");
+       printk("CTU USBCAN: usbcan thread finished\n");
        
        return 0;
 
@@ -531,65 +645,6 @@ static const struct net_device_ops ctu_usbcan_netdev_ops = {
        .ndo_start_xmit = ctu_usbcan_start_xmit,
 };
 
-static struct can_bittiming_const ctu_usbcan_bittiming_const = {
-       .name = "lpc17xx_can",
-       .tseg1_min = 1,
-       .tseg1_max = 16,
-       .tseg2_min = 1,
-       .tseg2_max = 8,
-       .sjw_max = 4,
-       .brp_min = 1,
-       .brp_max = 1024,
-       .brp_inc = 1,
-};
-
-static int ctu_usbcan_set_mode(struct net_device *netdev, enum can_mode mode)
-{
-       struct ems_usb *dev = netdev_priv(netdev);
-
-       printk("SET MODE\n");
-
-       return 0;
-}
-
-static int ctu_usbcan_set_bittiming(struct net_device *netdev)
-{
-       struct ctu_usbcan_usb *dev = netdev_priv(netdev);
-       struct can_bittiming *bt = &dev->can.bittiming;
-       int retval;
-       
-       u8 usbbuf[USBCAN_TRANSFER_SIZE];
-
-       printk("BRP: %d, SJW: %d, TSEG1: %d, TSEG2: %d - ", bt->brp, bt->sjw, ( bt->prop_seg + bt->phase_seg1), bt->phase_seg2);        
-
-
-       if (!dev)
-               return -ENODEV;
-
-       *(uint32_t *)(usbbuf)=cpu_to_le32(bt->brp);             // baudrate prescaler
-       *(uint32_t *)(usbbuf+4)=cpu_to_le32(bt->sjw);   // sjw
-       *(uint32_t *)(usbbuf+8)=cpu_to_le32(bt->prop_seg + bt->phase_seg1);     // TSEG1
-       *(uint32_t *)(usbbuf+12)=cpu_to_le32(bt->phase_seg2);   // TSEG2
-
-       retval = usb_control_msg(dev->udev,
-                               usb_sndctrlpipe(dev->udev, 0),
-                               USBCAN_VENDOR_SET_CANBTR,
-                               USB_TYPE_VENDOR,
-                               cpu_to_le16(0), cpu_to_le16(0),
-                               &usbbuf, USBCAN_TRANSFER_SIZE,
-                               1000);
-
-       if(retval){
-               printk("OK\n");
-               return 0;
-       }
-       else{
-               printk("KO\n");
-               return retval;
-       }
-
-}
-
 
 static int ctu_usbcan_probe(struct usb_interface *intf,
                                                        const struct usb_device_id *id)
@@ -626,11 +681,6 @@ static int ctu_usbcan_probe(struct usb_interface *intf,
        dev->udev = interface_to_usbdev(intf);
        dev->netdev = netdev;
 
-       dev->can.clock.freq = CTU_USBCAN_CAN_CLOCK;
-       dev->can.bittiming_const = &ctu_usbcan_bittiming_const;
-       dev->can.do_set_bittiming = ctu_usbcan_set_bittiming;
-       dev->can.do_set_mode = ctu_usbcan_set_mode;
-
 
        netdev->netdev_ops = &ctu_usbcan_netdev_ops;
        netdev->flags |= IFF_ECHO;
@@ -662,6 +712,16 @@ static int ctu_usbcan_probe(struct usb_interface *intf,
        usb_set_intfdata(intf, dev);
        SET_NETDEV_DEV(netdev, &intf->dev);
 
+       if (get_bittiming_constants(dev)){
+               err("Could not get bittiming constants\n");
+               goto exit;
+       }
+
+       dev->can.clock.freq = dev->can_clock;
+       dev->can.bittiming_const = &dev->cbc;
+       dev->can.do_set_bittiming = ctu_usbcan_set_bittiming;
+       dev->can.do_set_mode = ctu_usbcan_set_mode;
+
 
        err = register_candev(netdev);
        if (err) {
@@ -685,8 +745,11 @@ static void ctu_usbcan_disconnect(struct usb_interface *intf)
        usb_set_intfdata(intf, NULL);
 
        if (dev) {
-               unregister_netdev(dev->netdev);
+               if(test_bit(USBCAN_BITTIMING_CONST_SET,&dev->flags))            
+                       unregister_netdev(dev->netdev);
+
                free_candev(dev->netdev);
+               clear_bit(USBCAN_BITTIMING_CONST_SET,&dev->flags);
        }
 
 }