diff options
Diffstat (limited to 'drivers/staging/winbond/wb35reg.c')
| -rw-r--r-- | drivers/staging/winbond/wb35reg.c | 443 |
1 files changed, 261 insertions, 182 deletions
diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c index da595f16f63..bbc5ddcce6f 100644 --- a/drivers/staging/winbond/wb35reg.c +++ b/drivers/staging/winbond/wb35reg.c @@ -1,10 +1,9 @@ #include "wb35reg_f.h" +#include "phy_calibration.h" #include <linux/usb.h> #include <linux/slab.h> -extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency); - /* * true : read command process successfully * false : register not support @@ -14,7 +13,8 @@ extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency); * Flag : AUTO_INCREMENT - RegisterNo will auto increment 4 * NO_INCREMENT - Function will write data into the same register */ -unsigned char Wb35Reg_BurstWrite(struct hw_data *pHwData, u16 RegisterNo, u32 *pRegisterData, u8 NumberOfData, u8 Flag) +unsigned char Wb35Reg_BurstWrite(struct hw_data *pHwData, u16 RegisterNo, + u32 *pRegisterData, u8 NumberOfData, u8 Flag) { struct wb35_reg *reg = &pHwData->reg; struct urb *urb = NULL; @@ -30,87 +30,157 @@ unsigned char Wb35Reg_BurstWrite(struct hw_data *pHwData, u16 RegisterNo, u32 *p /* Trying to use burst write function if use new hardware */ UrbSize = sizeof(struct wb35_reg_queue) + DataSize + sizeof(struct usb_ctrlrequest); reg_queue = kzalloc(UrbSize, GFP_ATOMIC); + if (reg_queue == NULL) + return false; + urb = usb_alloc_urb(0, GFP_ATOMIC); - if (urb && reg_queue) { - reg_queue->DIRECT = 2; /* burst write register */ - reg_queue->INDEX = RegisterNo; - reg_queue->pBuffer = (u32 *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); - memcpy(reg_queue->pBuffer, pRegisterData, DataSize); - /* the function for reversing register data from little endian to big endian */ - for (i = 0; i < NumberOfData ; i++) - reg_queue->pBuffer[i] = cpu_to_le32(reg_queue->pBuffer[i]); - - dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue) + DataSize); - dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; - dr->bRequest = 0x04; /* USB or vendor-defined request code, burst mode */ - dr->wValue = cpu_to_le16(Flag); /* 0: Register number auto-increment, 1: No auto increment */ - dr->wIndex = cpu_to_le16(RegisterNo); - dr->wLength = cpu_to_le16(DataSize); - reg_queue->Next = NULL; - reg_queue->pUsbReq = dr; - reg_queue->urb = urb; + if (urb == NULL) { + kfree(reg_queue); + return false; + } - spin_lock_irq(®->EP0VM_spin_lock); - if (reg->reg_first == NULL) - reg->reg_first = reg_queue; - else - reg->reg_last->Next = reg_queue; - reg->reg_last = reg_queue; + reg_queue->DIRECT = 2; /* burst write register */ + reg_queue->INDEX = RegisterNo; + reg_queue->pBuffer = (u32 *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); + memcpy(reg_queue->pBuffer, pRegisterData, DataSize); + /* the function for reversing register data from little endian to big endian */ + for (i = 0; i < NumberOfData; i++) + reg_queue->pBuffer[i] = cpu_to_le32(reg_queue->pBuffer[i]); + + dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue) + DataSize); + dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; + dr->bRequest = 0x04; /* USB or vendor-defined request code, burst mode */ + dr->wValue = cpu_to_le16(Flag); /* 0: Register number auto-increment, 1: No auto increment */ + dr->wIndex = cpu_to_le16(RegisterNo); + dr->wLength = cpu_to_le16(DataSize); + reg_queue->Next = NULL; + reg_queue->pUsbReq = dr; + reg_queue->urb = urb; - spin_unlock_irq(®->EP0VM_spin_lock); + spin_lock_irq(®->EP0VM_spin_lock); + if (reg->reg_first == NULL) + reg->reg_first = reg_queue; + else + reg->reg_last->Next = reg_queue; + reg->reg_last = reg_queue; - /* Start EP0VM */ - Wb35Reg_EP0VM_start(pHwData); + spin_unlock_irq(®->EP0VM_spin_lock); - return true; - } else { - if (urb) - usb_free_urb(urb); - kfree(reg_queue); - return false; - } - return false; + /* Start EP0VM */ + Wb35Reg_EP0VM_start(pHwData); + + return true; } -void Wb35Reg_Update(struct hw_data *pHwData, u16 RegisterNo, u32 RegisterValue) +void Wb35Reg_Update(struct hw_data *pHwData, u16 RegisterNo, u32 RegisterValue) { struct wb35_reg *reg = &pHwData->reg; switch (RegisterNo) { - case 0x3b0: reg->U1B0 = RegisterValue; break; - case 0x3bc: reg->U1BC_LEDConfigure = RegisterValue; break; - case 0x400: reg->D00_DmaControl = RegisterValue; break; - case 0x800: reg->M00_MacControl = RegisterValue; break; - case 0x804: reg->M04_MulticastAddress1 = RegisterValue; break; - case 0x808: reg->M08_MulticastAddress2 = RegisterValue; break; - case 0x824: reg->M24_MacControl = RegisterValue; break; - case 0x828: reg->M28_MacControl = RegisterValue; break; - case 0x82c: reg->M2C_MacControl = RegisterValue; break; - case 0x838: reg->M38_MacControl = RegisterValue; break; - case 0x840: reg->M40_MacControl = RegisterValue; break; - case 0x844: reg->M44_MacControl = RegisterValue; break; - case 0x848: reg->M48_MacControl = RegisterValue; break; - case 0x84c: reg->M4C_MacStatus = RegisterValue; break; - case 0x860: reg->M60_MacControl = RegisterValue; break; - case 0x868: reg->M68_MacControl = RegisterValue; break; - case 0x870: reg->M70_MacControl = RegisterValue; break; - case 0x874: reg->M74_MacControl = RegisterValue; break; - case 0x878: reg->M78_ERPInformation = RegisterValue; break; - case 0x87C: reg->M7C_MacControl = RegisterValue; break; - case 0x880: reg->M80_MacControl = RegisterValue; break; - case 0x884: reg->M84_MacControl = RegisterValue; break; - case 0x888: reg->M88_MacControl = RegisterValue; break; - case 0x898: reg->M98_MacControl = RegisterValue; break; - case 0x100c: reg->BB0C = RegisterValue; break; - case 0x102c: reg->BB2C = RegisterValue; break; - case 0x1030: reg->BB30 = RegisterValue; break; - case 0x103c: reg->BB3C = RegisterValue; break; - case 0x1048: reg->BB48 = RegisterValue; break; - case 0x104c: reg->BB4C = RegisterValue; break; - case 0x1050: reg->BB50 = RegisterValue; break; - case 0x1054: reg->BB54 = RegisterValue; break; - case 0x1058: reg->BB58 = RegisterValue; break; - case 0x105c: reg->BB5C = RegisterValue; break; - case 0x1060: reg->BB60 = RegisterValue; break; + case 0x3b0: + reg->U1B0 = RegisterValue; + break; + case 0x3bc: + reg->U1BC_LEDConfigure = RegisterValue; + break; + case 0x400: + reg->D00_DmaControl = RegisterValue; + break; + case 0x800: + reg->M00_MacControl = RegisterValue; + break; + case 0x804: + reg->M04_MulticastAddress1 = RegisterValue; + break; + case 0x808: + reg->M08_MulticastAddress2 = RegisterValue; + break; + case 0x824: + reg->M24_MacControl = RegisterValue; + break; + case 0x828: + reg->M28_MacControl = RegisterValue; + break; + case 0x82c: + reg->M2C_MacControl = RegisterValue; + break; + case 0x838: + reg->M38_MacControl = RegisterValue; + break; + case 0x840: + reg->M40_MacControl = RegisterValue; + break; + case 0x844: + reg->M44_MacControl = RegisterValue; + break; + case 0x848: + reg->M48_MacControl = RegisterValue; + break; + case 0x84c: + reg->M4C_MacStatus = RegisterValue; + break; + case 0x860: + reg->M60_MacControl = RegisterValue; + break; + case 0x868: + reg->M68_MacControl = RegisterValue; + break; + case 0x870: + reg->M70_MacControl = RegisterValue; + break; + case 0x874: + reg->M74_MacControl = RegisterValue; + break; + case 0x878: + reg->M78_ERPInformation = RegisterValue; + break; + case 0x87C: + reg->M7C_MacControl = RegisterValue; + break; + case 0x880: + reg->M80_MacControl = RegisterValue; + break; + case 0x884: + reg->M84_MacControl = RegisterValue; + break; + case 0x888: + reg->M88_MacControl = RegisterValue; + break; + case 0x898: + reg->M98_MacControl = RegisterValue; + break; + case 0x100c: + reg->BB0C = RegisterValue; + break; + case 0x102c: + reg->BB2C = RegisterValue; + break; + case 0x1030: + reg->BB30 = RegisterValue; + break; + case 0x103c: + reg->BB3C = RegisterValue; + break; + case 0x1048: + reg->BB48 = RegisterValue; + break; + case 0x104c: + reg->BB4C = RegisterValue; + break; + case 0x1050: + reg->BB50 = RegisterValue; + break; + case 0x1054: + reg->BB54 = RegisterValue; + break; + case 0x1058: + reg->BB58 = RegisterValue; + break; + case 0x105c: + reg->BB5C = RegisterValue; + break; + case 0x1060: + reg->BB60 = RegisterValue; + break; } } @@ -118,7 +188,8 @@ void Wb35Reg_Update(struct hw_data *pHwData, u16 RegisterNo, u32 RegisterValue * true : read command process successfully * false : register not support */ -unsigned char Wb35Reg_WriteSync(struct hw_data *pHwData, u16 RegisterNo, u32 RegisterValue) +unsigned char Wb35Reg_WriteSync(struct hw_data *pHwData, u16 RegisterNo, + u32 RegisterValue) { struct wb35_reg *reg = &pHwData->reg; int ret = -1; @@ -139,9 +210,10 @@ unsigned char Wb35Reg_WriteSync(struct hw_data *pHwData, u16 RegisterNo, u32 Reg /* Sync IoCallDriver */ reg->EP0vm_state = VM_RUNNING; ret = usb_control_msg(pHwData->udev, - usb_sndctrlpipe(pHwData->udev, 0), - 0x03, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - 0x0, RegisterNo, &RegisterValue, 4, HZ * 100); + usb_sndctrlpipe(pHwData->udev, 0), + 0x03, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, + 0x0, RegisterNo, &RegisterValue, 4, HZ * 100); reg->EP0vm_state = VM_STOP; reg->SyncIoPause = 0; @@ -159,7 +231,8 @@ unsigned char Wb35Reg_WriteSync(struct hw_data *pHwData, u16 RegisterNo, u32 Reg * true : read command process successfully * false : register not support */ -unsigned char Wb35Reg_Write(struct hw_data *pHwData, u16 RegisterNo, u32 RegisterValue) +unsigned char Wb35Reg_Write(struct hw_data *pHwData, u16 RegisterNo, + u32 RegisterValue) { struct wb35_reg *reg = &pHwData->reg; struct usb_ctrlrequest *dr; @@ -174,50 +247,51 @@ unsigned char Wb35Reg_Write(struct hw_data *pHwData, u16 RegisterNo, u32 Registe /* update the register by send urb request */ UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest); reg_queue = kzalloc(UrbSize, GFP_ATOMIC); + if (reg_queue == NULL) + return false; + urb = usb_alloc_urb(0, GFP_ATOMIC); - if (urb && reg_queue) { - reg_queue->DIRECT = 1; /* burst write register */ - reg_queue->INDEX = RegisterNo; - reg_queue->VALUE = cpu_to_le32(RegisterValue); - reg_queue->RESERVED_VALID = false; - dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); - dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; - dr->bRequest = 0x03; /* USB or vendor-defined request code, burst mode */ - dr->wValue = cpu_to_le16(0x0); - dr->wIndex = cpu_to_le16(RegisterNo); - dr->wLength = cpu_to_le16(4); - - /* Enter the sending queue */ - reg_queue->Next = NULL; - reg_queue->pUsbReq = dr; - reg_queue->urb = urb; + if (urb == NULL) { + kfree(reg_queue); + return false; + } - spin_lock_irq(®->EP0VM_spin_lock); - if (reg->reg_first == NULL) - reg->reg_first = reg_queue; - else - reg->reg_last->Next = reg_queue; - reg->reg_last = reg_queue; + reg_queue->DIRECT = 1; /* burst write register */ + reg_queue->INDEX = RegisterNo; + reg_queue->VALUE = cpu_to_le32(RegisterValue); + reg_queue->RESERVED_VALID = false; + dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); + dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; + dr->bRequest = 0x03; /* USB or vendor-defined request code, burst mode */ + dr->wValue = cpu_to_le16(0x0); + dr->wIndex = cpu_to_le16(RegisterNo); + dr->wLength = cpu_to_le16(4); + + /* Enter the sending queue */ + reg_queue->Next = NULL; + reg_queue->pUsbReq = dr; + reg_queue->urb = urb; - spin_unlock_irq(®->EP0VM_spin_lock); + spin_lock_irq(®->EP0VM_spin_lock); + if (reg->reg_first == NULL) + reg->reg_first = reg_queue; + else + reg->reg_last->Next = reg_queue; + reg->reg_last = reg_queue; - /* Start EP0VM */ - Wb35Reg_EP0VM_start(pHwData); + spin_unlock_irq(®->EP0VM_spin_lock); - return true; - } else { - if (urb) - usb_free_urb(urb); - kfree(reg_queue); - return false; - } + /* Start EP0VM */ + Wb35Reg_EP0VM_start(pHwData); + + return true; } /* * This command will be executed with a user defined value. When it completes, * this value is useful. For example, hal_set_current_channel will use it. * true : read command process successfully - * false : register not support + * false : register not supported */ unsigned char Wb35Reg_WriteWithCallbackValue(struct hw_data *pHwData, u16 RegisterNo, @@ -238,43 +312,45 @@ unsigned char Wb35Reg_WriteWithCallbackValue(struct hw_data *pHwData, /* update the register by send urb request */ UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest); reg_queue = kzalloc(UrbSize, GFP_ATOMIC); - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (urb && reg_queue) { - reg_queue->DIRECT = 1; /* burst write register */ - reg_queue->INDEX = RegisterNo; - reg_queue->VALUE = cpu_to_le32(RegisterValue); - /* NOTE : Users must guarantee the size of value will not exceed the buffer size. */ - memcpy(reg_queue->RESERVED, pValue, Len); - reg_queue->RESERVED_VALID = true; - dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); - dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; - dr->bRequest = 0x03; /* USB or vendor-defined request code, burst mode */ - dr->wValue = cpu_to_le16(0x0); - dr->wIndex = cpu_to_le16(RegisterNo); - dr->wLength = cpu_to_le16(4); - - /* Enter the sending queue */ - reg_queue->Next = NULL; - reg_queue->pUsbReq = dr; - reg_queue->urb = urb; - spin_lock_irq(®->EP0VM_spin_lock); - if (reg->reg_first == NULL) - reg->reg_first = reg_queue; - else - reg->reg_last->Next = reg_queue; - reg->reg_last = reg_queue; - - spin_unlock_irq(®->EP0VM_spin_lock); + if (reg_queue == NULL) + return false; - /* Start EP0VM */ - Wb35Reg_EP0VM_start(pHwData); - return true; - } else { - if (urb) - usb_free_urb(urb); + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (urb == NULL) { kfree(reg_queue); return false; } + + reg_queue->DIRECT = 1; /* burst write register */ + reg_queue->INDEX = RegisterNo; + reg_queue->VALUE = cpu_to_le32(RegisterValue); + /* NOTE : Users must guarantee the size of value will not exceed the buffer size. */ + memcpy(reg_queue->RESERVED, pValue, Len); + reg_queue->RESERVED_VALID = true; + dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); + dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE; + dr->bRequest = 0x03; /* USB or vendor-defined request code, burst mode */ + dr->wValue = cpu_to_le16(0x0); + dr->wIndex = cpu_to_le16(RegisterNo); + dr->wLength = cpu_to_le16(4); + + /* Enter the sending queue */ + reg_queue->Next = NULL; + reg_queue->pUsbReq = dr; + reg_queue->urb = urb; + spin_lock_irq(®->EP0VM_spin_lock); + if (reg->reg_first == NULL) + reg->reg_first = reg_queue; + else + reg->reg_last->Next = reg_queue; + reg->reg_last = reg_queue; + + spin_unlock_irq(®->EP0VM_spin_lock); + + /* Start EP0VM */ + Wb35Reg_EP0VM_start(pHwData); + + return true; } /* @@ -283,7 +359,8 @@ unsigned char Wb35Reg_WriteWithCallbackValue(struct hw_data *pHwData, * pRegisterValue : It must be a resident buffer due to * asynchronous read register. */ -unsigned char Wb35Reg_ReadSync(struct hw_data *pHwData, u16 RegisterNo, u32 *pRegisterValue) +unsigned char Wb35Reg_ReadSync(struct hw_data *pHwData, u16 RegisterNo, + u32 *pRegisterValue) { struct wb35_reg *reg = &pHwData->reg; u32 *pltmp = pRegisterValue; @@ -302,9 +379,10 @@ unsigned char Wb35Reg_ReadSync(struct hw_data *pHwData, u16 RegisterNo, u32 *pRe reg->EP0vm_state = VM_RUNNING; ret = usb_control_msg(pHwData->udev, - usb_rcvctrlpipe(pHwData->udev, 0), - 0x01, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x0, RegisterNo, pltmp, 4, HZ * 100); + usb_rcvctrlpipe(pHwData->udev, 0), + 0x01, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + 0x0, RegisterNo, pltmp, 4, HZ * 100); *pRegisterValue = cpu_to_le32(*pltmp); @@ -329,7 +407,8 @@ unsigned char Wb35Reg_ReadSync(struct hw_data *pHwData, u16 RegisterNo, u32 *pRe * pRegisterValue : It must be a resident buffer due to * asynchronous read register. */ -unsigned char Wb35Reg_Read(struct hw_data *pHwData, u16 RegisterNo, u32 *pRegisterValue) +unsigned char Wb35Reg_Read(struct hw_data *pHwData, u16 RegisterNo, + u32 *pRegisterValue) { struct wb35_reg *reg = &pHwData->reg; struct usb_ctrlrequest *dr; @@ -344,41 +423,41 @@ unsigned char Wb35Reg_Read(struct hw_data *pHwData, u16 RegisterNo, u32 *pRegist /* update the variable by send Urb to read register */ UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest); reg_queue = kzalloc(UrbSize, GFP_ATOMIC); - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (urb && reg_queue) { - reg_queue->DIRECT = 0; /* read register */ - reg_queue->INDEX = RegisterNo; - reg_queue->pBuffer = pRegisterValue; - dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); - dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN; - dr->bRequest = 0x01; /* USB or vendor-defined request code, burst mode */ - dr->wValue = cpu_to_le16(0x0); - dr->wIndex = cpu_to_le16(RegisterNo); - dr->wLength = cpu_to_le16(4); - - /* Enter the sending queue */ - reg_queue->Next = NULL; - reg_queue->pUsbReq = dr; - reg_queue->urb = urb; - spin_lock_irq(®->EP0VM_spin_lock); - if (reg->reg_first == NULL) - reg->reg_first = reg_queue; - else - reg->reg_last->Next = reg_queue; - reg->reg_last = reg_queue; - - spin_unlock_irq(®->EP0VM_spin_lock); - - /* Start EP0VM */ - Wb35Reg_EP0VM_start(pHwData); + if (reg_queue == NULL) + return false; - return true; - } else { - if (urb) - usb_free_urb(urb); + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (urb == NULL) { kfree(reg_queue); return false; } + reg_queue->DIRECT = 0; /* read register */ + reg_queue->INDEX = RegisterNo; + reg_queue->pBuffer = pRegisterValue; + dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue)); + dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN; + dr->bRequest = 0x01; /* USB or vendor-defined request code, burst mode */ + dr->wValue = cpu_to_le16(0x0); + dr->wIndex = cpu_to_le16(RegisterNo); + dr->wLength = cpu_to_le16(4); + + /* Enter the sending queue */ + reg_queue->Next = NULL; + reg_queue->pUsbReq = dr; + reg_queue->urb = urb; + spin_lock_irq(®->EP0VM_spin_lock); + if (reg->reg_first == NULL) + reg->reg_first = reg_queue; + else + reg->reg_last->Next = reg_queue; + reg->reg_last = reg_queue; + + spin_unlock_irq(®->EP0VM_spin_lock); + + /* Start EP0VM */ + Wb35Reg_EP0VM_start(pHwData); + + return true; } @@ -631,7 +710,7 @@ unsigned char Wb35Reg_initial(struct hw_data *pHwData) * CardComputeCrc -- * * Description: - * Runs the AUTODIN II CRC algorithm on buffer Buffer of length, Length. + * Runs the AUTODIN II CRC algorithm on the buffers Buffer length. * * Arguments: * Buffer - the input buffer |
